From nobody Sat Sep 12 00:28:07 2026 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4hhXLw2DcJz6rbC2 for ; Sat, 12 Sep 2026 00:28:08 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hhXLv6ffXz4mwc for ; Sat, 12 Sep 2026 00:28:07 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1789172887; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=XKt4RdQeb5Lo57ADNjNrDeFRnUg9X5jXDgdwriPSCv4=; b=JLl9No1uuKxrwThW5sNydFVldO4IODN2UQLKZaMPrm98/oyizxKyujBe1/AzLEG+7Oh3eQ oHs6yDxEOkAsKLCR3F7ibF1CcGPJV+sPYdHbQVljNz/6g3wa/3jyU3FfnH92r8TmpTf4sR zwd7PNDiR3ZFR/OUYDXMhjCiwpcqs5NVbKREh9H1RmfV+h5obw0t+pLVws/c5IkaPxi07w kM0RRBwwm49xfbS0NLmzrMHy/FETS3E1nmskwclWsiJ6ud+t8R74b0J07KBj65RSTGN+Xd 5u8mOzdrtn5AVJ1qLRgMuWnI12LWP7cigEN2kSuyBVVLDZhIFSSmVfW9pPqP3g== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1789172887; b=go+oeek3E2E/qeVNPqfRy9bWS75fFELFgC8kgkNRxEkQy0HgldAto5BJk2t6HW+Me8Nte6 VXYZQR8qWlDjs/LIJWcwuvoUdItbBXmpSHziLQI/Z+QW106/Y0nzkYuxeg0qFFn5Ch68yH 2p02ZAC+aAJ2APK8oj5Y9sduJxj1n5sDcGgqrhVWpERwFBHZ7aLx+Msax18K8BkVTC3zoF 6Si6uYY1c0cn/xjyn6nljCyx4sHogTi6XivfeRDrmJjt3L6RjyFB2Hftf70YebzpJbAthj 8qlpXKXrfsqhodYQpyjsQ/b1YPEat7yx7PIDkX9GIfNna7w4omcZe7f0Dz6ekw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1789172887; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=XKt4RdQeb5Lo57ADNjNrDeFRnUg9X5jXDgdwriPSCv4=; b=p9ja6/C3U1Rizl9H6DgkV+mvvV2pliVTfDw9KNcumy9CCKrvG6KQexQbyWAIhZLseYD3V9 StsNyX5Kc9UhVAxLBkqNZO6QpyA9VZDbkJhJ6HDrNr8YLHTzk5pxP64uw/Kgsl2g5nhKb2 vfeIWhPkISRLkZPqOylMz77CxInHGO45/D4xeYO4Bj7RqEotFb8u4YuT6XTfKv5SjyM9AF /IRhBP84GwS8VQCw+kCjM2ajuK87vOheSVjZcqniqruYMtjh5003YblkTho/ZWsD63Ryi3 gF3blf7yQ7Ukmqlk+anFYAOApLTAmNI7N8B9MEimzb35JPIXBUr+EuNQ7G7H5w== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hhXLv5jnHzdLB for ; Sat, 12 Sep 2026 00:28:07 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 466f1 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sat, 12 Sep 2026 00:28:07 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Konstantin Belousov Subject: git: 2d049e4de292 - stable/15 - i386 rtld: implement support for TLSDESC relocation List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: 2d049e4de2925a495c54e502c77598f2f833eb5f Auto-Submitted: auto-generated Date: Sat, 12 Sep 2026 00:28:07 +0000 Message-Id: <6aa49c97.466f1.2ca53df7@gitrepo.freebsd.org> The branch stable/15 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=2d049e4de2925a495c54e502c77598f2f833eb5f commit 2d049e4de2925a495c54e502c77598f2f833eb5f Author: Konstantin Belousov AuthorDate: 2026-08-25 12:26:50 +0000 Commit: Konstantin Belousov CommitDate: 2026-09-11 06:59:53 +0000 i386 rtld: implement support for TLSDESC relocation (cherry picked from commit d45d7aea6197a91b794808d508295a74ce5be0cd) --- libexec/rtld-elf/amd64/rtld_start.S | 25 ++++++++++ libexec/rtld-elf/i386/reloc.c | 95 +++++++++++++++++++++++++++++++++++- libexec/rtld-elf/i386/rtld_machdep.h | 31 ++++++++++-- libexec/rtld-elf/i386/rtld_start.S | 36 ++++++++++++++ 4 files changed, 183 insertions(+), 4 deletions(-) diff --git a/libexec/rtld-elf/amd64/rtld_start.S b/libexec/rtld-elf/amd64/rtld_start.S index 7f85a9f94d5c..dcc168a33c57 100644 --- a/libexec/rtld-elf/amd64/rtld_start.S +++ b/libexec/rtld-elf/amd64/rtld_start.S @@ -171,4 +171,29 @@ rtld_dynamic_addr: .cfi_endproc .size rtld_dynamic_addr, . - rtld_dynamic_addr +rtld_tlsdesc_static: + .globl rtld_tlsdesc_static + .type rtld_tlsdesc_static,@function + .cfi_startproc + movq 8(%rax), %rax + ret + .cfi_endproc + .size rtld_tlsdesc_static, . - rtld_tlsdesc_static + +rtld_tlsdesc_undef: + .globl rtld_tlsdesc_undef + .type rtld_tlsdesc_undef,@function + .cfi_startproc + ret + .cfi_endproc + .size rtld_tlsdesc_undef, . - rtld_tlsdesc_undef + +rtld_tlsdesc_dynamic: + .globl rtld_tlsdesc_static + .type rtld_tlsdesc_dynamic,@function + .cfi_startproc + ret + .cfi_endproc + .size rtld_tlsdesc_dynamic, . - rtld_tlsdesc_dynamic + .section .note.GNU-stack,"",%progbits diff --git a/libexec/rtld-elf/i386/reloc.c b/libexec/rtld-elf/i386/reloc.c index 060b3cb147e3..5dd495f2056c 100644 --- a/libexec/rtld-elf/i386/reloc.c +++ b/libexec/rtld-elf/i386/reloc.c @@ -51,6 +51,22 @@ #include "rtld.h" #include "rtld_tls.h" +void +md_obj_entry_init(Obj_Entry *obj) +{ + STAILQ_INIT(&obj->tlsdesc_dynargs); +} + +void +md_obj_entry_fini(Obj_Entry *obj) +{ + struct tlsdesc_dynarg *tda, *t; + + STAILQ_FOREACH_SAFE(tda, &obj->tlsdesc_dynargs, link, t) { + free(tda); + } +} + /* * Process the special R_386_COPY relocations in the main program. These * copy data from a shared object into a region in the main program's BSS @@ -125,6 +141,60 @@ init_pltgot(Obj_Entry *obj) } } +static struct tlsdesc_dynarg * +reloc_tlsdesc_alloc(Obj_Entry *obj, Elf_Addr tlsoffs) +{ + struct tlsdesc_dynarg *tda; + + tda = xmalloc(sizeof(struct tlsdesc_dynarg)); + tda->tlsinfo.ti_module = obj->tlsindex; + tda->tlsinfo.ti_offset = tlsoffs; + STAILQ_INSERT_TAIL(&obj->tlsdesc_dynargs, tda, link); + return (tda); +} + +static void +reloc_tlsdesc(const Obj_Entry *obj, const Elf_Rel *rel, + struct tlsdesc *where, int flags, RtldLockState *lockstate) +{ + const Elf_Sym *def; + const Obj_Entry *defobj; + Elf_Addr offs; + + dbg("reloc_tlsdesc obj %s rel %p where %p", obj->path, rel, where); + offs = 0; + if (ELF_R_SYM(rel->r_info) != 0) { + def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, flags, + NULL, lockstate); + if (def == NULL) + rtld_die(); + if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) { + _rtld_error("%s: IFUNC for TLSDESC reloc", + obj->path); + rtld_die(); + } + offs = def->st_value; + obj = defobj; + if (def->st_shndx == SHN_UNDEF) { + /* Weak undefined thread variable */ + where->entry = rtld_tlsdesc_undef; + return; + } + } + offs += where->offset; + + if (obj->tlsoffset != 0) { + /* Variable is in initialy allocated TLS segment */ + where->entry = rtld_tlsdesc_static; + where->offset = offs - obj->tlsoffset; + } else { + /* TLS offest is unknown at load time, use dynamic resolving */ + where->entry = rtld_tlsdesc_dynamic; + where->arg = reloc_tlsdesc_alloc(__DECONST(Obj_Entry *, obj), + offs); + } +} + /* Process the non-PLT relocations. */ int reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags, @@ -271,6 +341,10 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags, case R_386_IRELATIVE: obj->irelative_nonplt = true; break; + case R_386_TLS_DESC: + reloc_tlsdesc(obj, rel, (struct tlsdesc *)where, + flags, lockstate); + break; default: _rtld_error( "%s: Unsupported relocation type %d in non-PLT relocations", @@ -295,10 +369,10 @@ reloc_plt(Obj_Entry *obj, int flags __unused, RtldLockState *lockstate __unused) for (rel = obj->pltrel; rel < rellim; rel++) { Elf_Addr *where; + where = (Elf_Addr *)(obj->relocbase + rel->r_offset); switch (ELF_R_TYPE(rel->r_info)) { case R_386_JMP_SLOT: /* Relocate the GOT slot pointing into the PLT. */ - where = (Elf_Addr *)(obj->relocbase + rel->r_offset); *where += (Elf_Addr)obj->relocbase; break; @@ -306,6 +380,11 @@ reloc_plt(Obj_Entry *obj, int flags __unused, RtldLockState *lockstate __unused) obj->irelative = true; break; + case R_386_TLS_DESC: + reloc_tlsdesc(obj, rel, (struct tlsdesc *)where, + SYMLOOK_IN_PLT | flags, lockstate); + break; + default: _rtld_error("Unknown relocation type %x in PLT", ELF_R_TYPE(rel->r_info)); @@ -552,3 +631,17 @@ calculate_first_tls_offset(size_t size, size_t align, size_t offset) { return (calculate_tls_offset(0, 0, size, align, offset)); } + +__GNU_ABI ptrdiff_t +rtld_tlsdesc_dynamic_impl(struct tlsdesc *tdp) +{ + struct tlsdesc_dynarg *tda; + struct tcb *tcb; + tls_index *ti; + + tda = tdp->arg; + ti = &tda->tlsinfo; + tcb = _tcb_get(); + return ((ptrdiff_t)tls_get_addr_common(tcb, ti->ti_module, + ti->ti_offset) - (ptrdiff_t)tcb); +} diff --git a/libexec/rtld-elf/i386/rtld_machdep.h b/libexec/rtld-elf/i386/rtld_machdep.h index 574eafe432db..50c2a1bef94e 100644 --- a/libexec/rtld-elf/i386/rtld_machdep.h +++ b/libexec/rtld-elf/i386/rtld_machdep.h @@ -35,10 +35,14 @@ struct Struct_Obj_Entry; -#define MD_OBJ_ENTRY +#define MD_OBJ_ENTRY \ + STAILQ_HEAD(, tlsdesc_dynarg) tlsdesc_dynargs; -#define MD_OBJ_ENTRY_INIT(obj) -#define MD_OBJ_ENTRY_FINI(obj) +#define MD_OBJ_ENTRY_INIT(obj) md_obj_entry_init(obj) +#define MD_OBJ_ENTRY_FINI(obj) md_obj_entry_fini(obj) + +void md_obj_entry_init(struct Struct_Obj_Entry *obj); +void md_obj_entry_fini(struct Struct_Obj_Entry *obj); /* Return the address of the .dynamic section in the dynamic linker. */ #define rtld_dynamic(obj) \ @@ -83,10 +87,31 @@ typedef struct { void *___tls_get_addr(tls_index *ti) __GNU_ABI __exported; void *__tls_get_addr(tls_index *ti) __exported; +struct tlsdesc_dynarg +{ + tls_index tlsinfo; + STAILQ_ENTRY(tlsdesc_dynarg) link; +}; + +struct tlsdesc +{ + ptrdiff_t (*entry)(struct tlsdesc *) __GNU_ABI; + union { + Elf_Size offset; + struct tlsdesc_dynarg *arg; + }; +}; + #define md_abi_variant_hook(x) size_t calculate_first_tls_offset(size_t size, size_t align, size_t offset); size_t calculate_tls_offset(size_t prev_offset, size_t prev_size, size_t size, size_t align, size_t offset); +ptrdiff_t rtld_tlsdesc_dynamic_impl(struct tlsdesc *tdp) __GNU_ABI; + +ptrdiff_t rtld_tlsdesc_static(struct tlsdesc *) __GNU_ABI; +ptrdiff_t rtld_tlsdesc_undef(struct tlsdesc *) __GNU_ABI; +ptrdiff_t rtld_tlsdesc_dynamic(struct tlsdesc *) __GNU_ABI; + #endif diff --git a/libexec/rtld-elf/i386/rtld_start.S b/libexec/rtld-elf/i386/rtld_start.S index 9dbe32d27628..d81f2d17fff4 100644 --- a/libexec/rtld-elf/i386/rtld_start.S +++ b/libexec/rtld-elf/i386/rtld_start.S @@ -95,4 +95,40 @@ _rtld_bind_start: leal 4(%esp),%esp # Discard reloff, do not change eflags ret # "Return" to target address +rtld_tlsdesc_static: + .globl rtld_tlsdesc_static + .type rtld_tlsdesc_static,@function + .cfi_startproc + movl 4(%eax), %eax + ret + .cfi_endproc + .size rtld_tlsdesc_static, . - rtld_tlsdesc_static + +rtld_tlsdesc_undef: + .globl rtld_tlsdesc_undef + .type rtld_tlsdesc_undef,@function + .cfi_startproc + movl 4(%eax), %eax + subl %gs:0, %eax + ret + .cfi_endproc + .size rtld_tlsdesc_undef, . - rtld_tlsdesc_undef + +rtld_tlsdesc_dynamic: + .globl rtld_tlsdesc_dynamic + .type rtld_tlsdesc_dynamic,@function + .cfi_startproc + pushl %ebp + /* XXXKIB cfi */ + movl %esp, %ebp + pushl %edx + pushl %ecx + call rtld_tlsdesc_dynamic_impl + popl %ecx + popl %edx + popl %ebp + ret + .cfi_endproc + .size rtld_tlsdesc_dynamic, . - rtld_tlsdesc_dynamic + .section .note.GNU-stack,"",%progbits