0
0
mirror of https://github.com/netwide-assembler/nasm.git synced 2025-09-22 10:43:39 -04:00

ELF32 support for offset to IE GOT entry

Add new WRT type ..tlsie.
Generate R_386_TLS_IE relocation entries
for references to thread local variables.
This commit is contained in:
Charles Crayne
2008-11-01 16:48:31 -07:00
parent b6e36102e6
commit 5fb6a39bc9

View File

@@ -39,6 +39,9 @@ enum reloc_type {
R_386_RELATIVE = 8, /* ??? */ R_386_RELATIVE = 8, /* ??? */
R_386_GOTOFF = 9, /* an offset from GOT base */ R_386_GOTOFF = 9, /* an offset from GOT base */
R_386_GOTPC = 10, /* a PC-relative offset _to_ GOT */ R_386_GOTPC = 10, /* a PC-relative offset _to_ GOT */
R_386_TLS_TPOFF = 14, /* Offset in static TLS block */
R_386_TLS_IE = 15, /* Address of GOT entry for static TLS
block offset */
/* These are GNU extensions, but useful */ /* These are GNU extensions, but useful */
R_386_16 = 20, /* A 16-bit absolute relocation */ R_386_16 = 20, /* A 16-bit absolute relocation */
R_386_PC16 = 21, /* A 16-bit PC-relative relocation */ R_386_PC16 = 21, /* A 16-bit PC-relative relocation */
@@ -287,12 +290,12 @@ void saa_wleb128s(struct SAA *, int);
/* /*
* Special section numbers which are used to define ELF special * Special section numbers which are used to define ELF special
* symbols, which can be used with WRT to provide PIC relocation * symbols, which can be used with WRT to provide PIC and TLS
* types. * relocation types.
*/ */
static int32_t elf_gotpc_sect, elf_gotoff_sect; static int32_t elf_gotpc_sect, elf_gotoff_sect;
static int32_t elf_got_sect, elf_plt_sect; static int32_t elf_got_sect, elf_plt_sect;
static int32_t elf_sym_sect; static int32_t elf_sym_sect, elf_tlsie_sect;
static void elf_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval) static void elf_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval)
{ {
@@ -332,6 +335,9 @@ static void elf_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval)
elf_sym_sect = seg_alloc(); elf_sym_sect = seg_alloc();
ldef("..sym", elf_sym_sect + 1, 0L, NULL, false, false, &of_elf32, ldef("..sym", elf_sym_sect + 1, 0L, NULL, false, false, &of_elf32,
error); error);
elf_tlsie_sect = seg_alloc();
ldef("..tlsie", elf_tlsie_sect + 1, 0L, NULL, false, false, &of_elf32,
error);
def_seg = seg_alloc(); def_seg = seg_alloc();
} }
@@ -544,7 +550,7 @@ static void elf_deflabel(char *name, int32_t segment, int64_t offset,
*/ */
if (strcmp(name, "..gotpc") && strcmp(name, "..gotoff") && if (strcmp(name, "..gotpc") && strcmp(name, "..gotoff") &&
strcmp(name, "..got") && strcmp(name, "..plt") && strcmp(name, "..got") && strcmp(name, "..plt") &&
strcmp(name, "..sym")) strcmp(name, "..sym") && strcmp(name, "..tlsie"))
error(ERR_NONFATAL, "unrecognised special symbol `%s'", name); error(ERR_NONFATAL, "unrecognised special symbol `%s'", name);
return; return;
} }
@@ -947,6 +953,9 @@ static void elf_out(int32_t segto, const void *data,
elf_add_reloc(s, segment, R_386_GOTPC); elf_add_reloc(s, segment, R_386_GOTPC);
} else if (wrt == elf_gotoff_sect + 1) { } else if (wrt == elf_gotoff_sect + 1) {
elf_add_reloc(s, segment, R_386_GOTOFF); elf_add_reloc(s, segment, R_386_GOTOFF);
} else if (wrt == elf_tlsie_sect + 1) {
addr = elf_add_gsym_reloc(s, segment, addr,
R_386_TLS_IE, true);
} else if (wrt == elf_got_sect + 1) { } else if (wrt == elf_got_sect + 1) {
addr = elf_add_gsym_reloc(s, segment, addr, addr = elf_add_gsym_reloc(s, segment, addr,
R_386_GOT32, true); R_386_GOT32, true);