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_size_key;
|
||||||
_thread_state_running;
|
_thread_state_running;
|
||||||
_thread_state_zoombie;
|
_thread_state_zoombie;
|
||||||
|
|
||||||
|
/* ABI bug workaround, indicate that pli->rtli_version is valid */
|
||||||
|
_pli_rtli_version;
|
||||||
};
|
};
|
||||||
|
|
||||||
FBSD_1.1 {
|
FBSD_1.1 {
|
||||||
|
@ -182,6 +182,13 @@ _thr_rtld_clr_flag(int mask __unused)
|
|||||||
return (0);
|
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
|
void
|
||||||
_thr_rtld_init(void)
|
_thr_rtld_init(void)
|
||||||
{
|
{
|
||||||
@ -205,6 +212,7 @@ _thr_rtld_init(void)
|
|||||||
mprotect(NULL, 0, 0);
|
mprotect(NULL, 0, 0);
|
||||||
_rtld_get_stack_prot();
|
_rtld_get_stack_prot();
|
||||||
|
|
||||||
|
li.rtli_version = RTLI_VERSION;
|
||||||
li.lock_create = _thr_rtld_lock_create;
|
li.lock_create = _thr_rtld_lock_create;
|
||||||
li.lock_destroy = _thr_rtld_lock_destroy;
|
li.lock_destroy = _thr_rtld_lock_destroy;
|
||||||
li.rlock_acquire = _thr_rtld_rlock_acquire;
|
li.rlock_acquire = _thr_rtld_rlock_acquire;
|
||||||
|
@ -344,8 +344,23 @@ lockdflt_init(void)
|
|||||||
void
|
void
|
||||||
_rtld_thread_init(struct RtldLockInfo *pli)
|
_rtld_thread_init(struct RtldLockInfo *pli)
|
||||||
{
|
{
|
||||||
int flags, i;
|
const Obj_Entry *obj;
|
||||||
|
SymLook req;
|
||||||
void *locks[RTLD_LOCK_CNT];
|
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 */
|
/* disable all locking while this function is running */
|
||||||
flags = thread_mask_set(~0);
|
flags = thread_mask_set(~0);
|
||||||
|
@ -30,7 +30,9 @@
|
|||||||
#ifndef _RTLD_LOCK_H_
|
#ifndef _RTLD_LOCK_H_
|
||||||
#define _RTLD_LOCK_H_
|
#define _RTLD_LOCK_H_
|
||||||
|
|
||||||
#define RTLI_VERSION 0x01
|
#define RTLI_VERSION_ONE 0x01
|
||||||
|
#define RTLI_VERSION 0x01
|
||||||
|
|
||||||
#define MAX_RTLD_LOCKS 8
|
#define MAX_RTLD_LOCKS 8
|
||||||
|
|
||||||
struct RtldLockInfo
|
struct RtldLockInfo
|
||||||
|
Loading…
Reference in New Issue
Block a user