mirror of
https://github.com/TinyCC/tinycc.git
synced 2026-02-04 04:41:37 +00:00
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.
This commit is contained in:
@@ -149,8 +149,11 @@ ST_FUNC void g(int c)
|
||||
if (nocode_wanted)
|
||||
return;
|
||||
ind1 = ind + 1;
|
||||
if (ind1 > cur_text_section->data_allocated)
|
||||
if ((unsigned)ind1 > cur_text_section->data_allocated) {
|
||||
if (ind1 < 0)
|
||||
tcc_error("program too big");
|
||||
section_realloc(cur_text_section, ind1);
|
||||
}
|
||||
cur_text_section->data[ind] = c;
|
||||
ind = ind1;
|
||||
}
|
||||
|
||||
@@ -257,8 +257,11 @@ void o(uint32_t i)
|
||||
if (!cur_text_section)
|
||||
tcc_error("compiler error! This happens f.ex. if the compiler\n"
|
||||
"can't evaluate constant expressions outside of a function.");
|
||||
if (ind1 > cur_text_section->data_allocated)
|
||||
if ((unsigned)ind1 > cur_text_section->data_allocated) {
|
||||
if (ind1 < 0)
|
||||
tcc_error("program too big");
|
||||
section_realloc(cur_text_section, ind1);
|
||||
}
|
||||
cur_text_section->data[ind++] = i&255;
|
||||
i>>=8;
|
||||
cur_text_section->data[ind++] = i&255;
|
||||
|
||||
@@ -31,8 +31,11 @@ ST_FUNC void g(int c)
|
||||
if (nocode_wanted)
|
||||
return;
|
||||
ind1 = ind + 1;
|
||||
if (ind1 > cur_text_section->data_allocated)
|
||||
if ((unsigned)ind1 > cur_text_section->data_allocated) {
|
||||
if (ind1 < 0)
|
||||
tcc_error("program too big");
|
||||
section_realloc(cur_text_section, ind1);
|
||||
}
|
||||
cur_text_section->data[ind] = c;
|
||||
ind = ind1;
|
||||
}
|
||||
|
||||
@@ -117,8 +117,11 @@ ST_FUNC void o(unsigned int c)
|
||||
int ind1 = ind + 4;
|
||||
if (nocode_wanted)
|
||||
return;
|
||||
if (ind1 > cur_text_section->data_allocated)
|
||||
if ((unsigned)ind1 > cur_text_section->data_allocated) {
|
||||
if (ind1 < 0)
|
||||
tcc_error("program too big");
|
||||
section_realloc(cur_text_section, ind1);
|
||||
}
|
||||
write32le(cur_text_section->data + ind, c);
|
||||
ind = ind1;
|
||||
}
|
||||
@@ -274,6 +277,7 @@ static int arm64_type_size(int t)
|
||||
case VT_DOUBLE: return 3;
|
||||
case VT_LDOUBLE: return 4;
|
||||
case VT_BOOL: return 0;
|
||||
case VT_VOID: return 0;
|
||||
}
|
||||
assert(0);
|
||||
return 0;
|
||||
|
||||
@@ -195,8 +195,11 @@ void C67_g(int c)
|
||||
fprintf(f, " %08X", c);
|
||||
#endif
|
||||
ind1 = ind + 4;
|
||||
if (ind1 > (int) cur_text_section->data_allocated)
|
||||
if ((unsigned)ind1 > (int) cur_text_section->data_allocated) {
|
||||
if (ind1 < 0)
|
||||
tcc_error("program too big");
|
||||
section_realloc(cur_text_section, ind1);
|
||||
}
|
||||
cur_text_section->data[ind] = c & 0xff;
|
||||
cur_text_section->data[ind + 1] = (c >> 8) & 0xff;
|
||||
cur_text_section->data[ind + 2] = (c >> 16) & 0xff;
|
||||
|
||||
@@ -126,8 +126,11 @@ ST_FUNC void g(int c)
|
||||
if (nocode_wanted)
|
||||
return;
|
||||
ind1 = ind + 1;
|
||||
if (ind1 > cur_text_section->data_allocated)
|
||||
if ((unsigned)ind1 > cur_text_section->data_allocated) {
|
||||
if (ind1 < 0)
|
||||
tcc_error("program too big");
|
||||
section_realloc(cur_text_section, ind1);
|
||||
}
|
||||
cur_text_section->data[ind] = c;
|
||||
ind = ind1;
|
||||
}
|
||||
@@ -363,7 +366,8 @@ ST_FUNC void load(int r, SValue *sv)
|
||||
r = 5;
|
||||
} else if ((ft & VT_TYPE) == VT_BYTE || (ft & VT_TYPE) == VT_BOOL) {
|
||||
opc = 0xbe0f; /* movsbl */
|
||||
} else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
|
||||
} else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED) ||
|
||||
(ft & VT_TYPE) == (VT_BOOL | VT_UNSIGNED)) {
|
||||
opc = 0xb60f; /* movzbl */
|
||||
} else if ((ft & VT_TYPE) == VT_SHORT) {
|
||||
opc = 0xbf0f; /* movswl */
|
||||
|
||||
@@ -98,8 +98,11 @@ ST_FUNC void g(int c)
|
||||
if (nocode_wanted)
|
||||
return;
|
||||
ind1 = ind + 1;
|
||||
if (ind1 > cur_text_section->data_allocated)
|
||||
if ((unsigned)ind1 > cur_text_section->data_allocated) {
|
||||
if (ind1 < 0)
|
||||
tcc_error("program too big");
|
||||
section_realloc(cur_text_section, ind1);
|
||||
}
|
||||
cur_text_section->data[ind] = c;
|
||||
ind = ind1;
|
||||
}
|
||||
|
||||
@@ -115,8 +115,11 @@ ST_FUNC void o(unsigned int c)
|
||||
int ind1 = ind + 4;
|
||||
if (nocode_wanted)
|
||||
return;
|
||||
if (ind1 > cur_text_section->data_allocated)
|
||||
if ((unsigned)ind1 > cur_text_section->data_allocated) {
|
||||
if (ind1 < 0)
|
||||
tcc_error("program too big");
|
||||
section_realloc(cur_text_section, ind1);
|
||||
}
|
||||
write32le(cur_text_section->data + ind, c);
|
||||
ind = ind1;
|
||||
}
|
||||
|
||||
25
tccasm.c
25
tccasm.c
@@ -398,6 +398,8 @@ ST_FUNC int asm_int_expr(TCCState *s1)
|
||||
asm_expr(s1, &e);
|
||||
if (e.sym)
|
||||
expect("constant");
|
||||
if ((int)e.v != e.v)
|
||||
tcc_error("integer out of range %lld", (long long)e.v);
|
||||
return e.v;
|
||||
}
|
||||
|
||||
@@ -515,7 +517,7 @@ static void asm_parse_directive(TCCState *s1, int global)
|
||||
tok1 = TOK_ASMDIR_align;
|
||||
}
|
||||
if (tok1 == TOK_ASMDIR_align || tok1 == TOK_ASMDIR_balign) {
|
||||
if (n < 0 || (n & (n-1)) != 0)
|
||||
if (n <= 0 || (n & (n-1)) != 0)
|
||||
tcc_error("alignment must be a positive power of two");
|
||||
offset = (ind + n - 1) & -n;
|
||||
size = offset - ind;
|
||||
@@ -677,17 +679,21 @@ static void asm_parse_directive(TCCState *s1, int global)
|
||||
}
|
||||
case TOK_ASMDIR_org:
|
||||
{
|
||||
unsigned long n;
|
||||
ExprValue e;
|
||||
ElfSym *esym;
|
||||
next();
|
||||
asm_expr(s1, &e);
|
||||
n = e.v;
|
||||
if (n != e.v || n < 0)
|
||||
range:
|
||||
tcc_error(".org out of range");
|
||||
esym = elfsym(e.sym);
|
||||
if (esym) {
|
||||
if (esym->st_shndx != cur_text_section->sh_num)
|
||||
expect("constant or same-section symbol");
|
||||
n += esym->st_value;
|
||||
if (n < esym->st_value)
|
||||
goto range;
|
||||
}
|
||||
if (n < ind)
|
||||
tcc_error("attempt to .org backwards");
|
||||
@@ -713,6 +719,8 @@ static void asm_parse_directive(TCCState *s1, int global)
|
||||
do {
|
||||
Sym *sym;
|
||||
next();
|
||||
if (tok < TOK_IDENT || tok >= SYM_FIRST_ANOM)
|
||||
tcc_error("Illegal symbol %s", get_tok_str(tok1, NULL));
|
||||
sym = get_asm_sym(tok, NULL);
|
||||
if (tok1 != TOK_ASMDIR_hidden)
|
||||
sym->type.t &= ~VT_STATIC;
|
||||
@@ -799,7 +807,7 @@ static void asm_parse_directive(TCCState *s1, int global)
|
||||
if (tok == TOK_STR)
|
||||
pstrcat(ident, sizeof(ident), tokc.str.data);
|
||||
else
|
||||
pstrcat(ident, sizeof(ident), get_tok_str(tok, NULL));
|
||||
pstrcat(ident, sizeof(ident), get_tok_str(tok, &tokc));
|
||||
tcc_warning_c(warn_unsupported)("ignoring .ident %s", ident);
|
||||
next();
|
||||
}
|
||||
@@ -808,10 +816,11 @@ static void asm_parse_directive(TCCState *s1, int global)
|
||||
{
|
||||
Sym *sym;
|
||||
|
||||
tok1 = tok;
|
||||
next();
|
||||
sym = asm_label_find(tok);
|
||||
if (!sym) {
|
||||
tcc_error("label not found: %s", get_tok_str(tok, NULL));
|
||||
tcc_error("label not found: %s", get_tok_str(tok1, NULL));
|
||||
}
|
||||
/* XXX .size name,label2-label1 */
|
||||
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)
|
||||
const char *newtype;
|
||||
int st_type;
|
||||
|
||||
tok1 = tok;
|
||||
next();
|
||||
if (tok < TOK_IDENT || tok >= SYM_FIRST_ANOM)
|
||||
tcc_error("Illegal symbol %s", get_tok_str(tok1, NULL));
|
||||
sym = get_asm_sym(tok, NULL);
|
||||
next();
|
||||
skip(',');
|
||||
@@ -1177,11 +1189,14 @@ static void subst_asm_operands(ASMOperand *operands, int nb_operands,
|
||||
modifier = *str++;
|
||||
index = find_constraint(operands, nb_operands, str, &str);
|
||||
if (index < 0)
|
||||
error:
|
||||
tcc_error("invalid operand reference after %%");
|
||||
op = &operands[index];
|
||||
if (modifier == 'l') {
|
||||
cstr_cat(out_str, get_tok_str(op->is_label, NULL), -1);
|
||||
} else {
|
||||
if (op->vt == NULL)
|
||||
goto error;
|
||||
sv = *op->vt;
|
||||
if (op->reg >= 0) {
|
||||
sv.r = op->reg;
|
||||
@@ -1318,6 +1333,8 @@ ST_FUNC void asm_instr(void)
|
||||
tcc_error("too many asm operands");
|
||||
if (tok < TOK_UIDENT)
|
||||
expect("label identifier");
|
||||
memset(operands + nb_operands + nb_labels, 0,
|
||||
sizeof(operands[0]));
|
||||
operands[nb_operands + nb_labels++].id = tok;
|
||||
|
||||
csym = label_find(tok);
|
||||
|
||||
3
tccgen.c
3
tccgen.c
@@ -7837,6 +7837,9 @@ static void init_putv(init_params *p, CType *type, unsigned long c)
|
||||
ElfW_Rel *rel;
|
||||
esym = elfsym(vtop->sym);
|
||||
ssec = tcc_state->sections[esym->st_shndx];
|
||||
if (esym->st_value + (int)vtop->c.i + size > ssec->data_offset)
|
||||
section_add(ssec, esym->st_value + (int)vtop->c.i +
|
||||
size - ssec->data_offset, 1);
|
||||
memmove (ptr, ssec->data + esym->st_value + (int)vtop->c.i, size);
|
||||
if (ssec->reloc) {
|
||||
/* We need to copy over all memory contents, and that
|
||||
|
||||
@@ -551,4 +551,84 @@ int main(int argc, char **argv)
|
||||
|
||||
}
|
||||
|
||||
#elif defined test_jmp_label
|
||||
|
||||
int main(void) {
|
||||
asm goto("jmp %[label]" : : : : label);
|
||||
}
|
||||
|
||||
#elif defined test_void_ternary
|
||||
|
||||
int main() {
|
||||
unsigned long b = 0;
|
||||
if ((b ? (void)0 : (long long)b))
|
||||
}
|
||||
|
||||
#elif defined test_init_int_string
|
||||
|
||||
int fsB = "";
|
||||
|
||||
//#elif defined test_constant1
|
||||
// results differs on 32/64 bits targets
|
||||
// reports 64: constant expression expected
|
||||
// reports 32: constant exceeds 32 bit
|
||||
//e[1.0 < r()
|
||||
//
|
||||
//#elif defined test_constant2
|
||||
// results differs on 32/64 bits targets
|
||||
// reports 64: constant expression expected
|
||||
// reports 32: constant exceeds 32 bit
|
||||
//e[1 < r()-1.
|
||||
|
||||
#elif defined test_asm1
|
||||
|
||||
asm (".align 8589934592");
|
||||
|
||||
#elif defined test_asm2
|
||||
|
||||
asm (".balign 8589934592");
|
||||
|
||||
#elif defined test_asm3
|
||||
|
||||
asm (".global ");
|
||||
|
||||
#elif defined test_asm4
|
||||
|
||||
asm (".type (a,cr0,digit)");
|
||||
|
||||
#elif defined test_asm5
|
||||
|
||||
asm (".type $6");
|
||||
|
||||
#elif defined test_asm6
|
||||
|
||||
asm (".global $-3");
|
||||
|
||||
#elif defined test_asm7
|
||||
|
||||
asm (".global (dx,0X2D,digit)");
|
||||
|
||||
#elif defined test_asm8
|
||||
|
||||
asm (".size 0XA");
|
||||
|
||||
#elif defined test_asm9
|
||||
|
||||
asm (".weak (fs:0)");
|
||||
|
||||
#elif defined test_asm10
|
||||
|
||||
asm (".align 0");
|
||||
|
||||
#elif defined test_asm11
|
||||
|
||||
asm (".org 33824993159184");
|
||||
|
||||
//#elif defined test_big
|
||||
// results differs on 32/64 bits targets
|
||||
// reports 64: error: program too big
|
||||
// reports 32: memory full
|
||||
//asm (".org 0x7fffffff");
|
||||
//asm (".byte 1, 2, 3, 4");
|
||||
|
||||
#endif
|
||||
|
||||
@@ -262,3 +262,45 @@ bar 15 12 34
|
||||
[test_scope_3]
|
||||
60_errors_and_warnings.c:548: warning: assignment from incompatible pointer type
|
||||
60_errors_and_warnings.c:549: error: initialization of incomplete type
|
||||
|
||||
[test_jmp_label]
|
||||
60_errors_and_warnings.c:557: error: invalid operand reference after %
|
||||
|
||||
[test_void_ternary]
|
||||
60_errors_and_warnings.c:564: error: invalid operand types for binary operation
|
||||
|
||||
[test_init_int_string]
|
||||
60_errors_and_warnings.c:569: warning: assignment makes integer from pointer without a cast
|
||||
|
||||
[test_asm1]
|
||||
60_errors_and_warnings.c:584: error: integer out of range 8589934592
|
||||
|
||||
[test_asm2]
|
||||
60_errors_and_warnings.c:588: error: integer out of range 8589934592
|
||||
|
||||
[test_asm3]
|
||||
60_errors_and_warnings.c:592: error: Illegal symbol .global
|
||||
|
||||
[test_asm4]
|
||||
60_errors_and_warnings.c:597: error: Illegal symbol .type
|
||||
|
||||
[test_asm5]
|
||||
60_errors_and_warnings.c:601: error: Illegal symbol .type
|
||||
|
||||
[test_asm6]
|
||||
60_errors_and_warnings.c:605: error: Illegal symbol .global
|
||||
|
||||
[test_asm7]
|
||||
60_errors_and_warnings.c:609: error: Illegal symbol .global
|
||||
|
||||
[test_asm8]
|
||||
60_errors_and_warnings.c:613: error: label not found: .size
|
||||
|
||||
[test_asm9]
|
||||
60_errors_and_warnings.c:617: error: Illegal symbol .weak
|
||||
|
||||
[test_asm10]
|
||||
60_errors_and_warnings.c:620: error: alignment must be a positive power of two
|
||||
|
||||
[test_asm11]
|
||||
60_errors_and_warnings.c:624: error: .org out of range
|
||||
|
||||
14
x86_64-gen.c
14
x86_64-gen.c
@@ -175,8 +175,11 @@ ST_FUNC void g(int c)
|
||||
if (nocode_wanted)
|
||||
return;
|
||||
ind1 = ind + 1;
|
||||
if (ind1 > cur_text_section->data_allocated)
|
||||
if ((unsigned)ind1 > cur_text_section->data_allocated) {
|
||||
if (ind1 < 0)
|
||||
tcc_error("program too big");
|
||||
section_realloc(cur_text_section, ind1);
|
||||
}
|
||||
cur_text_section->data[ind] = c;
|
||||
ind = ind1;
|
||||
}
|
||||
@@ -444,7 +447,8 @@ void load(int r, SValue *sv)
|
||||
b = 0xdb, r = 5; /* fldt */
|
||||
} else if ((ft & VT_TYPE) == VT_BYTE || (ft & VT_TYPE) == VT_BOOL) {
|
||||
b = 0xbe0f; /* movsbl */
|
||||
} else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
|
||||
} else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED) ||
|
||||
(ft & VT_TYPE) == (VT_BOOL | VT_UNSIGNED)) {
|
||||
b = 0xb60f; /* movzbl */
|
||||
} else if ((ft & VT_TYPE) == VT_SHORT) {
|
||||
b = 0xbf0f; /* movswl */
|
||||
@@ -538,7 +542,8 @@ void load(int r, SValue *sv)
|
||||
o(0x44 + REG_VALUE(r)*8); /* %xmmN */
|
||||
o(0xf024);
|
||||
} else {
|
||||
assert((v >= TREG_XMM0) && (v <= TREG_XMM7));
|
||||
if (!nocode_wanted)
|
||||
assert((v >= TREG_XMM0) && (v <= TREG_XMM7));
|
||||
if ((ft & VT_BTYPE) == VT_FLOAT) {
|
||||
o(0x100ff3);
|
||||
} else {
|
||||
@@ -548,7 +553,8 @@ void load(int r, SValue *sv)
|
||||
o(0xc0 + REG_VALUE(v) + REG_VALUE(r)*8);
|
||||
}
|
||||
} else if (r == TREG_ST0) {
|
||||
assert((v >= TREG_XMM0) && (v <= TREG_XMM7));
|
||||
if (!nocode_wanted)
|
||||
assert((v >= TREG_XMM0) && (v <= TREG_XMM7));
|
||||
/* gen_cvt_ftof(VT_LDOUBLE); */
|
||||
/* movsd %xmmN,-0x10(%rsp) */
|
||||
o(0x110ff2);
|
||||
|
||||
Reference in New Issue
Block a user