From 63003c4bcb169f8c6f225ff5b732b20aa125caa1 Mon Sep 17 00:00:00 2001 From: Michal Meloun Date: Sat, 8 Dec 2018 14:58:17 +0000 Subject: [PATCH] Implement R_AARCH64_TLS_DTPMOD64 and A_AARCH64_TLS_DTPREL64 relocations. Although these are slightly obsolete in favor of R_AARCH64_TLSDESC, gcc -mtls-dialect=trad still use them. Please note that definition of TLS_DTPMOD64 and TLS_DTPREL64 are incorrectly exchanged in GNU binutils. TLS_DTPREL64 should be encoded to 1028 (as is defined in ARM ELF ABI) but binutils encode it to 1029. And vice versa, TLS_DTPMOD64 should be encoded to 1029 but binutils encode it to 1028. While I'm in, add also R_AARCH64_NONE. It can be produced as result of linker relaxation. MFC after: 1 week --- libexec/rtld-elf/aarch64/reloc.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/libexec/rtld-elf/aarch64/reloc.c b/libexec/rtld-elf/aarch64/reloc.c index 7cac03bc1793..cd33f3e2a872 100644 --- a/libexec/rtld-elf/aarch64/reloc.c +++ b/libexec/rtld-elf/aarch64/reloc.c @@ -223,6 +223,8 @@ reloc_plt(Obj_Entry *obj) case R_AARCH64_IRELATIVE: obj->irelative = true; break; + case R_AARCH64_NONE: + break; default: _rtld_error("Unknown relocation type %u in PLT", (unsigned int)ELF_R_TYPE(rela->r_info)); @@ -391,6 +393,8 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags, case R_AARCH64_ABS64: case R_AARCH64_GLOB_DAT: case R_AARCH64_TLS_TPREL64: + case R_AARCH64_TLS_DTPREL64: + case R_AARCH64_TLS_DTPMOD64: def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, flags, cache, lockstate); if (def == NULL) @@ -478,9 +482,24 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags, *where = def->st_value + rela->r_addend + defobj->tlsoffset; break; + + /* + * !!! BEWARE !!! + * ARM ELF ABI defines TLS_DTPMOD64 as 1029, and TLS_DTPREL64 + * as 1028. But actual bfd linker and the glibc RTLD linker + * treats TLS_DTPMOD64 as 1028 and TLS_DTPREL64 1029. + */ + case R_AARCH64_TLS_DTPREL64: /* efectively is TLS_DTPMOD64 */ + *where += (Elf_Addr)defobj->tlsindex; + break; + case R_AARCH64_TLS_DTPMOD64: /* efectively is TLS_DTPREL64 */ + *where += (Elf_Addr)(def->st_value + rela->r_addend); + break; case R_AARCH64_RELATIVE: *where = (Elf_Addr)(obj->relocbase + rela->r_addend); break; + case R_AARCH64_NONE: + break; default: rtld_printf("%s: Unhandled relocation %lu\n", obj->path, ELF_R_TYPE(rela->r_info));