History

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).

Michael Matz committed 9 years ago

Commit c7dbc901 parent 25522e43 files · +42 −79Browse files

Unified · Split

3 files
  1. tcc.h +2 −1
  2. tccelf.c +21 −13
  3. tccgen.c +19 −65
tcc.h+2−1
@@ -470,7 +470,6 @@ typedef struct Sym { · 469 unmodified lines
470 470
471/* special flag, too */471/* special flag, too */
472#define SECTION_ABS ((void *)1)472#define SECTION_ABS ((void *)1)
473#define SECTION_COMMON ((void *)2)
474 473
475typedef struct Section {474typedef struct Section {
476 unsigned long data_offset; /* current data offset */475 unsigned long data_offset; /* current data offset */
@@ -1360,6 +1359,7 @@ typedef struct { · 883 unmodified lines
1360} Stab_Sym;1359} Stab_Sym;
1361 1360
1362ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */1361ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
1362ST_DATA Section *common_section;
1363ST_DATA Section *cur_text_section; /* current section where function code is generated */1363ST_DATA Section *cur_text_section; /* current section where function code is generated */
1364#ifdef CONFIG_TCC_ASM1364#ifdef CONFIG_TCC_ASM
1365ST_DATA Section *last_text_section; /* to handle .previous asm directive */1365ST_DATA Section *last_text_section; /* to handle .previous asm directive */
@@ -1381,6 +1381,7 @@ ST_FUNC void tccelf_stab_new(TCCState *s); · 15 unmodified lines
1381 1381
1382ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags);1382ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags);
1383ST_FUNC void section_realloc(Section *sec, unsigned long new_size);1383ST_FUNC void section_realloc(Section *sec, unsigned long new_size);
1384ST_FUNC size_t section_add(Section *sec, addr_t size, int align);
1384ST_FUNC void *section_ptr_add(Section *sec, addr_t size);1385ST_FUNC void *section_ptr_add(Section *sec, addr_t size);
1385ST_FUNC void section_reserve(Section *sec, unsigned long size);1386ST_FUNC void section_reserve(Section *sec, unsigned long size);
1386ST_FUNC Section *find_section(TCCState *s1, const char *name);1387ST_FUNC Section *find_section(TCCState *s1, const char *name);
tccelf.c+21−13
@@ -27,6 +27,7 @@ · 26 unmodified lines
27/* global variables */27/* global variables */
28 28
29ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */29ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
30ST_DATA Section *common_section;
30ST_DATA Section *cur_text_section; /* current section where function code is generated */31ST_DATA Section *cur_text_section; /* current section where function code is generated */
31#ifdef CONFIG_TCC_ASM32#ifdef CONFIG_TCC_ASM
32ST_DATA Section *last_text_section; /* to handle .previous asm directive */33ST_DATA Section *last_text_section; /* to handle .previous asm directive */
@@ -55,6 +56,8 @@ ST_FUNC void tccelf_new(TCCState *s) · 22 unmodified lines
55 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);56 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
56 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);57 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
57 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);58 bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
59 common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
60 common_section->sh_num = SHN_COMMON;
58 61
59 /* symbols are always generated for linking stage */62 /* symbols are always generated for linking stage */
60 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,63 symtab_section = new_symtab(s, ".symtab", SHT_SYMTAB, 0,
@@ -208,17 +211,27 @@ ST_FUNC void section_realloc(Section *sec, unsigned long new_size) · 147 unmodified lines
208 sec->data_allocated = size;211 sec->data_allocated = size;
209}212}
210 213
211/* reserve at least 'size' bytes in section 'sec' from214/* reserve at least 'size' bytes aligned per 'align' in section
212 sec->data_offset. */215 'sec' from current offset, and return the aligned offset */
213ST_FUNC void *section_ptr_add(Section *sec, addr_t size)216ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
214{217{
215 size_t offset, offset1;218 size_t offset, offset1;
216 219
217 offset = sec->data_offset;220 offset = (sec->data_offset + align - 1) & -align;
218 offset1 = offset + size;221 offset1 = offset + size;
219 if (offset1 > sec->data_allocated)222 if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated)
220 section_realloc(sec, offset1);223 section_realloc(sec, offset1);
221 sec->data_offset = offset1;224 sec->data_offset = offset1;
225 if (align > sec->sh_addralign)
226 sec->sh_addralign = align;
227 return offset;
228}
229
230/* reserve at least 'size' bytes in section 'sec' from
231 sec->data_offset. */
232ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
233{
234 size_t offset = section_add(sec, size, 1);
222 return sec->data + offset;235 return sec->data + offset;
223}236}
224 237
@@ -702,18 +715,13 @@ static void sort_syms(TCCState *s1, Section *s) · 477 unmodified lines
702ST_FUNC void relocate_common_syms(void)715ST_FUNC void relocate_common_syms(void)
703{716{
704 ElfW(Sym) *sym;717 ElfW(Sym) *sym;
705 unsigned long offset, align;
706 718
707 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {719 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
708 if (sym->st_shndx == SHN_COMMON) {720 if (sym->st_shndx == SHN_COMMON) {
709 /* align symbol */721 /* symbol alignment is in st_value for SHN_COMMONs */
710 align = sym->st_value;722 sym->st_value = section_add(bss_section, sym->st_size,
711 offset = bss_section->data_offset;723 sym->st_value);
712 offset = (offset + align - 1) & -align;
713 sym->st_value = offset;
714 sym->st_shndx = bss_section->sh_num;724 sym->st_shndx = bss_section->sh_num;
715 offset += sym->st_size;
716 bss_section->data_offset = offset;
717 }725 }
718 }726 }
719}727}
tccgen.c+19−65
@@ -76,6 +76,7 @@ static int is_compatible_types(CType *type1, CType *type2); · 75 unmodified lines
76static int parse_btype(CType *type, AttributeDef *ad);76static int parse_btype(CType *type, AttributeDef *ad);
77static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td);77static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td);
78static void parse_expr_type(CType *type);78static void parse_expr_type(CType *type);
79static void init_putv(CType *type, Section *sec, unsigned long c);
79static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);80static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
80static void block(int *bsym, int *csym, int is_expr);81static void block(int *bsym, int *csym, int is_expr);
81static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope);82static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, int has_init, int v, int scope);
@@ -302,8 +303,6 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section, · 220 unmodified lines
302 sh_num = SHN_UNDEF;303 sh_num = SHN_UNDEF;
303 else if (section == SECTION_ABS)304 else if (section == SECTION_ABS)
304 sh_num = SHN_ABS;305 sh_num = SHN_ABS;
305 else if (section == SECTION_COMMON)
306 sh_num = SHN_COMMON;
307 else306 else
308 sh_num = section->sh_num;307 sh_num = section->sh_num;
309 308
@@ -1065,7 +1064,7 @@ static void gbound(void) · 755 unmodified lines
1065 register value (such as structures). */1064 register value (such as structures). */
1066ST_FUNC int gv(int rc)1065ST_FUNC int gv(int rc)
1067{1066{
1068 int r, bit_pos, bit_size, size, align, i;1067 int r, bit_pos, bit_size, size, align;
1069 int rc2;1068 int rc2;
1070 1069
1071 /* NOTE: get_reg can modify vstack[] */1070 /* NOTE: get_reg can modify vstack[] */
@@ -1096,44 +1095,15 @@ ST_FUNC int gv(int rc) · 24 unmodified lines
1096 } else {1095 } else {
1097 if (is_float(vtop->type.t) && 1096 if (is_float(vtop->type.t) &&
1098 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {1097 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
1099 Sym *sym;
1100 int *ptr;
1101 unsigned long offset;1098 unsigned long offset;
1102#if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
1103 CValue check;
1104#endif
1105
1106 /* XXX: unify with initializers handling ? */
1107 /* CPUs usually cannot use float constants, so we store them1099 /* CPUs usually cannot use float constants, so we store them
1108 generically in data segment */1100 generically in data segment */
1109 size = type_size(&vtop->type, &align);1101 size = type_size(&vtop->type, &align);
1110 offset = (data_section->data_offset + align - 1) & -align;1102 offset = section_add(data_section, size, align);
1111 data_section->data_offset = offset;1103 vpush_ref(&vtop->type, data_section, offset, size);
1112 /* XXX: not portable yet */1104 vswap();
1113#if defined(__i386__) || defined(__x86_64__)1105 init_putv(&vtop->type, data_section, offset);
1114 /* Zero pad x87 tenbyte long doubles */1106 vtop->r |= VT_LVAL;
1115 if (size == LDOUBLE_SIZE) {
1116 vtop->c.tab[2] &= 0xffff;
1117#if LDOUBLE_SIZE == 16
1118 vtop->c.tab[3] = 0;
1119#endif
1120 }
1121#endif
1122 ptr = section_ptr_add(data_section, size);
1123 size = size >> 2;
1124#if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
1125 check.d = 1;
1126 if(check.tab[0])
1127 for(i=0;i<size;i++)
1128 ptr[i] = vtop->c.tab[size-1-i];
1129 else
1130#endif
1131 for(i=0;i<size;i++)
1132 ptr[i] = vtop->c.tab[i];
1133 sym = get_sym_ref(&vtop->type, data_section, offset, size << 2);
1134 vtop->r |= VT_LVAL | VT_SYM;
1135 vtop->sym = sym;
1136 vtop->c.i = 0;
1137 }1107 }
1138#ifdef CONFIG_TCC_BCHECK1108#ifdef CONFIG_TCC_BCHECK
1139 if (vtop->r & VT_MUSTBOUND) 1109 if (vtop->r & VT_MUSTBOUND)
@@ -4351,7 +4321,7 @@ ST_FUNC void unary(void) · 3211 unmodified lines
4351 t = VT_LLONG;4321 t = VT_LLONG;
4352 goto push_tokc;4322 goto push_tokc;
4353 case TOK_CULLONG:4323 case TOK_CULLONG:
4354 t =VT_LLONG | VT_UNSIGNED;4324 t = VT_LLONG | VT_UNSIGNED;
4355 goto push_tokc;4325 goto push_tokc;
4356 case TOK_CFLOAT:4326 case TOK_CFLOAT:
4357 t = VT_FLOAT;4327 t = VT_FLOAT;
@@ -6098,9 +6068,7 @@ static void init_putv(CType *type, Section *sec, unsigned long c) · 1740 unmodified lines
6098 gen_assign_cast(&dtype);6068 gen_assign_cast(&dtype);
6099 bt = type->t & VT_BTYPE;6069 bt = type->t & VT_BTYPE;
6100 size = type_size(type, &align);6070 size = type_size(type, &align);
6101 if (c + size > sec->data_allocated) {6071 section_reserve(sec, c + size);
6102 section_realloc(sec, c + size);
6103 }
6104 ptr = sec->data + c;6072 ptr = sec->data + c;
6105 /* XXX: make code faster ? */6073 /* XXX: make code faster ? */
6106 if (!(type->t & VT_BITFIELD)) {6074 if (!(type->t & VT_BITFIELD)) {
@@ -6190,6 +6158,9 @@ static void init_putv(CType *type, Section *sec, unsigned long c) · 83 unmodified lines
6190 case VT_SHORT:6158 case VT_SHORT:
6191 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;6159 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
6192 break;6160 break;
6161 case VT_FLOAT:
6162 *(float*)ptr = vtop->c.f;
6163 break;
6193 case VT_DOUBLE:6164 case VT_DOUBLE:
6194 *(double *)ptr = vtop->c.d;6165 *(double *)ptr = vtop->c.d;
6195 break;6166 break;
@@ -6475,7 +6446,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 279 unmodified lines
6475static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, 6446static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
6476 int has_init, int v, int scope)6447 int has_init, int v, int scope)
6477{6448{
6478 int size, align, addr, data_offset;6449 int size, align, addr;
6479 ParseState saved_parse_state = {0};6450 ParseState saved_parse_state = {0};
6480 TokenString *init_str = NULL;6451 TokenString *init_str = NULL;
6481 Section *sec;6452 Section *sec;
@@ -6624,41 +6595,24 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 142 unmodified lines
6624 }6595 }
6625 6596
6626 if (sec) {6597 if (sec) {
6627 data_offset = sec->data_offset;6598 addr = section_add(sec, size, align);
6628 data_offset = (data_offset + align - 1) & -align;
6629 addr = data_offset;
6630 /* very important to increment global pointer at this time
6631 because initializers themselves can create new initializers */
6632 data_offset += size;
6633#ifdef CONFIG_TCC_BCHECK6599#ifdef CONFIG_TCC_BCHECK
6634 /* add padding if bound check */6600 /* add padding if bound check */
6635 if (tcc_state->do_bounds_check)6601 if (tcc_state->do_bounds_check)
6636 data_offset++;6602 section_add(sec, 1, 1);
6637#endif6603#endif
6638 sec->data_offset = data_offset;
6639 /* allocate section space to put the data */
6640 if (sec->sh_type != SHT_NOBITS &&
6641 data_offset > sec->data_allocated)
6642 section_realloc(sec, data_offset);
6643 /* align section if needed */
6644 if (align > sec->sh_addralign)
6645 sec->sh_addralign = align;
6646 } else {6604 } else {
6647 addr = 0; /* avoid warning */6605 addr = align; /* SHN_COMMON is special, symbol value is align */
6606 sec = common_section;
6648 }6607 }
6649 6608
6650 if (v) {6609 if (v) {
6651 if (scope != VT_CONST || !sym) {6610 if (!sym) {
6652 sym = sym_push(v, type, r | VT_SYM, 0);6611 sym = sym_push(v, type, r | VT_SYM, 0);
6653 sym->asm_label = ad->asm_label;6612 sym->asm_label = ad->asm_label;
6654 }6613 }
6655 /* update symbol definition */6614 /* update symbol definition */
6656 if (sec) {6615 put_extern_sym(sym, sec, addr, size);
6657 put_extern_sym(sym, sec, addr, size);
6658 } else {
6659 put_extern_sym(sym, SECTION_COMMON, align, size);
6660 }
6661
6662 } else {6616 } else {
6663 /* push global reference */6617 /* push global reference */
6664 sym = get_sym_ref(type, sec, addr, size);6618 sym = get_sym_ref(type, sec, addr, size);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t