Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F106076383
D29633.id86989.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D29633.id86989.diff
View Options
diff --git a/lib/libthr/thread/thr_private.h b/lib/libthr/thread/thr_private.h
--- a/lib/libthr/thread/thr_private.h
+++ b/lib/libthr/thread/thr_private.h
@@ -577,6 +577,10 @@
/* pthread_set/get_name_np */
char *name;
+
+ /* rtld thread-local dlerror message and seen control */
+ char dlerror_msg[512];
+ int dlerror_seen;
};
#define THR_SHOULD_GC(thrd) \
diff --git a/lib/libthr/thread/thr_rtld.c b/lib/libthr/thread/thr_rtld.c
--- a/lib/libthr/thread/thr_rtld.c
+++ b/lib/libthr/thread/thr_rtld.c
@@ -182,6 +182,29 @@
return (0);
}
+/*
+ * ABI bug workaround: This symbol must be present for rtld to accept
+ * RTLI_VERSION from RtldLockInfo
+ */
+char *_thr_dlerror_loc(void);
+char *
+_thr_dlerror_loc(void)
+{
+ struct pthread *curthread;
+
+ curthread = _get_curthread();
+ return (curthread->dlerror_msg);
+}
+
+static int *
+_thr_dlerror_seen(void)
+{
+ struct pthread *curthread;
+
+ curthread = _get_curthread();
+ return (&curthread->dlerror_seen);
+}
+
void
_thr_rtld_init(void)
{
@@ -205,6 +228,7 @@
mprotect(NULL, 0, 0);
_rtld_get_stack_prot();
+ li.rtli_version = RTLI_VERSION;
li.lock_create = _thr_rtld_lock_create;
li.lock_destroy = _thr_rtld_lock_destroy;
li.rlock_acquire = _thr_rtld_rlock_acquire;
@@ -213,6 +237,9 @@
li.thread_set_flag = _thr_rtld_set_flag;
li.thread_clr_flag = _thr_rtld_clr_flag;
li.at_fork = NULL;
+ li.dlerror_loc = _thr_dlerror_loc;
+ li.dlerror_loc_sz = sizeof(curthread->dlerror_msg);
+ li.dlerror_seen = _thr_dlerror_seen;
/*
* Preresolve the symbols needed for the fork interposer. We
diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h
--- a/libexec/rtld-elf/rtld.h
+++ b/libexec/rtld-elf/rtld.h
@@ -389,6 +389,7 @@
Obj_Entry *globallist_next(const Obj_Entry *obj);
void obj_free(Obj_Entry *);
Obj_Entry *obj_new(void);
+Obj_Entry *obj_from_addr(const void *);
void _rtld_bind_start(void);
void *rtld_resolve_ifunc(const Obj_Entry *obj, const Elf_Sym *def);
void symlook_init(SymLook *, const char *);
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -124,7 +124,6 @@
static void map_stacks_exec(RtldLockState *);
static int obj_disable_relro(Obj_Entry *);
static int obj_enforce_relro(Obj_Entry *);
-static Obj_Entry *obj_from_addr(const void *);
static void objlist_call_fini(Objlist *, Obj_Entry *, RtldLockState *);
static void objlist_call_init(Objlist *, RtldLockState *);
static void objlist_clear(Objlist *);
@@ -195,7 +194,6 @@
/*
* Data declarations.
*/
-static char *error_message; /* Message for dlerror(), or NULL */
struct r_debug r_debug __exported; /* for GDB; */
static bool libmap_disable; /* Disable libmap */
static bool ld_loadfltr; /* Immediate filters processing */
@@ -443,6 +441,8 @@
assert(aux_info[AT_BASE] != NULL);
init_rtld((caddr_t) aux_info[AT_BASE]->a_un.a_ptr, aux_info);
+ dlerror_dflt_init();
+
__progname = obj_rtld.path;
argv0 = argv[0] != NULL ? argv[0] : "(null)";
environ = env;
@@ -927,14 +927,14 @@
void
_rtld_error(const char *fmt, ...)
{
- static char buf[512];
- va_list ap;
+ va_list ap;
- va_start(ap, fmt);
- rtld_vsnprintf(buf, sizeof buf, fmt, ap);
- error_message = buf;
- va_end(ap);
- LD_UTRACE(UTRACE_RTLD_ERROR, NULL, NULL, 0, 0, error_message);
+ va_start(ap, fmt);
+ rtld_vsnprintf(lockinfo.dlerror_loc(), lockinfo.dlerror_loc_sz,
+ fmt, ap);
+ va_end(ap);
+ *lockinfo.dlerror_seen() = 0;
+ LD_UTRACE(UTRACE_RTLD_ERROR, NULL, NULL, 0, 0, lockinfo.dlerror_loc());
}
/*
@@ -943,7 +943,7 @@
static char *
errmsg_save(void)
{
- return error_message == NULL ? NULL : xstrdup(error_message);
+ return (xstrdup(lockinfo.dlerror_loc()));
}
/*
@@ -953,12 +953,12 @@
static void
errmsg_restore(char *saved_msg)
{
- if (saved_msg == NULL)
- error_message = NULL;
- else {
- _rtld_error("%s", saved_msg);
- free(saved_msg);
- }
+ if (saved_msg == NULL)
+ _rtld_error("");
+ else {
+ _rtld_error("%s", saved_msg);
+ free(saved_msg);
+ }
}
static const char *
@@ -2687,7 +2687,7 @@
return (NULL);
}
-static Obj_Entry *
+Obj_Entry *
obj_from_addr(const void *addr)
{
Obj_Entry *obj;
@@ -3389,9 +3389,10 @@
char *
dlerror(void)
{
- char *msg = error_message;
- error_message = NULL;
- return msg;
+ if (*(lockinfo.dlerror_seen()) != 0)
+ return (NULL);
+ *lockinfo.dlerror_seen() = 1;
+ return (lockinfo.dlerror_loc());
}
/*
diff --git a/libexec/rtld-elf/rtld_lock.h b/libexec/rtld-elf/rtld_lock.h
--- a/libexec/rtld-elf/rtld_lock.h
+++ b/libexec/rtld-elf/rtld_lock.h
@@ -30,7 +30,9 @@
#ifndef _RTLD_LOCK_H_
#define _RTLD_LOCK_H_
-#define RTLI_VERSION 0x01
+#define RTLI_VERSION_ONE 0x01
+#define RTLI_VERSION 0x02
+
#define MAX_RTLD_LOCKS 8
struct RtldLockInfo
@@ -44,6 +46,9 @@
int (*thread_set_flag)(int);
int (*thread_clr_flag)(int);
void (*at_fork)(void);
+ char *(*dlerror_loc)(void);
+ int *(*dlerror_seen)(void);
+ int dlerror_loc_sz;
};
extern void _rtld_thread_init(struct RtldLockInfo *) __exported;
@@ -59,6 +64,8 @@
extern rtld_lock_t rtld_libc_lock;
extern rtld_lock_t rtld_phdr_lock;
+extern struct RtldLockInfo lockinfo;
+
#define RTLD_LOCK_UNLOCKED 0
#define RTLD_LOCK_RLOCKED 1
#define RTLD_LOCK_WLOCKED 2
@@ -72,6 +79,8 @@
void lock_upgrade(rtld_lock_t, RtldLockState *);
void lock_restart_for_upgrade(RtldLockState *);
+void dlerror_dflt_init(void);
+
#endif /* IN_RTLD */
#endif
diff --git a/libexec/rtld-elf/rtld_lock.c b/libexec/rtld-elf/rtld_lock.c
--- a/libexec/rtld-elf/rtld_lock.c
+++ b/libexec/rtld-elf/rtld_lock.c
@@ -59,6 +59,21 @@
void _rtld_atfork_pre(int *) __exported;
void _rtld_atfork_post(int *) __exported;
+static char def_dlerror_msg[512];
+static int def_dlerror_seen_val;
+
+static char *
+def_dlerror_loc(void)
+{
+ return (def_dlerror_msg);
+}
+
+static int *
+def_dlerror_seen(void)
+{
+ return (&def_dlerror_seen_val);
+}
+
#define WAFLAG 0x1 /* A writer holds the lock */
#define RC_INCR 0x2 /* Adjusts count of readers desiring lock */
@@ -192,7 +207,7 @@
/*
* Public interface exposed to the rest of the dynamic linker.
*/
-static struct RtldLockInfo lockinfo;
+struct RtldLockInfo lockinfo;
static struct RtldLockInfo deflockinfo;
static __inline int
@@ -299,6 +314,14 @@
}
}
+void
+dlerror_dflt_init(void)
+{
+ lockinfo.dlerror_loc = def_dlerror_loc;
+ lockinfo.dlerror_loc_sz = sizeof(def_dlerror_msg);
+ lockinfo.dlerror_seen = def_dlerror_seen;
+}
+
void
lockdflt_init(void)
{
@@ -313,6 +336,9 @@
deflockinfo.thread_set_flag = def_thread_set_flag;
deflockinfo.thread_clr_flag = def_thread_clr_flag;
deflockinfo.at_fork = NULL;
+ deflockinfo.dlerror_loc = def_dlerror_loc;
+ deflockinfo.dlerror_loc_sz = sizeof(def_dlerror_msg);
+ deflockinfo.dlerror_seen = def_dlerror_seen;
for (i = 0; i < RTLD_LOCK_CNT; i++) {
rtld_locks[i].mask = (1 << i);
@@ -344,8 +370,24 @@
void
_rtld_thread_init(struct RtldLockInfo *pli)
{
- int flags, i;
+ const Obj_Entry *obj;
+ SymLook req;
void *locks[RTLD_LOCK_CNT];
+ int flags, i, res;
+
+ if (pli == NULL) {
+ lockinfo.rtli_version = RTLI_VERSION;
+ } else {
+ lockinfo.rtli_version = RTLI_VERSION_ONE;
+ obj = obj_from_addr(pli->lock_create);
+ if (obj != NULL) {
+ symlook_init(&req, "_thr_dlerror_loc");
+ req.flags = SYMLOOK_IN_PLT;
+ res = symlook_obj(&req, obj);
+ if (res == 0)
+ lockinfo.rtli_version = pli->rtli_version;
+ }
+ }
/* disable all locking while this function is running */
flags = thread_mask_set(~0);
@@ -389,6 +431,13 @@
lockinfo.thread_set_flag = pli->thread_set_flag;
lockinfo.thread_clr_flag = pli->thread_clr_flag;
lockinfo.at_fork = pli->at_fork;
+ if (lockinfo.rtli_version > RTLI_VERSION_ONE && pli != NULL) {
+ strlcpy(pli->dlerror_loc(), lockinfo.dlerror_loc(),
+ lockinfo.dlerror_loc_sz);
+ lockinfo.dlerror_loc = pli->dlerror_loc;
+ lockinfo.dlerror_loc_sz = pli->dlerror_loc_sz;
+ lockinfo.dlerror_seen = pli->dlerror_seen;
+ }
/* restore thread locking state, this time with new locks */
thread_mask_clear(~0);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Dec 26, 12:10 AM (11 m, 25 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15599790
Default Alt Text
D29633.id86989.diff (7 KB)
Attached To
Mode
D29633: rtld: make dlerror() thread-local
Attached
Detach File
Event Timeline
Log In to Comment