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
This commit is contained in:
Michal Meloun 2018-12-08 14:58:17 +00:00
parent 6017827676
commit 63003c4bcb
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=341738

View File

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