rtld: workaround for broken ABI
Right now, libthr does not initialize RtldLockInfo.rtli_version when calling _rtld_thread_init(), which makes versioning the interface troublesome. Add a workaround: if the calling object of _rtld_thread_init() exports the "_pli_rtli_version" symbol, then consider rtli_version initialized. Otherwise, forcibly set it to RTLI_VERSION_ONE, currently defined as RTLI_VERSION. Export "_pli_rtli_version" from libthr and properly initialize rtli_version. Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D29633
This commit is contained in:
parent
4d7f08c84b
commit
08bfbd4359
@ -296,6 +296,9 @@ FBSDprivate_1.0 {
|
||||
_thread_size_key;
|
||||
_thread_state_running;
|
||||
_thread_state_zoombie;
|
||||
|
||||
/* ABI bug workaround, indicate that pli->rtli_version is valid */
|
||||
_pli_rtli_version;
|
||||
};
|
||||
|
||||
FBSD_1.1 {
|
||||
|
@ -182,6 +182,13 @@ _thr_rtld_clr_flag(int mask __unused)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* ABI bug workaround: This symbol must be present for rtld to accept
|
||||
* RTLI_VERSION from RtldLockInfo
|
||||
*/
|
||||
extern char _pli_rtli_version;
|
||||
char _pli_rtli_version;
|
||||
|
||||
void
|
||||
_thr_rtld_init(void)
|
||||
{
|
||||
@ -205,6 +212,7 @@ _thr_rtld_init(void)
|
||||
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;
|
||||
|
@ -344,8 +344,23 @@ lockdflt_init(void)
|
||||
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, "_pli_rtli_version");
|
||||
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);
|
||||
|
@ -30,7 +30,9 @@
|
||||
#ifndef _RTLD_LOCK_H_
|
||||
#define _RTLD_LOCK_H_
|
||||
|
||||
#define RTLI_VERSION_ONE 0x01
|
||||
#define RTLI_VERSION 0x01
|
||||
|
||||
#define MAX_RTLD_LOCKS 8
|
||||
|
||||
struct RtldLockInfo
|
||||
|
Loading…
Reference in New Issue
Block a user