mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-01-18 16:25:05 +08:00
ELF64 support for PC relative offset to IE GOT entry
Add new WRT type ..gottpoff. Generate R_X86_64_GOTTPOFF relocation entries for references to thread local variables.
This commit is contained in:
parent
b0e0718267
commit
10a863d87e
@ -335,6 +335,7 @@ void dwarf64_findsect(const int);
|
|||||||
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;
|
||||||
|
static int32_t elf_gottpoff_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)
|
||||||
{
|
{
|
||||||
@ -373,6 +374,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_elf64,
|
ldef("..sym", elf_sym_sect + 1, 0L, NULL, false, false, &of_elf64,
|
||||||
error);
|
error);
|
||||||
|
elf_gottpoff_sect = seg_alloc();
|
||||||
|
ldef("..gottpoff", elf_gottpoff_sect + 1, 0L, NULL, false, false, &of_elf64,
|
||||||
|
error);
|
||||||
|
|
||||||
def_seg = seg_alloc();
|
def_seg = seg_alloc();
|
||||||
|
|
||||||
@ -587,7 +591,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, "..gottpoff"))
|
||||||
error(ERR_NONFATAL, "unrecognised special symbol `%s'", name);
|
error(ERR_NONFATAL, "unrecognised special symbol `%s'", name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -776,7 +780,6 @@ static void elf_deflabel(char *name, int32_t segment, int64_t offset,
|
|||||||
* If TLS segment, mark symbol accordingly.
|
* If TLS segment, mark symbol accordingly.
|
||||||
*/
|
*/
|
||||||
if (sects[sym->section - 1]->flags & SHF_TLS) {
|
if (sects[sym->section - 1]->flags & SHF_TLS) {
|
||||||
error(ERR_DEBUG, "marked %s as TLS",name);
|
|
||||||
sym->type &= 0xf0;
|
sym->type &= 0xf0;
|
||||||
sym->type |= STT_TLS;
|
sym->type |= STT_TLS;
|
||||||
}
|
}
|
||||||
@ -1028,7 +1031,7 @@ static void elf_out(int32_t segto, const void *data,
|
|||||||
} else if (wrt == elf_gotoff_sect + 1) {
|
} else if (wrt == elf_gotoff_sect + 1) {
|
||||||
if (size != 8) {
|
if (size != 8) {
|
||||||
error(ERR_NONFATAL, "ELF64 requires ..gotoff "
|
error(ERR_NONFATAL, "ELF64 requires ..gotoff "
|
||||||
"references to be qword absolute");
|
"references to be qword");
|
||||||
} else {
|
} else {
|
||||||
elf_add_reloc(s, segment, addr, R_X86_64_GOTOFF64);
|
elf_add_reloc(s, segment, addr, R_X86_64_GOTOFF64);
|
||||||
addr = 0;
|
addr = 0;
|
||||||
@ -1129,6 +1132,10 @@ static void elf_out(int32_t segto, const void *data,
|
|||||||
wrt == elf_got_sect + 1) {
|
wrt == elf_got_sect + 1) {
|
||||||
error(ERR_NONFATAL, "ELF64 requires ..gotoff references to be "
|
error(ERR_NONFATAL, "ELF64 requires ..gotoff references to be "
|
||||||
"qword absolute");
|
"qword absolute");
|
||||||
|
} else if (wrt == elf_gottpoff_sect + 1) {
|
||||||
|
elf_add_gsym_reloc(s, segment, addr+size, size,
|
||||||
|
R_X86_64_GOTTPOFF, true);
|
||||||
|
addr = 0;
|
||||||
} else {
|
} else {
|
||||||
error(ERR_NONFATAL, "ELF64 format does not support this"
|
error(ERR_NONFATAL, "ELF64 format does not support this"
|
||||||
" use of WRT");
|
" use of WRT");
|
||||||
@ -1156,7 +1163,10 @@ static void elf_out(int32_t segto, const void *data,
|
|||||||
} else if (wrt == elf_gotoff_sect + 1 ||
|
} else if (wrt == elf_gotoff_sect + 1 ||
|
||||||
wrt == elf_got_sect + 1) {
|
wrt == elf_got_sect + 1) {
|
||||||
error(ERR_NONFATAL, "ELF64 requires ..gotoff references to be "
|
error(ERR_NONFATAL, "ELF64 requires ..gotoff references to be "
|
||||||
"qword absolute");
|
"absolute");
|
||||||
|
} else if (wrt == elf_gottpoff_sect + 1) {
|
||||||
|
error(ERR_NONFATAL, "ELF64 requires ..gottpoff references to be "
|
||||||
|
"dword");
|
||||||
} else {
|
} else {
|
||||||
error(ERR_NONFATAL, "ELF64 format does not support this"
|
error(ERR_NONFATAL, "ELF64 format does not support this"
|
||||||
" use of WRT");
|
" use of WRT");
|
||||||
|
Loading…
Reference in New Issue
Block a user