Add support for 64 bit TLS relocations.
This commit is contained in:
parent
a873c5cd55
commit
3a4af49105
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: mdreloc.c,v 1.51 2011/03/25 18:07:06 joerg Exp $ */
|
||||
/* $NetBSD: mdreloc.c,v 1.52 2011/03/30 08:37:52 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 Eduardo Horvath.
|
||||
|
@ -32,7 +32,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: mdreloc.c,v 1.51 2011/03/25 18:07:06 joerg Exp $");
|
||||
__RCSID("$NetBSD: mdreloc.c,v 1.52 2011/03/30 08:37:52 martin Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <errno.h>
|
||||
|
@ -67,7 +67,7 @@ __RCSID("$NetBSD: mdreloc.c,v 1.51 2011/03/25 18:07:06 joerg Exp $");
|
|||
#define _RF_U 0x04000000 /* Unaligned */
|
||||
#define _RF_SZ(s) (((s) & 0xff) << 8) /* memory target size */
|
||||
#define _RF_RS(s) ( (s) & 0xff) /* right shift */
|
||||
static const int reloc_target_flags[] = {
|
||||
static const int reloc_target_flags[R_TYPE(TLS_TPOFF64)+1] = {
|
||||
0, /* NONE */
|
||||
_RF_S|_RF_A| _RF_SZ(8) | _RF_RS(0), /* RELOC_8 */
|
||||
_RF_S|_RF_A| _RF_SZ(16) | _RF_RS(0), /* RELOC_16 */
|
||||
|
@ -125,6 +125,7 @@ static const int reloc_target_flags[] = {
|
|||
_RF_S|_RF_A| _RF_SZ(64) | _RF_RS(0), /* REGISTER */
|
||||
_RF_S|_RF_A| _RF_U| _RF_SZ(64) | _RF_RS(0), /* UA64 */
|
||||
_RF_S|_RF_A| _RF_U| _RF_SZ(16) | _RF_RS(0), /* UA16 */
|
||||
/* TLS relocs not represented here! */
|
||||
};
|
||||
|
||||
#ifdef RTLD_DEBUG_RELOC
|
||||
|
@ -139,7 +140,13 @@ static const char *reloc_names[] = {
|
|||
"HM10", "LM22", "PC_HH22", "PC_HM10", "PC_LM22",
|
||||
"WDISP16", "WDISP19", "GLOB_JMP", "7", "5", "6",
|
||||
"DISP64", "PLT64", "HIX22", "LOX10", "H44", "M44",
|
||||
"L44", "REGISTER", "UA64", "UA16"
|
||||
"L44", "REGISTER", "UA64", "UA16",
|
||||
"TLS_GD_HI22", "TLS_GD_LO10", "TLS_GD_ADD", "TLS_GD_CALL",
|
||||
"TLS_LDM_HI22", "TLS_LDM_LO10", "TLS_LDM_ADD", "TLS_LDM_CALL",
|
||||
"TLS_LDO_HIX22", "TLS_LDO_LOX10", "TLS_LDO_ADD", "TLS_IE_HI22",
|
||||
"TLS_IE_LO10", "TLS_IE_LD", "TLS_IE_LDX", "TLS_IE_ADD", "TLS_LE_HIX22",
|
||||
"TLS_LE_LOX10", "TLS_DTPMOD32", "TLS_DTPMOD64", "TLS_DTPOFF32",
|
||||
"TLS_DTPOFF64", "TLS_TPOFF32", "TLS_TPOFF64",
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -150,6 +157,7 @@ static const char *reloc_names[] = {
|
|||
#define RELOC_USE_ADDEND(t) ((reloc_target_flags[t] & _RF_A) != 0)
|
||||
#define RELOC_TARGET_SIZE(t) ((reloc_target_flags[t] >> 8) & 0xff)
|
||||
#define RELOC_VALUE_RIGHTSHIFT(t) (reloc_target_flags[t] & 0xff)
|
||||
#define RELOC_TLS(t) (t >= R_TYPE(TLS_GD_HI22))
|
||||
|
||||
static const long reloc_target_bitmask[] = {
|
||||
#define _BM(x) (~(-(1ULL << (x))))
|
||||
|
@ -325,13 +333,73 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj)
|
|||
|
||||
/*
|
||||
* We use the fact that relocation types are an `enum'
|
||||
* Note: R_SPARC_UA16 is currently numerically largest.
|
||||
* Note: R_SPARC_TLS_TPOFF64 is currently numerically largest.
|
||||
*/
|
||||
if (type > R_TYPE(UA16))
|
||||
if (type > R_TYPE(TLS_TPOFF64))
|
||||
return (-1);
|
||||
|
||||
value = rela->r_addend;
|
||||
|
||||
/*
|
||||
* Handle TLS relocations here, they are different.
|
||||
*/
|
||||
if (RELOC_TLS(type)) {
|
||||
switch (type) {
|
||||
case R_TYPE(TLS_DTPMOD64):
|
||||
def = _rtld_find_symdef(symnum, obj,
|
||||
&defobj, false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
|
||||
*where = (Elf64_Addr)defobj->tlsindex;
|
||||
|
||||
rdbg(("TLS_DTPMOD64 %s in %s --> %p",
|
||||
obj->strtab +
|
||||
obj->symtab[symnum].st_name,
|
||||
obj->path, (void *)*where));
|
||||
|
||||
break;
|
||||
|
||||
case R_TYPE(TLS_DTPOFF64):
|
||||
def = _rtld_find_symdef(symnum, obj,
|
||||
&defobj, false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
|
||||
*where = (Elf64_Addr)(def->st_value
|
||||
+ rela->r_addend);
|
||||
|
||||
rdbg(("DTPOFF64 %s in %s --> %p",
|
||||
obj->strtab +
|
||||
obj->symtab[symnum].st_name,
|
||||
obj->path, (void *)*where));
|
||||
|
||||
break;
|
||||
|
||||
case R_TYPE(TLS_TPOFF64):
|
||||
def = _rtld_find_symdef(symnum, obj,
|
||||
&defobj, false);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
|
||||
if (!defobj->tls_done &&
|
||||
_rtld_tls_offset_allocate(obj))
|
||||
return -1;
|
||||
|
||||
*where = (Elf64_Addr)(def->st_value -
|
||||
defobj->tlsoffset +
|
||||
rela->r_addend);
|
||||
|
||||
rdbg(("TLS_TPOFF64 %s in %s --> %p",
|
||||
obj->strtab +
|
||||
obj->symtab[symnum].st_name,
|
||||
obj->path, (void *)*where));
|
||||
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle relative relocs here, as an optimization.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue