mirror of
https://github.com/mirror/tinycc.git
synced 2025-02-28 08:10:25 +08:00
Init range wth symbols
The init range with symbols did only init the first value. The relocation for all other symbols was missing. Also see testcase. tccgen.c: - New function get_init_string - Use macro processing in decl_designator for each init string - Use get_init_string in decl_initializer_alloc tccelf.c: - Fix insertion sort in squeeze_multi_relocs tests/tests2/90_struct-init.c: - Add test case test_init_ranges
This commit is contained in:
parent
afc0917f88
commit
0da93838c1
8
tccelf.c
8
tccelf.c
@ -774,13 +774,13 @@ ST_FUNC void squeeze_multi_relocs(Section *s, size_t oldrelocoffset)
|
||||
a simple insertion sort. */
|
||||
for (a = oldrelocoffset + sizeof(*r); a < sr->data_offset; a += sizeof(*r)) {
|
||||
ssize_t i = a - sizeof(*r);
|
||||
addr = ((ElfW_Rel*)(sr->data + a))->r_offset;
|
||||
ElfW_Rel tmp = *(ElfW_Rel*)(sr->data + a);
|
||||
addr = tmp.r_offset;
|
||||
for (; i >= (ssize_t)oldrelocoffset &&
|
||||
((ElfW_Rel*)(sr->data + i))->r_offset > addr; i -= sizeof(*r)) {
|
||||
ElfW_Rel tmp = *(ElfW_Rel*)(sr->data + a);
|
||||
*(ElfW_Rel*)(sr->data + a) = *(ElfW_Rel*)(sr->data + i);
|
||||
*(ElfW_Rel*)(sr->data + i) = tmp;
|
||||
*(ElfW_Rel*)(sr->data + i + sizeof(*r)) = *(ElfW_Rel*)(sr->data + i);
|
||||
}
|
||||
*(ElfW_Rel*)(sr->data + i + sizeof(*r)) = tmp;
|
||||
}
|
||||
|
||||
r = (ElfW_Rel*)(sr->data + oldrelocoffset);
|
||||
|
69
tccgen.c
69
tccgen.c
@ -7296,6 +7296,23 @@ static void skip_or_save_block(TokenString **str)
|
||||
}
|
||||
}
|
||||
|
||||
static void get_init_string(TokenString **str, int has_init)
|
||||
{
|
||||
if (has_init == 2) {
|
||||
*str = tok_str_alloc();
|
||||
/* only get strings */
|
||||
while (tok == TOK_STR || tok == TOK_LSTR) {
|
||||
tok_str_add_tok(*str);
|
||||
next();
|
||||
}
|
||||
tok_str_add(*str, -1);
|
||||
tok_str_add(*str, 0);
|
||||
}
|
||||
else
|
||||
skip_or_save_block(str);
|
||||
unget_tok(0);
|
||||
}
|
||||
|
||||
#define EXPR_CONST 1
|
||||
#define EXPR_ANY 2
|
||||
|
||||
@ -7361,6 +7378,7 @@ static int decl_designator(CType *type, Section *sec, unsigned long c,
|
||||
Sym *s, *f;
|
||||
int index, index_last, align, l, nb_elems, elem_size;
|
||||
unsigned long corig = c;
|
||||
TokenString *init_str = NULL;
|
||||
|
||||
elem_size = 0;
|
||||
nb_elems = 1;
|
||||
@ -7454,34 +7472,26 @@ static int decl_designator(CType *type, Section *sec, unsigned long c,
|
||||
init_putz(sec, corig + al, zlen);
|
||||
}
|
||||
|
||||
if (!(flags & DIF_SIZE_ONLY) && nb_elems > 1) {
|
||||
get_init_string(&init_str, tok == TOK_STR || tok == TOK_LSTR ? 2 : 0);
|
||||
begin_macro(init_str, 1);
|
||||
next();
|
||||
}
|
||||
|
||||
decl_initializer(type, sec, c, flags & ~DIF_FIRST);
|
||||
|
||||
/* XXX: make it more general */
|
||||
if (!(flags & DIF_SIZE_ONLY) && nb_elems > 1) {
|
||||
unsigned long c_end;
|
||||
uint8_t *src, *dst;
|
||||
int i;
|
||||
|
||||
if (!sec) {
|
||||
vset(type, VT_LOCAL|VT_LVAL, c);
|
||||
for (i = 1; i < nb_elems; i++) {
|
||||
vset(type, VT_LOCAL|VT_LVAL, c + elem_size * i);
|
||||
vswap();
|
||||
vstore();
|
||||
}
|
||||
vpop();
|
||||
} else if (!NODATA_WANTED) {
|
||||
c_end = c + nb_elems * elem_size;
|
||||
if (c_end > sec->data_allocated)
|
||||
section_realloc(sec, c_end);
|
||||
src = sec->data + c;
|
||||
dst = src;
|
||||
for(i = 1; i < nb_elems; i++) {
|
||||
dst += elem_size;
|
||||
memcpy(dst, src, elem_size);
|
||||
}
|
||||
}
|
||||
for(i = 1; i < nb_elems; i++) {
|
||||
macro_ptr = init_str->str;
|
||||
next();
|
||||
decl_initializer(type, sec, c + i * elem_size, flags & ~DIF_FIRST);
|
||||
}
|
||||
end_macro();
|
||||
next();
|
||||
}
|
||||
|
||||
c += nb_elems * type_size(type, &align);
|
||||
if (c - corig > al)
|
||||
al = c - corig;
|
||||
@ -7919,20 +7929,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
|
||||
if (size < 0 || (flexible_array && has_init)) {
|
||||
if (!has_init)
|
||||
tcc_error("unknown type size");
|
||||
/* get all init string */
|
||||
if (has_init == 2) {
|
||||
init_str = tok_str_alloc();
|
||||
/* only get strings */
|
||||
while (tok == TOK_STR || tok == TOK_LSTR) {
|
||||
tok_str_add_tok(init_str);
|
||||
next();
|
||||
}
|
||||
tok_str_add(init_str, -1);
|
||||
tok_str_add(init_str, 0);
|
||||
} else {
|
||||
skip_or_save_block(&init_str);
|
||||
}
|
||||
unget_tok(0);
|
||||
get_init_string(&init_str, has_init);
|
||||
|
||||
/* compute size */
|
||||
begin_macro(init_str, 1);
|
||||
|
@ -235,6 +235,33 @@ void test_multi_relocs(void)
|
||||
for (i = 0; i < sizeof(table)/sizeof(table[0]); i++)
|
||||
table[i]();
|
||||
}
|
||||
|
||||
void test_init_ranges(void) {
|
||||
int i,c=0;
|
||||
static void *gostring[] = {
|
||||
[0 ... 31] = &&l_bad, [127] = &&l_bad,
|
||||
[32 ... 126] = &&l_loop,
|
||||
['\\'] = &&l_esc, ['"'] = &&l_qdown,
|
||||
[128 ... 191] = &&l_bad,
|
||||
[192 ... 223] = &&l_utf8_2,
|
||||
[224 ... 239] = &&l_utf8_3,
|
||||
[240 ... 247] = &&l_utf8_4,
|
||||
[248 ... 255] = &&l_bad
|
||||
};
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
goto *gostring[i];
|
||||
l_bad: c++;
|
||||
l_loop: c++;
|
||||
l_esc: c++;
|
||||
l_qdown: c++;
|
||||
l_utf8_2: c++;
|
||||
l_utf8_3: c++;
|
||||
l_utf8_4: c++;
|
||||
}
|
||||
printf ("%d\n", c);
|
||||
}
|
||||
|
||||
|
||||
/* Following is from GCC gcc.c-torture/execute/20050613-1.c. */
|
||||
|
||||
@ -298,5 +325,6 @@ int main()
|
||||
test_compound_with_relocs();
|
||||
test_multi_relocs();
|
||||
test_zero_init();
|
||||
test_init_ranges();
|
||||
return 0;
|
||||
}
|
||||
|
@ -46,3 +46,4 @@ three
|
||||
sea_fill0: okay
|
||||
sea_fill1: okay
|
||||
sea_fill2: okay
|
||||
1438
|
||||
|
Loading…
Reference in New Issue
Block a user