Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F150073999
D2183.id4617.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D2183.id4617.diff
View Options
Index: libexec/rtld-elf/aarch64/reloc.c
===================================================================
--- libexec/rtld-elf/aarch64/reloc.c
+++ libexec/rtld-elf/aarch64/reloc.c
@@ -50,6 +50,8 @@
* a function pointer to a simple asm function.
*/
void *_rtld_tlsdesc(void *);
+void *_rtld_tlsdesc_dynamic(void *);
+
void _exit(int);
void
@@ -120,6 +122,68 @@
return (0);
}
+struct tls_data {
+ int64_t index;
+ Obj_Entry *obj;
+ const Elf_Rela *rela;
+};
+
+static struct tls_data *
+reloc_tlsdesc_alloc(Obj_Entry *obj, const Elf_Rela *rela)
+{
+ struct tls_data *tlsdesc;
+
+ tlsdesc = xmalloc(sizeof(struct tls_data));
+ tlsdesc->index = -1;
+ tlsdesc->obj = obj;
+ tlsdesc->rela = rela;
+
+ return (tlsdesc);
+}
+
+/*
+ * Look up the symbol to find its tls index
+ */
+static int64_t
+rtld_tlsdesc_handle_locked(struct tls_data *tlsdesc, int flags,
+ RtldLockState *lockstate)
+{
+ const Elf_Rela *rela;
+ const Elf_Sym *def;
+ const Obj_Entry *defobj;
+ Obj_Entry *obj;
+
+ rela = tlsdesc->rela;
+ obj = tlsdesc->obj;
+
+ def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, flags, NULL,
+ lockstate);
+ if (def == NULL)
+ die();
+
+ tlsdesc->index = defobj->tlsindex + def->st_value + rela->r_addend;
+
+ return (tlsdesc->index);
+}
+
+int64_t
+rtld_tlsdesc_handle(struct tls_data *tlsdesc, int flags)
+{
+ RtldLockState lockstate;
+
+ /* We have already found the index, return it */
+ if (tlsdesc->index >= 0)
+ return (tlsdesc->index);
+
+ wlock_acquire(rtld_bind_lock, &lockstate);
+ /* tlsdesc->index may have been set by another thread */
+ if (tlsdesc->index == -1)
+ rtld_tlsdesc_handle_locked(tlsdesc, flags, &lockstate);
+ lock_release(rtld_bind_lock, &lockstate);
+
+ return (tlsdesc->index);
+}
+
/*
* Process the PLT relocations.
*/
@@ -142,11 +206,11 @@
case R_AARCH64_TLSDESC:
if (ELF_R_SYM(rela->r_info) == 0) {
where[0] = (Elf_Addr)_rtld_tlsdesc;
- where[1] = rela->r_addend;
+ where[1] = obj->tlsindex + rela->r_addend;
} else {
- _rtld_error("Unable to handle "
- "R_AARCH64_TLSDESC with a symbol set");
- return (-1);
+ where[0] = (Elf_Addr)_rtld_tlsdesc_dynamic;
+ where[1] = (Elf_Addr)reloc_tlsdesc_alloc(obj,
+ rela);
}
break;
default:
@@ -169,14 +233,15 @@
const Elf_Rela *relalim;
const Elf_Rela *rela;
const Elf_Sym *def;
+ struct tls_data *tlsdesc;
relalim = (const Elf_Rela *)((char *)obj->pltrela + obj->pltrelasize);
for (rela = obj->pltrela; rela < relalim; rela++) {
Elf_Addr *where;
+ where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
switch(ELF_R_TYPE(rela->r_info)) {
case R_AARCH64_JUMP_SLOT:
- where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
def = find_symdef(ELF_R_SYM(rela->r_info), obj,
&defobj, SYMLOOK_IN_PLT | flags, NULL, lockstate);
if (def == NULL) {
@@ -187,6 +252,12 @@
*where = (Elf_Addr)(defobj->relocbase + def->st_value);
break;
case R_AARCH64_TLSDESC:
+ if (ELF_R_SYM(rela->r_info) != 0) {
+ tlsdesc = (struct tls_data *)where[1];
+ if (tlsdesc->index == -1)
+ rtld_tlsdesc_handle_locked(tlsdesc,
+ SYMLOOK_IN_PLT | flags, lockstate);
+ }
break;
default:
_rtld_error("Unknown relocation type %x in jmpslot",
@@ -285,6 +356,32 @@
return (-1);
}
break;
+ case R_AARCH64_TLS_TPREL64:
+ def = find_symdef(symnum, obj, &defobj, flags, cache,
+ lockstate);
+ if (def == NULL)
+ return (-1);
+
+ /*
+ * We lazily allocate offsets for static TLS as we
+ * see the first relocation that references the
+ * TLS block. This allows us to support (small
+ * amounts of) static TLS in dynamically loaded
+ * modules. If we run out of space, we generate an
+ * error.
+ */
+ if (!defobj->tls_done) {
+ if (!allocate_tls_offset((Obj_Entry*) defobj)) {
+ _rtld_error(
+ "%s: No space available for static "
+ "Thread Local Storage", obj->path);
+ return (-1);
+ }
+ }
+
+ *where = def->st_value + rela->r_addend +
+ defobj->tlsoffset - TLS_TCB_SIZE;
+ break;
case R_AARCH64_RELATIVE:
*where = (Elf_Addr)(obj->relocbase + rela->r_addend);
break;
Index: libexec/rtld-elf/aarch64/rtld_machdep.h
===================================================================
--- libexec/rtld-elf/aarch64/rtld_machdep.h
+++ libexec/rtld-elf/aarch64/rtld_machdep.h
@@ -47,6 +47,9 @@
})
#define RTLD_IS_DYNAMIC() (1)
+#define RTLD_DIE_GLOBAL
+void die(void) __dead2;
+
Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
const struct Struct_Obj_Entry *defobj,
const struct Struct_Obj_Entry *obj,
Index: libexec/rtld-elf/aarch64/rtld_start.S
===================================================================
--- libexec/rtld-elf/aarch64/rtld_start.S
+++ libexec/rtld-elf/aarch64/rtld_start.S
@@ -109,5 +109,44 @@
*/
ENTRY(_rtld_tlsdesc)
ldr x0, [x0, #8]
- RET
+ ret
END(_rtld_tlsdesc)
+
+/*
+ * uint64_t _rtld_tlsdesc_dynamic(struct tlsdesc *);
+ *
+ * TODO: We could lookup the saved index here to skip saving the entire stack.
+ */
+ENTRY(_rtld_tlsdesc_dynamic)
+ /* Store any registers we may use in rtld_tlsdesc_handle */
+ stp x29, x30, [sp, #-(10 * 16)]!
+ mov x29, sp
+ stp x1, x2, [sp, #(1 * 16)]
+ stp x3, x4, [sp, #(2 * 16)]
+ stp x5, x6, [sp, #(3 * 16)]
+ stp x7, x8, [sp, #(4 * 16)]
+ stp x9, x10, [sp, #(5 * 16)]
+ stp x11, x12, [sp, #(6 * 16)]
+ stp x13, x14, [sp, #(7 * 16)]
+ stp x15, x16, [sp, #(8 * 16)]
+ stp x17, x18, [sp, #(9 * 16)]
+
+ /* Find the tls offset */
+ ldr x0, [x0, #8]
+ mov x1, #1
+ bl rtld_tlsdesc_handle
+
+ /* Restore the registers */
+ ldp x17, x18, [sp, #(9 * 16)]
+ ldp x15, x16, [sp, #(8 * 16)]
+ ldp x13, x14, [sp, #(7 * 16)]
+ ldp x11, x12, [sp, #(6 * 16)]
+ ldp x9, x10, [sp, #(5 * 16)]
+ ldp x7, x8, [sp, #(4 * 16)]
+ ldp x5, x6, [sp, #(3 * 16)]
+ ldp x3, x4, [sp, #(2 * 16)]
+ ldp x1, x2, [sp, #(1 * 16)]
+ ldp x29, x30, [sp], #(10 * 16)
+
+ ret
+END(_rtld_tlsdesc_dynamic)
Index: libexec/rtld-elf/rtld.c
===================================================================
--- libexec/rtld-elf/rtld.c
+++ libexec/rtld-elf/rtld.c
@@ -78,7 +78,9 @@
* Function declarations.
*/
static const char *basename(const char *);
+#ifndef RTLD_DIE_GLOBAL
static void die(void) __dead2;
+#endif
static void digest_dynamic1(Obj_Entry *, int, const Elf_Dyn **,
const Elf_Dyn **, const Elf_Dyn **);
static void digest_dynamic2(Obj_Entry *, const Elf_Dyn *, const Elf_Dyn *,
@@ -865,7 +867,11 @@
return (res4);
}
-static void
+/* Hack until all architectures use -fvisibility=hidden */
+#ifndef RTLD_DIE_GLOBAL
+static
+#endif
+void
die(void)
{
const char *msg = dlerror();
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Mar 30, 4:26 AM (18 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30573379
Default Alt Text
D2183.id4617.diff (6 KB)
Attached To
Mode
D2183: Add support for R_AARCH64_TLSDESC with a symbol, and R_AARCH64_TLS_TPREL64
Attached
Detach File
Event Timeline
Log In to Comment