Skip to content

Commit 8a8388c

Browse files
committed
Solve some bug reports
The savannah web site had some new bug report last december. A lot of them are assemmbly bugs. See testcase 60 for an overview.
1 parent 9a7edb2 commit 8a8388c

File tree

13 files changed

+191
-17
lines changed

13 files changed

+191
-17
lines changed

arm-asm.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,11 @@ ST_FUNC void g(int c)
149149
if (nocode_wanted)
150150
return;
151151
ind1 = ind + 1;
152-
if (ind1 > cur_text_section->data_allocated)
152+
if ((unsigned)ind1 > cur_text_section->data_allocated) {
153+
if (ind1 < 0)
154+
tcc_error("program too big");
153155
section_realloc(cur_text_section, ind1);
156+
}
154157
cur_text_section->data[ind] = c;
155158
ind = ind1;
156159
}

arm-gen.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,11 @@ void o(uint32_t i)
257257
if (!cur_text_section)
258258
tcc_error("compiler error! This happens f.ex. if the compiler\n"
259259
"can't evaluate constant expressions outside of a function.");
260-
if (ind1 > cur_text_section->data_allocated)
260+
if ((unsigned)ind1 > cur_text_section->data_allocated) {
261+
if (ind1 < 0)
262+
tcc_error("program too big");
261263
section_realloc(cur_text_section, ind1);
264+
}
262265
cur_text_section->data[ind++] = i&255;
263266
i>>=8;
264267
cur_text_section->data[ind++] = i&255;

arm64-asm.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,11 @@ ST_FUNC void g(int c)
3131
if (nocode_wanted)
3232
return;
3333
ind1 = ind + 1;
34-
if (ind1 > cur_text_section->data_allocated)
34+
if ((unsigned)ind1 > cur_text_section->data_allocated) {
35+
if (ind1 < 0)
36+
tcc_error("program too big");
3537
section_realloc(cur_text_section, ind1);
38+
}
3639
cur_text_section->data[ind] = c;
3740
ind = ind1;
3841
}

arm64-gen.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,11 @@ ST_FUNC void o(unsigned int c)
117117
int ind1 = ind + 4;
118118
if (nocode_wanted)
119119
return;
120-
if (ind1 > cur_text_section->data_allocated)
120+
if ((unsigned)ind1 > cur_text_section->data_allocated) {
121+
if (ind1 < 0)
122+
tcc_error("program too big");
121123
section_realloc(cur_text_section, ind1);
124+
}
122125
write32le(cur_text_section->data + ind, c);
123126
ind = ind1;
124127
}
@@ -274,6 +277,7 @@ static int arm64_type_size(int t)
274277
case VT_DOUBLE: return 3;
275278
case VT_LDOUBLE: return 4;
276279
case VT_BOOL: return 0;
280+
case VT_VOID: return 0;
277281
}
278282
assert(0);
279283
return 0;

c67-gen.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,11 @@ void C67_g(int c)
195195
fprintf(f, " %08X", c);
196196
#endif
197197
ind1 = ind + 4;
198-
if (ind1 > (int) cur_text_section->data_allocated)
198+
if ((unsigned)ind1 > (int) cur_text_section->data_allocated) {
199+
if (ind1 < 0)
200+
tcc_error("program too big");
199201
section_realloc(cur_text_section, ind1);
202+
}
200203
cur_text_section->data[ind] = c & 0xff;
201204
cur_text_section->data[ind + 1] = (c >> 8) & 0xff;
202205
cur_text_section->data[ind + 2] = (c >> 16) & 0xff;

i386-gen.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,11 @@ ST_FUNC void g(int c)
126126
if (nocode_wanted)
127127
return;
128128
ind1 = ind + 1;
129-
if (ind1 > cur_text_section->data_allocated)
129+
if ((unsigned)ind1 > cur_text_section->data_allocated) {
130+
if (ind1 < 0)
131+
tcc_error("program too big");
130132
section_realloc(cur_text_section, ind1);
133+
}
131134
cur_text_section->data[ind] = c;
132135
ind = ind1;
133136
}
@@ -363,7 +366,8 @@ ST_FUNC void load(int r, SValue *sv)
363366
r = 5;
364367
} else if ((ft & VT_TYPE) == VT_BYTE || (ft & VT_TYPE) == VT_BOOL) {
365368
opc = 0xbe0f; /* movsbl */
366-
} else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
369+
} else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED) ||
370+
(ft & VT_TYPE) == (VT_BOOL | VT_UNSIGNED)) {
367371
opc = 0xb60f; /* movzbl */
368372
} else if ((ft & VT_TYPE) == VT_SHORT) {
369373
opc = 0xbf0f; /* movswl */

riscv64-asm.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,11 @@ ST_FUNC void g(int c)
9898
if (nocode_wanted)
9999
return;
100100
ind1 = ind + 1;
101-
if (ind1 > cur_text_section->data_allocated)
101+
if ((unsigned)ind1 > cur_text_section->data_allocated) {
102+
if (ind1 < 0)
103+
tcc_error("program too big");
102104
section_realloc(cur_text_section, ind1);
105+
}
103106
cur_text_section->data[ind] = c;
104107
ind = ind1;
105108
}

riscv64-gen.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,11 @@ ST_FUNC void o(unsigned int c)
115115
int ind1 = ind + 4;
116116
if (nocode_wanted)
117117
return;
118-
if (ind1 > cur_text_section->data_allocated)
118+
if ((unsigned)ind1 > cur_text_section->data_allocated) {
119+
if (ind1 < 0)
120+
tcc_error("program too big");
119121
section_realloc(cur_text_section, ind1);
122+
}
120123
write32le(cur_text_section->data + ind, c);
121124
ind = ind1;
122125
}

