Add thread-local storage support for ARM to rtld-elf
Reviewed by: cognet Obtained from: NetBSD
This commit is contained in:
parent
28bd45cae8
commit
ffed3e927f
@ -10,6 +10,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "machine/sysarch.h"
|
||||
|
||||
#include "debug.h"
|
||||
#include "rtld.h"
|
||||
|
||||
@ -233,6 +236,63 @@ reloc_nonplt_object(Obj_Entry *obj, const Elf_Rel *rel, SymCache *cache,
|
||||
dbg("COPY (avoid in main)");
|
||||
break;
|
||||
|
||||
case R_ARM_TLS_DTPOFF32:
|
||||
def = find_symdef(symnum, obj, &defobj, false, cache,
|
||||
lockstate);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
|
||||
tmp = (Elf_Addr)(def->st_value);
|
||||
if (__predict_true(RELOC_ALIGNED_P(where)))
|
||||
*where = tmp;
|
||||
else
|
||||
store_ptr(where, tmp);
|
||||
|
||||
dbg("TLS_DTPOFF32 %s in %s --> %p",
|
||||
obj->strtab + obj->symtab[symnum].st_name,
|
||||
obj->path, (void *)tmp);
|
||||
|
||||
break;
|
||||
case R_ARM_TLS_DTPMOD32:
|
||||
def = find_symdef(symnum, obj, &defobj, false, cache,
|
||||
lockstate);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
|
||||
tmp = (Elf_Addr)(defobj->tlsindex);
|
||||
if (__predict_true(RELOC_ALIGNED_P(where)))
|
||||
*where = tmp;
|
||||
else
|
||||
store_ptr(where, tmp);
|
||||
|
||||
dbg("TLS_DTPMOD32 %s in %s --> %p",
|
||||
obj->strtab + obj->symtab[symnum].st_name,
|
||||
obj->path, (void *)tmp);
|
||||
|
||||
break;
|
||||
|
||||
case R_ARM_TLS_TPOFF32:
|
||||
def = find_symdef(symnum, obj, &defobj, false, cache,
|
||||
lockstate);
|
||||
if (def == NULL)
|
||||
return -1;
|
||||
|
||||
if (!defobj->tls_done && allocate_tls_offset(obj))
|
||||
return -1;
|
||||
|
||||
/* XXX: FIXME */
|
||||
tmp = (Elf_Addr)def->st_value + defobj->tlsoffset +
|
||||
TLS_TCB_SIZE;
|
||||
if (__predict_true(RELOC_ALIGNED_P(where)))
|
||||
*where = tmp;
|
||||
else
|
||||
store_ptr(where, tmp);
|
||||
dbg("TLS_TPOFF32 %s in %s --> %p",
|
||||
obj->strtab + obj->symtab[symnum].st_name,
|
||||
obj->path, (void *)tmp);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
dbg("sym = %lu, type = %lu, offset = %p, "
|
||||
"contents = %p, symbol = %s",
|
||||
@ -369,11 +429,26 @@ reloc_jmpslot(Elf_Addr *where, Elf_Addr target, const Obj_Entry *defobj,
|
||||
void
|
||||
allocate_initial_tls(Obj_Entry *objs)
|
||||
{
|
||||
|
||||
void **_tp = (void **)ARM_TP_ADDRESS;
|
||||
|
||||
/*
|
||||
* Fix the size of the static TLS block by using the maximum
|
||||
* offset allocated so far and adding a bit for dynamic modules to
|
||||
* use.
|
||||
*/
|
||||
|
||||
tls_static_space = tls_last_offset + tls_last_size + RTLD_STATIC_TLS_EXTRA;
|
||||
|
||||
(*_tp) = (void *) allocate_tls(objs, NULL, TLS_TCB_SIZE, 8);
|
||||
}
|
||||
|
||||
void *
|
||||
__tls_get_addr(tls_index* ti)
|
||||
{
|
||||
return (NULL);
|
||||
void **_tp = (void **)ARM_TP_ADDRESS;
|
||||
char *p;
|
||||
|
||||
p = tls_get_addr_common((Elf_Addr **)(*_tp), ti->ti_module, ti->ti_offset);
|
||||
|
||||
return (p);
|
||||
}
|
||||
|
@ -48,20 +48,20 @@ Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
|
||||
#define call_initfini_pointer(obj, target) \
|
||||
(((InitFunc)(target))())
|
||||
|
||||
#define TLS_TCB_SIZE 8
|
||||
typedef struct {
|
||||
unsigned long ti_module;
|
||||
unsigned long ti_offset;
|
||||
} tls_index;
|
||||
|
||||
#define round(size, align) \
|
||||
(((size) + (align) - 1) & ~((align) - 1))
|
||||
(((size) + (align) - 1) & ~((align) - 1))
|
||||
#define calculate_first_tls_offset(size, align) \
|
||||
round(size, align)
|
||||
round(8, align)
|
||||
#define calculate_tls_offset(prev_offset, prev_size, size, align) \
|
||||
round(prev_offset + prev_size, align)
|
||||
round(prev_offset + prev_size, align)
|
||||
#define calculate_tls_end(off, size) ((off) + (size))
|
||||
|
||||
|
||||
/*
|
||||
* Lazy binding entry point, called via PLT.
|
||||
*/
|
||||
|
@ -3542,9 +3542,7 @@ tls_get_addr_common(Elf_Addr** dtvp, int index, size_t offset)
|
||||
return (void*) (dtv[index + 1] + offset);
|
||||
}
|
||||
|
||||
/* XXX not sure what variants to use for arm. */
|
||||
|
||||
#if defined(__ia64__) || defined(__powerpc__) || defined(__mips__)
|
||||
#if defined(__arm__) || defined(__ia64__) || defined(__mips__) || defined(__powerpc__)
|
||||
|
||||
/*
|
||||
* Allocate Static TLS using the Variant I method.
|
||||
@ -3625,8 +3623,7 @@ free_tls(void *tcb, size_t tcbsize, size_t tcbalign)
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__i386__) || defined(__amd64__) || defined(__sparc64__) || \
|
||||
defined(__arm__)
|
||||
#if defined(__i386__) || defined(__amd64__) || defined(__sparc64__)
|
||||
|
||||
/*
|
||||
* Allocate Static TLS using the Variant II method.
|
||||
|
Loading…
Reference in New Issue
Block a user