From c7dbc900c8089ddff753ca2d618fb313b357d927 Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Sun, 12 Mar 2017 05:25:09 +0100 Subject: Cleanups (float consts, sections, symbols) introduce common_section (SHN_COMMON), factorize some handling in decl_initializer_alloc, add section_add and use it to factorize some code that allocates stuff in sections (at the same time also fixing harmless bugs re section alignment), use init_putv to emit float consts into .data from gv() (fixing an XXX). --- tccelf.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) (limited to 'tccelf.c') diff --git a/tccelf.c b/tccelf.c index 57bf0f1..76f3da6 100644 --- a/tccelf.c +++ b/tccelf.c @@ -27,6 +27,7 @@ /* global variables */ ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */ +ST_DATA Section *common_section; 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 */ @@ -55,6 +56,8 @@ ST_FUNC void tccelf_new(TCCState *s) text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR); data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE); + common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE); + common_section->sh_num = SHN_COMMON; /* symbols are always generated for linking stage */ symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0, @@ -208,17 +211,27 @@ ST_FUNC void section_realloc(Section *sec, unsigned long new_size) sec->data_allocated = size; } -/* reserve at least 'size' bytes in section 'sec' from - sec->data_offset. */ -ST_FUNC void *section_ptr_add(Section *sec, addr_t size) +/* reserve at least 'size' bytes aligned per 'align' in section + 'sec' from current offset, and return the aligned offset */ +ST_FUNC size_t section_add(Section *sec, addr_t size, int align) { size_t offset, offset1; - offset = sec->data_offset; + offset = (sec->data_offset + align - 1) & -align; offset1 = offset + size; - if (offset1 > sec->data_allocated) + if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated) section_realloc(sec, offset1); sec->data_offset = offset1; + if (align > sec->sh_addralign) + sec->sh_addralign = align; + return offset; +} + +/* reserve at least 'size' bytes in section 'sec' from + sec->data_offset. */ +ST_FUNC void *section_ptr_add(Section *sec, addr_t size) +{ + size_t offset = section_add(sec, size, 1); return sec->data + offset; } @@ -702,18 +715,13 @@ static void sort_syms(TCCState *s1, Section *s) ST_FUNC void relocate_common_syms(void) { ElfW(Sym) *sym; - unsigned long offset, align; for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { if (sym->st_shndx == SHN_COMMON) { - /* align symbol */ - align = sym->st_value; - offset = bss_section->data_offset; - offset = (offset + align - 1) & -align; - sym->st_value = offset; + /* symbol alignment is in st_value for SHN_COMMONs */ + sym->st_value = section_add(bss_section, sym->st_size, + sym->st_value); sym->st_shndx = bss_section->sh_num; - offset += sym->st_size; - bss_section->data_offset = offset; } } } -- cgit v1.3.1