aboutsummaryrefslogtreecommitdiff
path: root/tccgen.c
diff options
context:
space:
mode:
authorThomas Preud'homme <robotux@celest.fr>2013-10-29 22:10:02 +0800
committerThomas Preud'homme <robotux@celest.fr>2013-10-29 22:10:02 +0800
commit1c4afd13501f07a673aed5f130166f2ee0f30927 (patch)
tree01d8f2a1455cd0b0cf8036a129418361207a6e6c /tccgen.c
parent3b07a15fd12d5452bf539cd855edde8139db1686 (diff)
downloadtinycc-1c4afd13501f07a673aed5f130166f2ee0f30927.tar.gz
tinycc-1c4afd13501f07a673aed5f130166f2ee0f30927.tar.bz2
Add support for thread-local storage variables
Diffstat (limited to 'tccgen.c')
-rw-r--r--tccgen.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/tccgen.c b/tccgen.c
index bab4f7c..bfe461f 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -31,6 +31,7 @@
ST_DATA int rsym, anon_sym, ind, loc;
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 */
#ifdef CONFIG_TCC_ASM
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;
next();
break;
+ case TOK_THREAD:
+ t |= VT_TLS;
+ next();
+ break;
/* GNUC attribute */
case TOK_ATTRIBUTE1:
@@ -5495,10 +5500,26 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
/* allocate symbol in corresponding section */
sec = ad->section;
if (!sec) {
- if (has_init)
- sec = data_section;
- else if (tcc_state->nocommon)
- sec = bss_section;
+ 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;
+ }
+ 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;
+ }
}
if (sec) {
data_offset = sec->data_offset;