tccasm.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,8 @@ ST_FUNC int asm_int_expr(TCCState *s1)
398398
asm_expr(s1, &e);
399399
if (e.sym)
400400
expect("constant");
401+
if ((int)e.v != e.v)
402+
tcc_error("integer out of range %lld", (long long)e.v);
401403
return e.v;
402404
}
403405

@@ -515,7 +517,7 @@ static void asm_parse_directive(TCCState *s1, int global)
515517
tok1 = TOK_ASMDIR_align;
516518
}
517519
if (tok1 == TOK_ASMDIR_align || tok1 == TOK_ASMDIR_balign) {
518-
if (n < 0 || (n & (n-1)) != 0)
520+
if (n <= 0 || (n & (n-1)) != 0)
519521
tcc_error("alignment must be a positive power of two");
520522
offset = (ind + n - 1) & -n;
521523
size = offset - ind;
@@ -677,17 +679,21 @@ static void asm_parse_directive(TCCState *s1, int global)
677679
}
678680
case TOK_ASMDIR_org:
679681
{
680-
unsigned long n;
681682
ExprValue e;
682683
ElfSym *esym;
683684
next();
684685
asm_expr(s1, &e);
685686
n = e.v;
687+
if (n != e.v || n < 0)
688+
range:
689+
tcc_error(".org out of range");
686690
esym = elfsym(e.sym);
687691
if (esym) {
688692
if (esym->st_shndx != cur_text_section->sh_num)
689693
expect("constant or same-section symbol");
690694
n += esym->st_value;
695+
if (n < esym->st_value)
696+
goto range;
691697
}
692698
if (n < ind)
693699
tcc_error("attempt to .org backwards");
@@ -713,6 +719,8 @@ static void asm_parse_directive(TCCState *s1, int global)
713719
do {
714720
Sym *sym;
715721
next();
722+
if (tok < TOK_IDENT || tok >= SYM_FIRST_ANOM)
723+
tcc_error("Illegal symbol %s", get_tok_str(tok1, NULL));
716724
sym = get_asm_sym(tok, NULL);
717725
if (tok1 != TOK_ASMDIR_hidden)
718726
sym->type.t &= ~VT_STATIC;
@@ -799,7 +807,7 @@ static void asm_parse_directive(TCCState *s1, int global)
799807
if (tok == TOK_STR)
800808
pstrcat(ident, sizeof(ident), tokc.str.data);
801809
else
802-
pstrcat(ident, sizeof(ident), get_tok_str(tok, NULL));
810+
pstrcat(ident, sizeof(ident), get_tok_str(tok, &tokc));
803811
tcc_warning_c(warn_unsupported)("ignoring .ident %s", ident);
804812
next();
805813
}
@@ -808,10 +816,11 @@ static void asm_parse_directive(TCCState *s1, int global)
808816
{
809817
Sym *sym;
810818

819+
tok1 = tok;
811820
next();
812821
sym = asm_label_find(tok);
813822
if (!sym) {
814-
tcc_error("label not found: %s", get_tok_str(tok, NULL));
823+
tcc_error("label not found: %s", get_tok_str(tok1, NULL));
815824
}
816825
/* XXX .size name,label2-label1 */
817826
tcc_warning_c(warn_unsupported)("ignoring .size %s,*", get_tok_str(tok, NULL));
@@ -828,7 +837,10 @@ static void asm_parse_directive(TCCState *s1, int global)
828837
const char *newtype;
829838
int st_type;
830839

840+
tok1 = tok;
831841
next();
842+
if (tok < TOK_IDENT || tok >= SYM_FIRST_ANOM)
843+
tcc_error("Illegal symbol %s", get_tok_str(tok1, NULL));
832844
sym = get_asm_sym(tok, NULL);
833845
next();
834846
skip(',');
@@ -1177,11 +1189,14 @@ static void subst_asm_operands(ASMOperand *operands, int nb_operands,
11771189
modifier = *str++;
11781190
index = find_constraint(operands, nb_operands, str, &str);
11791191
if (index < 0)
1192+
error:
11801193
tcc_error("invalid operand reference after %%");
11811194
op = &operands[index];
11821195
if (modifier == 'l') {
11831196
cstr_cat(out_str, get_tok_str(op->is_label, NULL), -1);
11841197
} else {
1198+
if (op->vt == NULL)
1199+
goto error;
11851200
sv = *op->vt;
11861201
if (op->reg >= 0) {
11871202
sv.r = op->reg;
@@ -1318,6 +1333,8 @@ ST_FUNC void asm_instr(void)
13181333
tcc_error("too many asm operands");
13191334
if (tok < TOK_UIDENT)
13201335
expect("label identifier");
1336+
memset(operands + nb_operands + nb_labels, 0,
1337+
sizeof(operands[0]));
13211338
operands[nb_operands + nb_labels++].id = tok;
13221339

13231340
csym = label_find(tok);

tccgen.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7837,6 +7837,9 @@ static void init_putv(init_params *p, CType *type, unsigned long c)
78377837
ElfW_Rel *rel;
78387838
esym = elfsym(vtop->sym);
78397839
ssec = tcc_state->sections[esym->st_shndx];
7840+
if (esym->st_value + (int)vtop->c.i + size > ssec->data_offset)
7841+
section_add(ssec, esym->st_value + (int)vtop->c.i +
7842+
size - ssec->data_offset, 1);
78407843
memmove (ptr, ssec->data + esym->st_value + (int)vtop->c.i, size);
78417844
if (ssec->reloc) {
78427845
/* We need to copy over all memory contents, and that

0 commit comments

Comments
 (0)