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
470470
471471 /* special flag, too */
472472 #define SECTION_ABS ((void *)1)
473−#define SECTION_COMMON ((void *)2)
474473
475474 typedef struct Section {
476475 unsigned long data_offset; /* current data offset */
@@ -1360,6 +1359,7 @@ typedef struct { · 883 unmodified lines
13601359 } Stab_Sym;
13611360
13621361 ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
1362+ST_DATA Section *common_section;
13631363 ST_DATA Section *cur_text_section; /* current section where function code is generated */
13641364 #ifdef CONFIG_TCC_ASM
13651365 ST_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
13811381
13821382 ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags);
13831383 ST_FUNC void section_realloc(Section *sec, unsigned long new_size);
1384+ST_FUNC size_t section_add(Section *sec, addr_t size, int align);
13841385 ST_FUNC void *section_ptr_add(Section *sec, addr_t size);
13851386 ST_FUNC void section_reserve(Section *sec, unsigned long size);
13861387 ST_FUNC Section *find_section(TCCState *s1, const char *name);
tccelf.c+21−13
@@ -27,6 +27,7 @@ · 26 unmodified lines
2727 /* global variables */
2828
2929 ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */
30+ST_DATA Section *common_section;
3031 ST_DATA Section *cur_text_section; /* current section where function code is generated */
3132 #ifdef CONFIG_TCC_ASM
3233 ST_DATA Section *last_text_section; /* to handle .previous asm directive */
@@ -55,6 +56,8 @@ ST_FUNC void tccelf_new(TCCState *s) · 22 unmodified lines
5556 text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
5657 data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
5758 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;
5861
5962 /* symbols are always generated for linking stage */
6063 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
208211 sec->data_allocated = size;
209212 }
210213
211−/* reserve at least 'size' bytes in section 'sec' from
212− sec->data_offset. */
213−ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
214+/* reserve at least 'size' bytes aligned per 'align' in section
215+ 'sec' from current offset, and return the aligned offset */
216+ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
214217 {
215218 size_t offset, offset1;
216219
217− offset = sec->data_offset;
220+ offset = (sec->data_offset + align - 1) & -align;
218221 offset1 = offset + size;
219− if (offset1 > sec->data_allocated)
222+ if (sec->sh_type != SHT_NOBITS && offset1 > sec->data_allocated)
220223 section_realloc(sec, offset1);
221224 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. */
232+ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
233+{
234+ size_t offset = section_add(sec, size, 1);
222235 return sec->data + offset;
223236 }
224237
@@ -702,18 +715,13 @@ static void sort_syms(TCCState *s1, Section *s) · 477 unmodified lines
702715 ST_FUNC void relocate_common_syms(void)
703716 {
704717 ElfW(Sym) *sym;
705− unsigned long offset, align;
706718
707719 for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
708720 if (sym->st_shndx == SHN_COMMON) {
709− /* align symbol */
710− align = sym->st_value;
711− offset = bss_section->data_offset;
712− offset = (offset + align - 1) & -align;
713− sym->st_value = offset;
721+ /* symbol alignment is in st_value for SHN_COMMONs */
722+ sym->st_value = section_add(bss_section, sym->st_size,
723+ sym->st_value);
714724 sym->st_shndx = bss_section->sh_num;
715− offset += sym->st_size;
716− bss_section->data_offset = offset;
717725 }
718726 }
719727 }
tccgen.c+19−65
@@ -76,6 +76,7 @@ static int is_compatible_types(CType *type1, CType *type2); · 75 unmodified lines
7676 static int parse_btype(CType *type, AttributeDef *ad);
7777 static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td);
7878 static void parse_expr_type(CType *type);
79+static void init_putv(CType *type, Section *sec, unsigned long c);
7980 static void decl_initializer(CType *type, Section *sec, unsigned long c, int first, int size_only);
8081 static void block(int *bsym, int *csym, int is_expr);
8182 static 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
302303 sh_num = SHN_UNDEF;
303304 else if (section == SECTION_ABS)
304305 sh_num = SHN_ABS;
305− else if (section == SECTION_COMMON)
306− sh_num = SHN_COMMON;
307306 else
308307 sh_num = section->sh_num;
309308
@@ -1065,7 +1064,7 @@ static void gbound(void) · 755 unmodified lines
10651064 register value (such as structures). */
10661065 ST_FUNC int gv(int rc)
10671066 {
1068− int r, bit_pos, bit_size, size, align, i;
1067+ int r, bit_pos, bit_size, size, align;
10691068 int rc2;
10701069
10711070 /* NOTE: get_reg can modify vstack[] */
@@ -1096,44 +1095,15 @@ ST_FUNC int gv(int rc) · 24 unmodified lines
10961095 } else {
10971096 if (is_float(vtop->type.t) &&
10981097 (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
1099− Sym *sym;
1100− int *ptr;
11011098 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 ? */
11071099 /* CPUs usually cannot use float constants, so we store them
11081100 generically in data segment */
11091101 size = type_size(&vtop->type, &align);
1110− offset = (data_section->data_offset + align - 1) & -align;
1111− data_section->data_offset = offset;
1112− /* XXX: not portable yet */
1113−#if defined(__i386__) || defined(__x86_64__)
1114− /* Zero pad x87 tenbyte long doubles */
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;
1102+ offset = section_add(data_section, size, align);
1103+ vpush_ref(&vtop->type, data_section, offset, size);
1104+ vswap();
1105+ init_putv(&vtop->type, data_section, offset);
1106+ vtop->r |= VT_LVAL;
11371107 }
11381108 #ifdef CONFIG_TCC_BCHECK
11391109 if (vtop->r & VT_MUSTBOUND)
@@ -4351,7 +4321,7 @@ ST_FUNC void unary(void) · 3211 unmodified lines
43514321 t = VT_LLONG;
43524322 goto push_tokc;
43534323 case TOK_CULLONG:
4354− t =VT_LLONG | VT_UNSIGNED;
4324+ t = VT_LLONG | VT_UNSIGNED;
43554325 goto push_tokc;
43564326 case TOK_CFLOAT:
43574327 t = VT_FLOAT;
@@ -6098,9 +6068,7 @@ static void init_putv(CType *type, Section *sec, unsigned long c) · 1740 unmodified lines
60986068 gen_assign_cast(&dtype);
60996069 bt = type->t & VT_BTYPE;
61006070 size = type_size(type, &align);
6101− if (c + size > sec->data_allocated) {
6102− section_realloc(sec, c + size);
6103− }
6071+ section_reserve(sec, c + size);
61046072 ptr = sec->data + c;
61056073 /* XXX: make code faster ? */
61066074 if (!(type->t & VT_BITFIELD)) {
@@ -6190,6 +6158,9 @@ static void init_putv(CType *type, Section *sec, unsigned long c) · 83 unmodified lines
61906158 case VT_SHORT:
61916159 *(short *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
61926160 break;
6161+ case VT_FLOAT:
6162+ *(float*)ptr = vtop->c.f;
6163+ break;
61936164 case VT_DOUBLE:
61946165 *(double *)ptr = vtop->c.d;
61956166 break;
@@ -6475,7 +6446,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c, · 279 unmodified lines
64756446 static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
64766447 int has_init, int v, int scope)
64776448 {
6478− int size, align, addr, data_offset;
6449+ int size, align, addr;
64796450 ParseState saved_parse_state = {0};
64806451 TokenString *init_str = NULL;
64816452 Section *sec;
@@ -6624,41 +6595,24 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 142 unmodified lines
66246595 }
66256596
66266597 if (sec) {
6627− data_offset = sec->data_offset;
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;
6598+ addr = section_add(sec, size, align);
66336599 #ifdef CONFIG_TCC_BCHECK
66346600 /* add padding if bound check */
66356601 if (tcc_state->do_bounds_check)
6636− data_offset++;
6602+ section_add(sec, 1, 1);
66376603 #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;
66466604 } else {
6647− addr = 0; /* avoid warning */
6605+ addr = align; /* SHN_COMMON is special, symbol value is align */
6606+ sec = common_section;
66486607 }
66496608
66506609 if (v) {
6651− if (scope != VT_CONST || !sym) {
6610+ if (!sym) {
66526611 sym = sym_push(v, type, r | VT_SYM, 0);
66536612 sym->asm_label = ad->asm_label;
66546613 }
66556614 /* update symbol definition */
6656− if (sec) {
6657− put_extern_sym(sym, sec, addr, size);
6658− } else {
6659− put_extern_sym(sym, SECTION_COMMON, align, size);
6660− }
6661−
6615+ put_extern_sym(sym, sec, addr, size);
66626616 } else {
66636617 /* push global reference */
66646618 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