enum {
ELF_SSYM_SYM_RELATIVE = 1 << 0,
- ELF_SSYM_CURPOS_ADJUST = 1 << 1
+ ELF_SSYM_CURPOS_ADJUST = 1 << 1,
+ ELF_SSYM_THREAD_LOCAL = 1 << 2
};
typedef struct {
} else if (strcmp(sectname, ".data") == 0) {
data.type = SHT_PROGBITS;
data.flags = SHF_ALLOC + SHF_WRITE;
+ } else if (strcmp(sectname, ".tdata") == 0) {
+ data.type = SHT_PROGBITS;
+ data.flags = SHF_ALLOC + SHF_WRITE;
} else if (strcmp(sectname, ".rodata") == 0) {
data.type = SHT_PROGBITS;
data.flags = SHF_ALLOC;
elf_sym_set_type(entry, STT_FUNC);
else if (yasm__strcasecmp(type, "object") == 0)
elf_sym_set_type(entry, STT_OBJECT);
+ else if (yasm__strcasecmp(type, "tls_object") == 0)
+ elf_sym_set_type(entry, STT_TLS);
+ else if (yasm__strcasecmp(type, "notype") == 0)
+ elf_sym_set_type(entry, STT_NOTYPE);
else
yasm_warn_set(YASM_WARN_GENERAL,
N_("unrecognized symbol type `%s'"), type);
static elf_machine_ssym elf_x86_amd64_ssyms[] = {
{"plt", ELF_SSYM_SYM_RELATIVE, R_X86_64_PLT32, 32},
{"gotpcrel", ELF_SSYM_SYM_RELATIVE, R_X86_64_GOTPCREL, 32},
- {"tlsgd", ELF_SSYM_SYM_RELATIVE, R_X86_64_TLSGD, 32},
- {"tlsld", ELF_SSYM_SYM_RELATIVE, R_X86_64_TLSLD, 32},
- {"gottpoff", ELF_SSYM_SYM_RELATIVE, R_X86_64_GOTTPOFF, 32},
- {"tpoff", ELF_SSYM_SYM_RELATIVE, R_X86_64_TPOFF32, 32},
- {"dtpoff", ELF_SSYM_SYM_RELATIVE, R_X86_64_DTPOFF32, 32},
+ {"tlsgd", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL,
+ R_X86_64_TLSGD, 32},
+ {"tlsld", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL,
+ R_X86_64_TLSLD, 32},
+ {"gottpoff", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL,
+ R_X86_64_GOTTPOFF, 32},
+ {"tpoff", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL,
+ R_X86_64_TPOFF32, 32},
+ {"dtpoff", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL,
+ R_X86_64_DTPOFF32, 32},
{"got", ELF_SSYM_SYM_RELATIVE, R_X86_64_GOT32, 32}
};
size_t i;
for (i=0; i<NELEMS(elf_x86_amd64_ssyms); i++) {
if (reloc->wrt == ssyms[i] &&
- reloc->valsize == elf_x86_amd64_ssyms[i].size)
+ reloc->valsize == elf_x86_amd64_ssyms[i].size) {
+ /* Force TLS type; this is required by the linker. */
+ if (elf_x86_amd64_ssyms[i].sym_rel & ELF_SSYM_THREAD_LOCAL) {
+ elf_symtab_entry *esym;
+
+ esym = yasm_symrec_get_data(reloc->reloc.sym,
+ &elf_symrec_data);
+ if (esym)
+ esym->type = STT_TLS;
+ }
return (unsigned char) elf_x86_amd64_ssyms[i].reloc;
+ }
}
yasm_internal_error(N_("Unsupported WRT"));
} else if (reloc->rtype_rel) {
{"gotoff", 0, R_386_GOTOFF, 32},
/* special one for NASM */
{"gotpc", ELF_SSYM_CURPOS_ADJUST, R_386_GOTPC, 32},
- {"tlsgd", ELF_SSYM_SYM_RELATIVE, R_386_TLS_GD, 32},
- {"tlsldm", ELF_SSYM_SYM_RELATIVE, R_386_TLS_LDM, 32},
- {"gottpoff", ELF_SSYM_SYM_RELATIVE, R_386_TLS_IE_32, 32},
- {"tpoff", ELF_SSYM_SYM_RELATIVE, R_386_TLS_LE_32, 32},
- {"ntpoff", ELF_SSYM_SYM_RELATIVE, R_386_TLS_LE, 32},
- {"dtpoff", ELF_SSYM_SYM_RELATIVE, R_386_TLS_LDO_32, 32},
- {"gotntpoff", ELF_SSYM_SYM_RELATIVE, R_386_TLS_GOTIE, 32},
- {"indntpoff", ELF_SSYM_SYM_RELATIVE, R_386_TLS_IE, 32},
+ {"tlsgd", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL,
+ R_386_TLS_GD, 32},
+ {"tlsldm", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL,
+ R_386_TLS_LDM, 32},
+ {"gottpoff", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL,
+ R_386_TLS_IE_32, 32},
+ {"tpoff", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL,
+ R_386_TLS_LE_32, 32},
+ {"ntpoff", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL,
+ R_386_TLS_LE, 32},
+ {"dtpoff", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL,
+ R_386_TLS_LDO_32, 32},
+ {"gotntpoff", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL,
+ R_386_TLS_GOTIE, 32},
+ {"indntpoff", ELF_SSYM_SYM_RELATIVE|ELF_SSYM_THREAD_LOCAL,
+ R_386_TLS_IE, 32},
{"got", ELF_SSYM_SYM_RELATIVE, R_386_GOT32, 32}
};
size_t i;
for (i=0; i<NELEMS(elf_x86_x86_ssyms); i++) {
if (reloc->wrt == ssyms[i] &&
- reloc->valsize == elf_x86_x86_ssyms[i].size)
+ reloc->valsize == elf_x86_x86_ssyms[i].size) {
+ /* Force TLS type; this is required by the linker. */
+ if (elf_x86_x86_ssyms[i].sym_rel & ELF_SSYM_THREAD_LOCAL) {
+ elf_symtab_entry *esym;
+
+ esym = yasm_symrec_get_data(reloc->reloc.sym,
+ &elf_symrec_data);
+ if (esym)
+ esym->type = STT_TLS;
+ }
return (unsigned char) elf_x86_x86_ssyms[i].reloc;
+ }
}
yasm_internal_error(N_("Unsupported WRT"));
} else if (reloc->rtype_rel) {
if (value_intn == NULL)
value_intn = yasm_intnum_create_uint(entry->value);
+ /* If symbol is in a TLS section, force its type to TLS. */
+ if (entry->sym) {
+ yasm_bytecode *precbc;
+ yasm_section *sect;
+ elf_secthead *shead;
+ if (yasm_symrec_get_label(entry->sym, &precbc) &&
+ (sect = yasm_bc_get_section(precbc)) &&
+ (shead = yasm_section_get_data(sect, &elf_section_data)) &&
+ shead->flags & SHF_TLS) {
+ entry->type = STT_TLS;
+ }
+ }
if (!elf_march->write_symtab_entry || !elf_march->symtab_entry_size)
yasm_internal_error(N_("Unsupported machine for ELF output"));
STT_FUNC = 2, /* a function or executable code */
STT_SECTION = 3, /* a section: often for relocation, STB_LOCAL */
STT_FILE = 4, /* often source filename: STB_LOCAL, SHN_ABS */
+ STT_COMMON = 5, /* Uninitialized common block. */
+ STT_TLS = 6, /* TLS object. */
+ STT_NUM = 7,
STT_LOOS = 10, /* Environment specific use */
STT_HIOS = 12,
00
00
00
-10
+16
00
00
00
00
00
00
-10
+16
00
00
00