Implement TLS relocations for powerpc.
Approved by: grehan (mentor)
This commit is contained in:
parent
5bbd22ee8d
commit
6c2a9753f2
@ -206,6 +206,58 @@ reloc_nonplt_object(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela,
|
||||
*/
|
||||
break;
|
||||
|
||||
case R_PPC_DTPMOD32:
|
||||
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
|
||||
false, cache);
|
||||
|
||||
if (def == NULL)
|
||||
return (-1);
|
||||
|
||||
*where = (Elf_Addr) defobj->tlsindex;
|
||||
|
||||
break;
|
||||
|
||||
case R_PPC_TPREL32:
|
||||
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
|
||||
false, cache);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
*(Elf_Addr **)where = *where * sizeof(Elf_Addr)
|
||||
+ (Elf_Addr *)(def->st_value + rela->r_addend
|
||||
+ defobj->tlsoffset - TLS_TP_OFFSET - TLS_TCB_SIZE);
|
||||
|
||||
break;
|
||||
|
||||
case R_PPC_DTPREL32:
|
||||
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
|
||||
false, cache);
|
||||
|
||||
if (def == NULL)
|
||||
return (-1);
|
||||
|
||||
*where += (Elf_Addr)(def->st_value + rela->r_addend
|
||||
- TLS_DTV_OFFSET);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
_rtld_error("%s: Unsupported relocation type %d"
|
||||
" in non-PLT relocations\n", obj->path,
|
||||
@ -494,6 +546,7 @@ void
|
||||
allocate_initial_tls(Obj_Entry *list)
|
||||
{
|
||||
register Elf_Addr **tp __asm__("r2");
|
||||
Elf_Addr **_tp;
|
||||
|
||||
/*
|
||||
* Fix the size of the static TLS block by using the maximum
|
||||
@ -503,7 +556,14 @@ allocate_initial_tls(Obj_Entry *list)
|
||||
|
||||
tls_static_space = tls_last_offset + tls_last_size + RTLD_STATIC_TLS_EXTRA;
|
||||
|
||||
tp = (Elf_Addr **) ((char *) allocate_tls(list, 0, 8, 8) + 0x7008);
|
||||
_tp = (Elf_Addr **) ((char *) allocate_tls(list, 0, 8, 8)
|
||||
+ TLS_TP_OFFSET + TLS_TCB_SIZE);
|
||||
|
||||
/*
|
||||
* XXX gcc seems to ignore 'tp = _tp;'
|
||||
*/
|
||||
|
||||
__asm __volatile("mr %0,%1" : "=r"(tp) : "r"(_tp));
|
||||
}
|
||||
|
||||
void*
|
||||
@ -512,6 +572,8 @@ __tls_get_addr(tls_index* ti)
|
||||
register Elf_Addr **tp __asm__("r2");
|
||||
char *p;
|
||||
|
||||
p = tls_get_addr_common(tp, ti->ti_module, ti->ti_offset);
|
||||
return p + 0x8000;
|
||||
p = tls_get_addr_common((Elf_Addr**)((Elf_Addr)tp - TLS_TP_OFFSET
|
||||
- TLS_TCB_SIZE), ti->ti_module, ti->ti_offset);
|
||||
|
||||
return (p + TLS_DTV_OFFSET);
|
||||
}
|
||||
|
@ -62,6 +62,14 @@ void _rtld_bind_start(void);
|
||||
void _rtld_powerpc_pltresolve(void);
|
||||
void _rtld_powerpc_pltcall(void);
|
||||
|
||||
/*
|
||||
* TLS
|
||||
*/
|
||||
|
||||
#define TLS_TP_OFFSET 0x7000
|
||||
#define TLS_DTV_OFFSET 0x8000
|
||||
#define TLS_TCB_SIZE 8
|
||||
|
||||
#define round(size, align) \
|
||||
(((size) + (align) - 1) & ~((align) - 1))
|
||||
#define calculate_first_tls_offset(size, align) \
|
||||
|
@ -127,6 +127,34 @@ __ElfType(Auxinfo);
|
||||
|
||||
#define R_PPC_COUNT 37 /* Count of defined relocation types. */
|
||||
|
||||
/*
|
||||
* TLS relocations
|
||||
*/
|
||||
#define R_PPC_TLS 67
|
||||
#define R_PPC_DTPMOD32 68
|
||||
#define R_PPC_TPREL16 69
|
||||
#define R_PPC_TPREL16_LO 70
|
||||
#define R_PPC_TPREL16_HI 71
|
||||
#define R_PPC_TPREL16_HA 72
|
||||
#define R_PPC_TPREL32 73
|
||||
#define R_PPC_DTPREL16 74
|
||||
#define R_PPC_DTPREL16_LO 75
|
||||
#define R_PPC_DTPREL16_HI 76
|
||||
#define R_PPC_DTPREL16_HA 77
|
||||
#define R_PPC_DTPREL32 78
|
||||
#define R_PPC_GOT_TLSGD16 79
|
||||
#define R_PPC_GOT_TLSGD16_LO 80
|
||||
#define R_PPC_GOT_TLSGD16_HI 81
|
||||
#define R_PPC_GOT_TLSGD16_HA 82
|
||||
#define R_PPC_GOT_TLSLD16 83
|
||||
#define R_PPC_GOT_TLSLD16_LO 84
|
||||
#define R_PPC_GOT_TLSLD16_HI 85
|
||||
#define R_PPC_GOT_TLSLD16_HA 86
|
||||
#define R_PPC_GOT_TPREL16 87
|
||||
#define R_PPC_GOT_TPREL16_LO 88
|
||||
#define R_PPC_GOT_TPREL16_HI 89
|
||||
#define R_PPC_GOT_TPREL16_HA 90
|
||||
|
||||
/*
|
||||
* The remaining relocs are from the Embedded ELF ABI, and are not in the
|
||||
* SVR4 ELF ABI.
|
||||
|
Loading…
x
Reference in New Issue
Block a user