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:
Konstantin Belousov 2021-04-10 15:32:24 +03:00
parent 4d7f08c84b
commit 08bfbd4359
4 changed files with 30 additions and 2 deletions

View File

@ -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 {

View File

@ -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;

View File

@ -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);

View File

@ -30,7 +30,9 @@
#ifndef _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
struct RtldLockInfo