mirror of
https://git.musl-libc.org/git/musl
synced 2025-01-24 07:02:03 +03:00
refactor to remove arch-specific relocation code from dynamic linker
this was one of the main instances of ugly code duplication: all archs use basically the same types of relocations, but roughly equivalent logic was duplicated for each arch to account for the different naming and numbering of relocation types and variation in whether REL or RELA records are used. as an added bonus, both REL and RELA are now supported on all archs, regardless of which is used by the standard toolchain.
This commit is contained in:
parent
94cf991bf4
commit
adf94c1966
@ -16,42 +16,29 @@
|
||||
|
||||
#define LDSO_ARCH "arm" ENDIAN_SUFFIX FP_SUFFIX
|
||||
|
||||
#define IS_COPY(x) ((x)==R_ARM_COPY)
|
||||
#define IS_PLT(x) ((x)==R_ARM_JUMP_SLOT)
|
||||
#define NO_LEGACY_INITFINI
|
||||
|
||||
static inline int do_single_reloc(
|
||||
struct dso *self, unsigned char *base_addr,
|
||||
size_t *reloc_addr, int type, size_t addend,
|
||||
Sym *sym, size_t sym_size,
|
||||
struct symdef def, size_t sym_val)
|
||||
#define TPOFF_K 8
|
||||
|
||||
static int remap_rel(int type)
|
||||
{
|
||||
switch(type) {
|
||||
case R_ARM_ABS32:
|
||||
*reloc_addr += sym_val;
|
||||
break;
|
||||
return REL_SYMBOLIC;
|
||||
case R_ARM_GLOB_DAT:
|
||||
return REL_GOT;
|
||||
case R_ARM_JUMP_SLOT:
|
||||
*reloc_addr = sym_val;
|
||||
break;
|
||||
return REL_PLT;
|
||||
case R_ARM_RELATIVE:
|
||||
*reloc_addr += (size_t)base_addr;
|
||||
break;
|
||||
return REL_RELATIVE;
|
||||
case R_ARM_COPY:
|
||||
memcpy(reloc_addr, (void *)sym_val, sym_size);
|
||||
break;
|
||||
return REL_COPY;
|
||||
case R_ARM_TLS_DTPMOD32:
|
||||
*reloc_addr = def.dso ? def.dso->tls_id : self->tls_id;
|
||||
break;
|
||||
return REL_DTPMOD;
|
||||
case R_ARM_TLS_DTPOFF32:
|
||||
*reloc_addr += def.sym->st_value;
|
||||
break;
|
||||
return REL_DTPOFF;
|
||||
case R_ARM_TLS_TPOFF32:
|
||||
*reloc_addr += def.sym
|
||||
? def.sym->st_value + def.dso->tls_offset + 8
|
||||
: self->tls_offset + 8;
|
||||
break;
|
||||
return REL_TPOFF;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define NO_LEGACY_INITFINI
|
||||
|
@ -3,48 +3,29 @@
|
||||
|
||||
#define LDSO_ARCH "i386"
|
||||
|
||||
#define IS_COPY(x) ((x)==R_386_COPY)
|
||||
#define IS_PLT(x) ((x)==R_386_JMP_SLOT)
|
||||
|
||||
static inline int do_single_reloc(
|
||||
struct dso *self, unsigned char *base_addr,
|
||||
size_t *reloc_addr, int type, size_t addend,
|
||||
Sym *sym, size_t sym_size,
|
||||
struct symdef def, size_t sym_val)
|
||||
static int remap_rel(int type)
|
||||
{
|
||||
switch(type) {
|
||||
case R_386_32:
|
||||
*reloc_addr += sym_val;
|
||||
break;
|
||||
return REL_SYMBOLIC;
|
||||
case R_386_PC32:
|
||||
*reloc_addr += sym_val - (size_t)reloc_addr;
|
||||
break;
|
||||
return REL_OFFSET;
|
||||
case R_386_GLOB_DAT:
|
||||
return REL_GOT;
|
||||
case R_386_JMP_SLOT:
|
||||
*reloc_addr = sym_val;
|
||||
break;
|
||||
return REL_PLT;
|
||||
case R_386_RELATIVE:
|
||||
*reloc_addr += (size_t)base_addr;
|
||||
break;
|
||||
return REL_RELATIVE;
|
||||
case R_386_COPY:
|
||||
memcpy(reloc_addr, (void *)sym_val, sym_size);
|
||||
break;
|
||||
return REL_COPY;
|
||||
case R_386_TLS_DTPMOD32:
|
||||
*reloc_addr = def.dso ? def.dso->tls_id : self->tls_id;
|
||||
break;
|
||||
return REL_DTPMOD;
|
||||
case R_386_TLS_DTPOFF32:
|
||||
*reloc_addr = def.sym->st_value;
|
||||
break;
|
||||
return REL_DTPOFF;
|
||||
case R_386_TLS_TPOFF:
|
||||
*reloc_addr += def.sym
|
||||
? def.sym->st_value - def.dso->tls_offset
|
||||
: 0 - self->tls_offset;
|
||||
break;
|
||||
return REL_TPOFF;
|
||||
case R_386_TLS_TPOFF32:
|
||||
*reloc_addr += def.sym
|
||||
? def.dso->tls_offset - def.sym->st_value
|
||||
: self->tls_offset;
|
||||
break;
|
||||
return REL_TPOFF_NEG;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -10,33 +10,25 @@
|
||||
|
||||
#define LDSO_ARCH "microblaze" ENDIAN_SUFFIX
|
||||
|
||||
#define IS_COPY(x) ((x)==R_MICROBLAZE_COPY)
|
||||
#define IS_PLT(x) ((x)==R_MICROBLAZE_JUMP_SLOT)
|
||||
#define TPOFF_K 0
|
||||
|
||||
static inline int do_single_reloc(
|
||||
struct dso *self, unsigned char *base_addr,
|
||||
size_t *reloc_addr, int type, size_t addend,
|
||||
Sym *sym, size_t sym_size,
|
||||
struct symdef def, size_t sym_val)
|
||||
static int remap_rel(int type)
|
||||
{
|
||||
switch(type) {
|
||||
case R_MICROBLAZE_32:
|
||||
return REL_SYMBOLIC;
|
||||
case R_MICROBLAZE_GLOB_DAT:
|
||||
return REL_GOT;
|
||||
case R_MICROBLAZE_JUMP_SLOT:
|
||||
*reloc_addr = sym_val + addend;
|
||||
break;
|
||||
return REL_PLT;
|
||||
case R_MICROBLAZE_REL:
|
||||
*reloc_addr = (size_t)base_addr + addend;
|
||||
break;
|
||||
return REL_RELATIVE;
|
||||
case R_MICROBLAZE_COPY:
|
||||
memcpy(reloc_addr, (void *)sym_val, sym_size);
|
||||
break;
|
||||
return REL_COPY;
|
||||
case R_MICROBLAZE_TLSDTPMOD32:
|
||||
*reloc_addr = def.dso ? def.dso->tls_id : self->tls_id;
|
||||
break;
|
||||
return REL_DTPMOD;
|
||||
case R_MICROBLAZE_TLSDTPREL32:
|
||||
*reloc_addr = def.sym->st_value + addend;
|
||||
break;
|
||||
return REL_DTPOFF;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -16,37 +16,23 @@
|
||||
|
||||
#define LDSO_ARCH "mips" ENDIAN_SUFFIX FP_SUFFIX
|
||||
|
||||
#define IS_COPY(x) ((x)==R_MIPS_COPY)
|
||||
#define IS_PLT(x) 1
|
||||
#define TPOFF_K (-0x7000)
|
||||
|
||||
static inline int do_single_reloc(
|
||||
struct dso *self, unsigned char *base_addr,
|
||||
size_t *reloc_addr, int type, size_t addend,
|
||||
Sym *sym, size_t sym_size,
|
||||
struct symdef def, size_t sym_val)
|
||||
static int remap_rel(int type)
|
||||
{
|
||||
switch(type) {
|
||||
case R_MIPS_JUMP_SLOT:
|
||||
*reloc_addr = sym_val;
|
||||
break;
|
||||
case R_MIPS_REL32:
|
||||
if (sym_val) *reloc_addr += sym_val;
|
||||
else *reloc_addr += (size_t)base_addr;
|
||||
break;
|
||||
return REL_SYM_OR_REL;
|
||||
case R_MIPS_JUMP_SLOT:
|
||||
return REL_PLT;
|
||||
case R_MIPS_COPY:
|
||||
memcpy(reloc_addr, (void *)sym_val, sym_size);
|
||||
break;
|
||||
return REL_COPY;
|
||||
case R_MIPS_TLS_DTPMOD32:
|
||||
*reloc_addr = def.dso ? def.dso->tls_id : self->tls_id;
|
||||
break;
|
||||
return REL_DTPMOD;
|
||||
case R_MIPS_TLS_DTPREL32:
|
||||
*reloc_addr += def.sym->st_value;
|
||||
break;
|
||||
return REL_DTPOFF;
|
||||
case R_MIPS_TLS_TPREL32:
|
||||
*reloc_addr += def.sym
|
||||
? def.sym->st_value + def.dso->tls_offset - 0x7000
|
||||
: self->tls_offset - 0x7000;
|
||||
break;
|
||||
return REL_TPOFF;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -3,39 +3,27 @@
|
||||
|
||||
#define LDSO_ARCH "powerpc"
|
||||
|
||||
#define IS_COPY(x) ((x)==R_PPC_COPY)
|
||||
#define IS_PLT(x) ((x)==R_PPC_JMP_SLOT)
|
||||
#define TPOFF_K (-0x7000)
|
||||
|
||||
// see linux' arch/powerpc/include/asm/elf.h
|
||||
static inline int do_single_reloc(
|
||||
struct dso *self, unsigned char *base_addr,
|
||||
size_t *reloc_addr, int type, size_t addend,
|
||||
Sym *sym, size_t sym_size,
|
||||
struct symdef def, size_t sym_val)
|
||||
static int remap_rel(int type)
|
||||
{
|
||||
switch(type) {
|
||||
case R_PPC_GLOB_DAT:
|
||||
case R_PPC_JMP_SLOT:
|
||||
case R_PPC_ADDR32:
|
||||
*reloc_addr = sym_val + addend;
|
||||
break;
|
||||
case R_PPC_COPY:
|
||||
memcpy(reloc_addr, (void *)sym_val, sym_size);
|
||||
break;
|
||||
return REL_SYMBOLIC;
|
||||
case R_PPC_GLOB_DAT:
|
||||
return REL_GOT;
|
||||
case R_PPC_JMP_SLOT:
|
||||
return REL_PLT;
|
||||
case R_PPC_RELATIVE:
|
||||
*reloc_addr = (size_t)base_addr + addend;
|
||||
break;
|
||||
return REL_RELATIVE;
|
||||
case R_PPC_COPY:
|
||||
return REL_COPY;
|
||||
case R_PPC_DTPMOD32:
|
||||
*reloc_addr = def.dso ? def.dso->tls_id : self->tls_id;
|
||||
break;
|
||||
return REL_DTPMOD;
|
||||
case R_PPC_DTPREL32:
|
||||
*reloc_addr = def.sym->st_value + addend;
|
||||
break;
|
||||
return REL_DTPOFF;
|
||||
case R_PPC_TPREL32:
|
||||
*reloc_addr = (def.sym
|
||||
? def.sym->st_value + def.dso->tls_offset
|
||||
: self->tls_offset) - 0x7000 + addend;
|
||||
break;
|
||||
return REL_TPOFF;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -6,41 +6,29 @@
|
||||
|
||||
#define LDSO_ARCH "sh" ENDIAN_SUFFIX
|
||||
|
||||
#define IS_COPY(x) ((x) == R_SH_COPY)
|
||||
#define IS_PLT(x) ((x) == R_SH_JMP_SLOT)
|
||||
#define TPOFF_K 8
|
||||
|
||||
static inline int do_single_reloc(
|
||||
struct dso *self, unsigned char *base_addr,
|
||||
size_t *reloc_addr, int type, size_t addend,
|
||||
Sym *sym, size_t sym_size,
|
||||
struct symdef def, size_t sym_val)
|
||||
static int remap_rel(int type)
|
||||
{
|
||||
switch(type) {
|
||||
case R_SH_GLOB_DAT:
|
||||
case R_SH_JMP_SLOT:
|
||||
case R_SH_DIR32:
|
||||
*reloc_addr = sym_val + addend;
|
||||
break;
|
||||
case R_SH_RELATIVE:
|
||||
*reloc_addr = (size_t)base_addr + addend;
|
||||
break;
|
||||
return REL_SYMBOLIC;
|
||||
case R_SH_REL32:
|
||||
*reloc_addr = sym_val + addend - (size_t)reloc_addr;
|
||||
break;
|
||||
return REL_OFFSET;
|
||||
case R_SH_GLOB_DAT:
|
||||
return REL_GOT;
|
||||
case R_SH_JMP_SLOT:
|
||||
return REL_PLT;
|
||||
case R_SH_RELATIVE:
|
||||
return REL_RELATIVE;
|
||||
case R_SH_COPY:
|
||||
memcpy(reloc_addr, (void *)sym_val, sym_size);
|
||||
break;
|
||||
return REL_COPY;
|
||||
case R_SH_TLS_DTPMOD32:
|
||||
*reloc_addr = def.dso ? def.dso->tls_id : self->tls_id;
|
||||
break;
|
||||
return REL_DTPMOD;
|
||||
case R_SH_TLS_DTPOFF32:
|
||||
*reloc_addr = def.sym->st_value + addend;
|
||||
break;
|
||||
return REL_DTPOFF;
|
||||
case R_SH_TLS_TPOFF32:
|
||||
*reloc_addr = (def.sym
|
||||
? def.sym->st_value + def.dso->tls_offset
|
||||
: self->tls_offset) + 8 + addend;
|
||||
break;
|
||||
return REL_TPOFF;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -4,44 +4,37 @@
|
||||
|
||||
#define LDSO_ARCH "x32"
|
||||
|
||||
#define IS_COPY(x) ((x)==R_X86_64_COPY)
|
||||
#define IS_PLT(x) ((x)==R_X86_64_JUMP_SLOT)
|
||||
/* FIXME: x32 is very strange in its use of 64-bit relocation types in
|
||||
* a 32-bit environment. As long as the memory at reloc_addr is
|
||||
* zero-filled prior to relocations, just treating 64-bit relocations
|
||||
* as operating on 32-bit slots should be fine, but this should be
|
||||
* checked. In particular, R_X86_64_64, R_X86_64_DTPOFF64, and
|
||||
* R_X86_64_TPOFF64 may need checking. */
|
||||
|
||||
static inline int do_single_reloc(
|
||||
struct dso *self, unsigned char *base_addr,
|
||||
size_t *reloc_addr, int type, size_t addend,
|
||||
Sym *sym, size_t sym_size,
|
||||
struct symdef def, size_t sym_val)
|
||||
static int remap_rel(int type)
|
||||
{
|
||||
switch(type) {
|
||||
case R_X86_64_GLOB_DAT:
|
||||
case R_X86_64_JUMP_SLOT:
|
||||
case R_X86_64_64:
|
||||
*reloc_addr = sym_val + addend;
|
||||
break;
|
||||
case R_X86_64_32:
|
||||
*(uint32_t *)reloc_addr = sym_val + addend;
|
||||
break;
|
||||
return REL_SYMBOLIC;
|
||||
case R_X86_64_PC32:
|
||||
*reloc_addr = sym_val + addend - (size_t)reloc_addr + (size_t)base_addr;
|
||||
break;
|
||||
return REL_OFFSET;
|
||||
case R_X86_64_GLOB_DAT:
|
||||
return REL_GOT;
|
||||
case R_X86_64_JUMP_SLOT:
|
||||
return REL_PLT;
|
||||
case R_X86_64_RELATIVE:
|
||||
*reloc_addr = (size_t)base_addr + addend;
|
||||
break;
|
||||
return REL_RELATIVE;
|
||||
case R_X86_64_COPY:
|
||||
memcpy(reloc_addr, (void *)sym_val, sym_size);
|
||||
break;
|
||||
return REL_COPY;
|
||||
case R_X86_64_DTPMOD64:
|
||||
*reloc_addr = def.dso ? def.dso->tls_id : self->tls_id;
|
||||
break;
|
||||
return REL_DTPMOD;
|
||||
case R_X86_64_DTPOFF64:
|
||||
*reloc_addr = def.sym->st_value + addend;
|
||||
break;
|
||||
case R_X86_64_DTPOFF32:
|
||||
return REL_DTPOFF;
|
||||
case R_X86_64_TPOFF64:
|
||||
*reloc_addr = (def.sym
|
||||
? def.sym->st_value - def.dso->tls_offset
|
||||
: 0 - self->tls_offset) + addend;
|
||||
break;
|
||||
case R_X86_64_TPOFF32:
|
||||
return REL_TPOFF;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -4,44 +4,27 @@
|
||||
|
||||
#define LDSO_ARCH "x86_64"
|
||||
|
||||
#define IS_COPY(x) ((x)==R_X86_64_COPY)
|
||||
#define IS_PLT(x) ((x)==R_X86_64_JUMP_SLOT)
|
||||
|
||||
static inline int do_single_reloc(
|
||||
struct dso *self, unsigned char *base_addr,
|
||||
size_t *reloc_addr, int type, size_t addend,
|
||||
Sym *sym, size_t sym_size,
|
||||
struct symdef def, size_t sym_val)
|
||||
static int remap_rel(int type)
|
||||
{
|
||||
switch(type) {
|
||||
case R_X86_64_GLOB_DAT:
|
||||
case R_X86_64_JUMP_SLOT:
|
||||
case R_X86_64_64:
|
||||
*reloc_addr = sym_val + addend;
|
||||
break;
|
||||
case R_X86_64_32:
|
||||
*(uint32_t *)reloc_addr = sym_val + addend;
|
||||
break;
|
||||
return REL_SYMBOLIC;
|
||||
case R_X86_64_PC32:
|
||||
*reloc_addr = sym_val + addend - (size_t)reloc_addr + (size_t)base_addr;
|
||||
break;
|
||||
return REL_OFFSET32;
|
||||
case R_X86_64_GLOB_DAT:
|
||||
return REL_GOT;
|
||||
case R_X86_64_JUMP_SLOT:
|
||||
return REL_PLT;
|
||||
case R_X86_64_RELATIVE:
|
||||
*reloc_addr = (size_t)base_addr + addend;
|
||||
break;
|
||||
return REL_RELATIVE;
|
||||
case R_X86_64_COPY:
|
||||
memcpy(reloc_addr, (void *)sym_val, sym_size);
|
||||
break;
|
||||
return REL_COPY;
|
||||
case R_X86_64_DTPMOD64:
|
||||
*reloc_addr = def.dso ? def.dso->tls_id : self->tls_id;
|
||||
break;
|
||||
return REL_DTPMOD;
|
||||
case R_X86_64_DTPOFF64:
|
||||
*reloc_addr = def.sym->st_value + addend;
|
||||
break;
|
||||
return REL_DTPOFF;
|
||||
case R_X86_64_TPOFF64:
|
||||
*reloc_addr = (def.sym
|
||||
? def.sym->st_value - def.dso->tls_offset
|
||||
: 0 - self->tls_offset) + addend;
|
||||
break;
|
||||
return REL_TPOFF;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -89,6 +89,23 @@ struct symdef {
|
||||
struct dso *dso;
|
||||
};
|
||||
|
||||
enum {
|
||||
REL_ERR,
|
||||
REL_SYMBOLIC,
|
||||
REL_GOT,
|
||||
REL_PLT,
|
||||
REL_RELATIVE,
|
||||
REL_OFFSET,
|
||||
REL_OFFSET32,
|
||||
REL_COPY,
|
||||
REL_SYM_OR_REL,
|
||||
REL_TLS, /* everything past here is TLS */
|
||||
REL_DTPMOD,
|
||||
REL_DTPOFF,
|
||||
REL_TPOFF,
|
||||
REL_TPOFF_NEG,
|
||||
};
|
||||
|
||||
#include "reloc.h"
|
||||
|
||||
int __init_tp(void *);
|
||||
@ -227,6 +244,8 @@ static struct symdef find_sym(struct dso *dso, const char *s, int need_def)
|
||||
return def;
|
||||
}
|
||||
|
||||
#define NO_INLINE_ADDEND (1<<REL_COPY | 1<<REL_GOT | 1<<REL_PLT)
|
||||
|
||||
static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stride)
|
||||
{
|
||||
unsigned char *base = dso->base;
|
||||
@ -235,18 +254,34 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
|
||||
Sym *sym;
|
||||
const char *name;
|
||||
void *ctx;
|
||||
int type;
|
||||
int astype, type;
|
||||
int sym_index;
|
||||
struct symdef def;
|
||||
size_t *reloc_addr;
|
||||
size_t sym_val;
|
||||
size_t tls_val;
|
||||
size_t addend;
|
||||
|
||||
for (; rel_size; rel+=stride, rel_size-=stride*sizeof(size_t)) {
|
||||
type = R_TYPE(rel[1]);
|
||||
astype = R_TYPE(rel[1]);
|
||||
if (!astype) continue;
|
||||
type = remap_rel(astype);
|
||||
if (!type) {
|
||||
snprintf(errbuf, sizeof errbuf,
|
||||
"Error relocating %s: unsupported relocation type %d",
|
||||
dso->name, astype);
|
||||
if (runtime) longjmp(*rtld_fail, 1);
|
||||
dprintf(2, "%s\n", errbuf);
|
||||
ldso_fail = 1;
|
||||
continue;
|
||||
}
|
||||
sym_index = R_SYM(rel[1]);
|
||||
reloc_addr = (void *)(base + rel[0]);
|
||||
if (sym_index) {
|
||||
sym = syms + sym_index;
|
||||
name = strings + sym->st_name;
|
||||
ctx = IS_COPY(type) ? head->next : head;
|
||||
def = find_sym(ctx, name, IS_PLT(type));
|
||||
ctx = type==REL_COPY ? head->next : head;
|
||||
def = find_sym(ctx, name, type==REL_PLT);
|
||||
if (!def.sym && (sym->st_shndx != SHN_UNDEF
|
||||
|| sym->st_info>>4 != STB_WEAK)) {
|
||||
snprintf(errbuf, sizeof errbuf,
|
||||
@ -260,11 +295,57 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
|
||||
} else {
|
||||
sym = 0;
|
||||
def.sym = 0;
|
||||
def.dso = 0;
|
||||
def.dso = dso;
|
||||
}
|
||||
|
||||
addend = stride>2 ? rel[2]
|
||||
: (1<<type & NO_INLINE_ADDEND) ? 0
|
||||
: *reloc_addr;
|
||||
|
||||
sym_val = def.sym ? (size_t)def.dso->base+def.sym->st_value : 0;
|
||||
tls_val = def.sym ? def.sym->st_value : 0;
|
||||
|
||||
switch(type) {
|
||||
case REL_OFFSET:
|
||||
addend -= (size_t)reloc_addr;
|
||||
case REL_SYMBOLIC:
|
||||
case REL_GOT:
|
||||
case REL_PLT:
|
||||
*reloc_addr = sym_val + addend;
|
||||
break;
|
||||
case REL_RELATIVE:
|
||||
*reloc_addr = (size_t)base + addend;
|
||||
break;
|
||||
case REL_SYM_OR_REL:
|
||||
if (sym) *reloc_addr = sym_val + addend;
|
||||
else *reloc_addr = (size_t)base + addend;
|
||||
break;
|
||||
case REL_COPY:
|
||||
memcpy(reloc_addr, (void *)sym_val, sym->st_size);
|
||||
break;
|
||||
case REL_OFFSET32:
|
||||
*(uint32_t *)reloc_addr = sym_val + addend
|
||||
- (size_t)reloc_addr;
|
||||
break;
|
||||
case REL_DTPMOD:
|
||||
*reloc_addr = def.dso->tls_id;
|
||||
break;
|
||||
case REL_DTPOFF:
|
||||
*reloc_addr = tls_val + addend;
|
||||
break;
|
||||
#ifdef TLS_ABOVE_TP
|
||||
case REL_TPOFF:
|
||||
*reloc_addr = tls_val + def.dso->tls_offset + TPOFF_K + addend;
|
||||
break;
|
||||
#else
|
||||
case REL_TPOFF:
|
||||
*reloc_addr = tls_val - def.dso->tls_offset + addend;
|
||||
break;
|
||||
case REL_TPOFF_NEG:
|
||||
*reloc_addr = def.dso->tls_offset - tls_val + addend;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
do_single_reloc(dso, base, (void *)(base + rel[0]), type,
|
||||
stride>2 ? rel[2] : 0, sym, sym?sym->st_size:0, def,
|
||||
def.sym?(size_t)(def.dso->base+def.sym->st_value):0);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user