diff options
| author | Thomas Preud'homme <robotux@celest.fr> | 2013-10-29 22:10:02 +0800 |
|---|---|---|
| committer | Thomas Preud'homme <robotux@celest.fr> | 2013-10-29 22:10:02 +0800 |
| commit | 1c4afd13501f07a673aed5f130166f2ee0f30927 (patch) | |
| tree | 01d8f2a1455cd0b0cf8036a129418361207a6e6c /tccelf.c | |
| parent | 3b07a15fd12d5452bf539cd855edde8139db1686 (diff) | |
| download | tinycc-1c4afd13501f07a673aed5f130166f2ee0f30927.tar.gz tinycc-1c4afd13501f07a673aed5f130166f2ee0f30927.tar.bz2 | |
Add support for thread-local storage variables
Diffstat (limited to 'tccelf.c')
| -rw-r--r-- | tccelf.c | 29 |
1 files changed, 21 insertions, 8 deletions
@@ -1543,6 +1543,7 @@ static int elf_output_file(TCCState *s1, const char *filename) int fd, mode, ret; int *section_order; int shnum, i, phnum, file_offset, offset, size, j, sh_order_index, k; + int have_tls_section = 0; long long tmp; addr_t addr; 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 */ 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 */ @@ -1904,12 +1910,16 @@ static int elf_output_file(TCCState *s1, const char *filename) if (interp) ph += 1 + HAVE_PHDR; - for(j = 0; j < 2; j++) { - ph->p_type = PT_LOAD; - if (j == 0) - ph->p_flags = PF_R | PF_X; + for(j = 0; j < 2 + have_tls_section; j++) { + if (j != 2) + ph->p_type = PT_LOAD; 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; /* 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]; /* compute if section should be included */ if (j == 0) { - if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != + if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) != SHF_ALLOC) continue; - } else { - if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != + } else if (j == 1) { + if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) != (SHF_ALLOC | SHF_WRITE)) continue; + } else { + if ((s->sh_flags & SHF_TLS) != SHF_TLS) + continue; } if (s == interp) { if (k != 0) |
