Add support for thread-local storage variables
This commit is contained in:
parent
3b07a15fd1
commit
1c4afd1350
5 changed files with 54 additions and 14 deletions
4
elf.h
4
elf.h
|
@ -447,6 +447,7 @@ typedef struct
|
||||||
#define STT_SECTION 3 /* Symbol associated with a section */
|
#define STT_SECTION 3 /* Symbol associated with a section */
|
||||||
#define STT_FILE 4 /* Symbol's name is file name */
|
#define STT_FILE 4 /* Symbol's name is file name */
|
||||||
#define STT_NUM 5 /* Number of defined types. */
|
#define STT_NUM 5 /* Number of defined types. */
|
||||||
|
#define STT_TLS 6 /* Symbol is a thread-local data object */
|
||||||
#define STT_GNU_IFUNC 10 /* Symbol is a indirect code object */
|
#define STT_GNU_IFUNC 10 /* Symbol is a indirect code object */
|
||||||
#define STT_LOOS 11 /* Start of OS-specific */
|
#define STT_LOOS 11 /* Start of OS-specific */
|
||||||
#define STT_HIOS 12 /* End of OS-specific */
|
#define STT_HIOS 12 /* End of OS-specific */
|
||||||
|
@ -555,7 +556,8 @@ typedef struct
|
||||||
#define PT_NOTE 4 /* Auxiliary information */
|
#define PT_NOTE 4 /* Auxiliary information */
|
||||||
#define PT_SHLIB 5 /* Reserved */
|
#define PT_SHLIB 5 /* Reserved */
|
||||||
#define PT_PHDR 6 /* Entry for header table itself */
|
#define PT_PHDR 6 /* Entry for header table itself */
|
||||||
#define PT_NUM 7 /* Number of defined types. */
|
#define PT_TLS 7 /* Thread-local program segment */
|
||||||
|
#define PT_NUM 8 /* Number of defined types. */
|
||||||
#define PT_LOOS 0x60000000 /* Start of OS-specific */
|
#define PT_LOOS 0x60000000 /* Start of OS-specific */
|
||||||
#define PT_HIOS 0x6fffffff /* End of OS-specific */
|
#define PT_HIOS 0x6fffffff /* End of OS-specific */
|
||||||
#define PT_LOPROC 0x70000000 /* Start of processor-specific */
|
#define PT_LOPROC 0x70000000 /* Start of processor-specific */
|
||||||
|
|
3
libtcc.c
3
libtcc.c
|
@ -444,6 +444,9 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section,
|
||||||
} else if ((sym->type.t & VT_BTYPE) == VT_VOID) {
|
} else if ((sym->type.t & VT_BTYPE) == VT_VOID) {
|
||||||
sym_type = STT_NOTYPE;
|
sym_type = STT_NOTYPE;
|
||||||
} else {
|
} else {
|
||||||
|
if (section && section->sh_flags & SHF_TLS)
|
||||||
|
sym_type = STT_TLS;
|
||||||
|
else
|
||||||
sym_type = STT_OBJECT;
|
sym_type = STT_OBJECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
27
tccelf.c
27
tccelf.c
|
@ -1543,6 +1543,7 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
||||||
int fd, mode, ret;
|
int fd, mode, ret;
|
||||||
int *section_order;
|
int *section_order;
|
||||||
int shnum, i, phnum, file_offset, offset, size, j, sh_order_index, k;
|
int shnum, i, phnum, file_offset, offset, size, j, sh_order_index, k;
|
||||||
|
int have_tls_section = 0;
|
||||||
long long tmp;
|
long long tmp;
|
||||||
addr_t addr;
|
addr_t addr;
|
||||||
Section *strsec, *s;
|
Section *strsec, *s;
|
||||||
|
@ -1861,6 +1862,11 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
||||||
/* we output all sections if debug or object file */
|
/* we output all sections if debug or object file */
|
||||||
s->sh_size = s->data_offset;
|
s->sh_size = s->data_offset;
|
||||||
}
|
}
|
||||||
|
/* if tls section we'll need to add one segment */
|
||||||
|
if (s->sh_flags & SHF_TLS) {
|
||||||
|
have_tls_section = 1;
|
||||||
|
phnum++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate program segment headers */
|
/* allocate program segment headers */
|
||||||
|
@ -1904,12 +1910,16 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
||||||
if (interp)
|
if (interp)
|
||||||
ph += 1 + HAVE_PHDR;
|
ph += 1 + HAVE_PHDR;
|
||||||
|
|
||||||
for(j = 0; j < 2; j++) {
|
for(j = 0; j < 2 + have_tls_section; j++) {
|
||||||
|
if (j != 2)
|
||||||
ph->p_type = PT_LOAD;
|
ph->p_type = PT_LOAD;
|
||||||
if (j == 0)
|
|
||||||
ph->p_flags = PF_R | PF_X;
|
|
||||||
else
|
else
|
||||||
ph->p_flags = PF_R | PF_W;
|
ph->p_type = PT_TLS;
|
||||||
|
ph->p_flags = PF_R;
|
||||||
|
if (j == 0)
|
||||||
|
ph->p_flags |= PF_X;
|
||||||
|
else if (j == 1)
|
||||||
|
ph->p_flags |= PF_W;
|
||||||
ph->p_align = s1->section_align;
|
ph->p_align = s1->section_align;
|
||||||
|
|
||||||
/* we do the following ordering: interp, symbol tables,
|
/* we do the following ordering: interp, symbol tables,
|
||||||
|
@ -1920,13 +1930,16 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
||||||
s = s1->sections[i];
|
s = s1->sections[i];
|
||||||
/* compute if section should be included */
|
/* compute if section should be included */
|
||||||
if (j == 0) {
|
if (j == 0) {
|
||||||
if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
|
if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
|
||||||
SHF_ALLOC)
|
SHF_ALLOC)
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else if (j == 1) {
|
||||||
if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) !=
|
if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) !=
|
||||||
(SHF_ALLOC | SHF_WRITE))
|
(SHF_ALLOC | SHF_WRITE))
|
||||||
continue;
|
continue;
|
||||||
|
} else {
|
||||||
|
if ((s->sh_flags & SHF_TLS) != SHF_TLS)
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
if (s == interp) {
|
if (s == interp) {
|
||||||
if (k != 0)
|
if (k != 0)
|
||||||
|
|
25
tccgen.c
25
tccgen.c
|
@ -31,6 +31,7 @@
|
||||||
ST_DATA int rsym, anon_sym, ind, loc;
|
ST_DATA int rsym, anon_sym, ind, loc;
|
||||||
|
|
||||||
ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
|
ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
|
||||||
|
ST_DATA Section *tdata_section, *tbss_section; /* thread-local storage sections */
|
||||||
ST_DATA Section *cur_text_section; /* current section where function code is generated */
|
ST_DATA Section *cur_text_section; /* current section where function code is generated */
|
||||||
#ifdef CONFIG_TCC_ASM
|
#ifdef CONFIG_TCC_ASM
|
||||||
ST_DATA Section *last_text_section; /* to handle .previous asm directive */
|
ST_DATA Section *last_text_section; /* to handle .previous asm directive */
|
||||||
|
@ -3092,6 +3093,10 @@ static int parse_btype(CType *type, AttributeDef *ad)
|
||||||
t |= VT_INLINE;
|
t |= VT_INLINE;
|
||||||
next();
|
next();
|
||||||
break;
|
break;
|
||||||
|
case TOK_THREAD:
|
||||||
|
t |= VT_TLS;
|
||||||
|
next();
|
||||||
|
break;
|
||||||
|
|
||||||
/* GNUC attribute */
|
/* GNUC attribute */
|
||||||
case TOK_ATTRIBUTE1:
|
case TOK_ATTRIBUTE1:
|
||||||
|
@ -5495,11 +5500,27 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
|
||||||
/* allocate symbol in corresponding section */
|
/* allocate symbol in corresponding section */
|
||||||
sec = ad->section;
|
sec = ad->section;
|
||||||
if (!sec) {
|
if (!sec) {
|
||||||
if (has_init)
|
if (has_init) {
|
||||||
|
if (type->t & VT_TLS) {
|
||||||
|
if (!tdata_section)
|
||||||
|
tdata_section = new_section(tcc_state, ".tdata",
|
||||||
|
SHT_PROGBITS,
|
||||||
|
SHF_ALLOC | SHF_WRITE | SHF_TLS);
|
||||||
|
sec = tdata_section;
|
||||||
|
} else
|
||||||
sec = data_section;
|
sec = data_section;
|
||||||
else if (tcc_state->nocommon)
|
}
|
||||||
|
else if (tcc_state->nocommon) {
|
||||||
|
if (type->t & VT_TLS) {
|
||||||
|
if (!tbss_section)
|
||||||
|
tbss_section = new_section(tcc_state, ".tbss",
|
||||||
|
SHT_NOBITS,
|
||||||
|
SHF_ALLOC | SHF_WRITE | SHF_TLS);
|
||||||
|
sec = tbss_section;
|
||||||
|
} else
|
||||||
sec = bss_section;
|
sec = bss_section;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (sec) {
|
if (sec) {
|
||||||
data_offset = sec->data_offset;
|
data_offset = sec->data_offset;
|
||||||
data_offset = (data_offset + align - 1) & -align;
|
data_offset = (data_offset + align - 1) & -align;
|
||||||
|
|
1
tcctok.h
1
tcctok.h
|
@ -10,6 +10,7 @@
|
||||||
DEF(TOK_FOR, "for")
|
DEF(TOK_FOR, "for")
|
||||||
DEF(TOK_EXTERN, "extern")
|
DEF(TOK_EXTERN, "extern")
|
||||||
DEF(TOK_STATIC, "static")
|
DEF(TOK_STATIC, "static")
|
||||||
|
DEF(TOK_THREAD, "__thread")
|
||||||
DEF(TOK_UNSIGNED, "unsigned")
|
DEF(TOK_UNSIGNED, "unsigned")
|
||||||
DEF(TOK_GOTO, "goto")
|
DEF(TOK_GOTO, "goto")
|
||||||
DEF(TOK_DO, "do")
|
DEF(TOK_DO, "do")
|
||||||
|
|
Loading…
Reference in a new issue