From 1c4afd13501f07a673aed5f130166f2ee0f30927 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Tue, 29 Oct 2013 22:10:02 +0800 Subject: Add support for thread-local storage variables --- tccelf.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'tccelf.c') diff --git a/tccelf.c b/tccelf.c index 8af4bb6..4602ce8 100644 --- a/tccelf.c +++ b/tccelf.c @@ -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) -- cgit v1.3.1