The savannah web site had some new bug report last december. A lot of them are assemmbly bugs. See testcase 60 for an overview.
Unified · Split
| @@ -149,8 +149,11 @@ ST_FUNC void g(int c) · 148 unmodified lines | ||
| 149 | 149 | if (nocode_wanted) |
| 150 | 150 | return; |
| 151 | 151 | 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"); | |
| 153 | 155 | section_realloc(cur_text_section, ind1); |
| 156 | + } | |
| 154 | 157 | cur_text_section->data[ind] = c; |
| 155 | 158 | ind = ind1; |
| 156 | 159 | } |
| @@ -257,8 +257,11 @@ void o(uint32_t i) · 256 unmodified lines | ||
| 257 | 257 | if (!cur_text_section) |
| 258 | 258 | tcc_error("compiler error! This happens f.ex. if the compiler\n" |
| 259 | 259 | "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"); | |
| 261 | 263 | section_realloc(cur_text_section, ind1); |
| 264 | + } | |
| 262 | 265 | cur_text_section->data[ind++] = i&255; |
| 263 | 266 | i>>=8; |
| 264 | 267 | cur_text_section->data[ind++] = i&255; |
| @@ -31,8 +31,11 @@ ST_FUNC void g(int c) · 30 unmodified lines | ||
| 31 | 31 | if (nocode_wanted) |
| 32 | 32 | return; |
| 33 | 33 | 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"); | |
| 35 | 37 | section_realloc(cur_text_section, ind1); |
| 38 | + } | |
| 36 | 39 | cur_text_section->data[ind] = c; |
| 37 | 40 | ind = ind1; |
| 38 | 41 | } |
| @@ -117,8 +117,11 @@ ST_FUNC void o(unsigned int c) · 116 unmodified lines | ||
| 117 | 117 | int ind1 = ind + 4; |
| 118 | 118 | if (nocode_wanted) |
| 119 | 119 | 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"); | |
| 121 | 123 | section_realloc(cur_text_section, ind1); |
| 124 | + } | |
| 122 | 125 | write32le(cur_text_section->data + ind, c); |
| 123 | 126 | ind = ind1; |
| 124 | 127 | } |
| @@ -274,6 +277,7 @@ static int arm64_type_size(int t) · 149 unmodified lines | ||
| 274 | 277 | case VT_DOUBLE: return 3; |
| 275 | 278 | case VT_LDOUBLE: return 4; |
| 276 | 279 | case VT_BOOL: return 0; |
| 280 | + case VT_VOID: return 0; | |
| 277 | 281 | } |
| 278 | 282 | assert(0); |
| 279 | 283 | return 0; |
| @@ -195,8 +195,11 @@ void C67_g(int c) · 194 unmodified lines | ||
| 195 | 195 | fprintf(f, " %08X", c); |
| 196 | 196 | #endif |
| 197 | 197 | 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"); | |
| 199 | 201 | section_realloc(cur_text_section, ind1); |
| 202 | + } | |
| 200 | 203 | cur_text_section->data[ind] = c & 0xff; |
| 201 | 204 | cur_text_section->data[ind + 1] = (c >> 8) & 0xff; |
| 202 | 205 | cur_text_section->data[ind + 2] = (c >> 16) & 0xff; |
| @@ -126,8 +126,11 @@ ST_FUNC void g(int c) · 125 unmodified lines | ||
| 126 | 126 | if (nocode_wanted) |
| 127 | 127 | return; |
| 128 | 128 | 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"); | |
| 130 | 132 | section_realloc(cur_text_section, ind1); |
| 133 | + } | |
| 131 | 134 | cur_text_section->data[ind] = c; |
| 132 | 135 | ind = ind1; |
| 133 | 136 | } |
| @@ -363,7 +366,8 @@ ST_FUNC void load(int r, SValue *sv) · 229 unmodified lines | ||
| 363 | 366 | r = 5; |
| 364 | 367 | } else if ((ft & VT_TYPE) == VT_BYTE || (ft & VT_TYPE) == VT_BOOL) { |
| 365 | 368 | 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)) { | |
| 367 | 371 | opc = 0xb60f; /* movzbl */ |
| 368 | 372 | } else if ((ft & VT_TYPE) == VT_SHORT) { |
| 369 | 373 | opc = 0xbf0f; /* movswl */ |
| @@ -98,8 +98,11 @@ ST_FUNC void g(int c) · 97 unmodified lines | ||
| 98 | 98 | if (nocode_wanted) |
| 99 | 99 | return; |
| 100 | 100 | 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"); | |
| 102 | 104 | section_realloc(cur_text_section, ind1); |
| 105 | + } | |
| 103 | 106 | cur_text_section->data[ind] = c; |
| 104 | 107 | ind = ind1; |
| 105 | 108 | } |
| @@ -115,8 +115,11 @@ ST_FUNC void o(unsigned int c) · 114 unmodified lines | ||
| 115 | 115 | int ind1 = ind + 4; |
| 116 | 116 | if (nocode_wanted) |
| 117 | 117 | 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"); | |
| 119 | 121 | section_realloc(cur_text_section, ind1); |
| 122 | + } | |
| 120 | 123 | write32le(cur_text_section->data + ind, c); |
| 121 | 124 | ind = ind1; |
| 122 | 125 | } |
| @@ -398,6 +398,8 @@ ST_FUNC int asm_int_expr(TCCState *s1) · 397 unmodified lines | ||
| 398 | 398 | asm_expr(s1, &e); |
| 399 | 399 | if (e.sym) |
| 400 | 400 | expect("constant"); |
| 401 | + if ((int)e.v != e.v) | |
| 402 | + tcc_error("integer out of range %lld", (long long)e.v); | |
| 401 | 403 | return e.v; |
| 402 | 404 | } |
| 403 | 405 | |
| @@ -515,7 +517,7 @@ static void asm_parse_directive(TCCState *s1, int global) · 111 unmodified lines | ||
| 515 | 517 | tok1 = TOK_ASMDIR_align; |
| 516 | 518 | } |
| 517 | 519 | 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) | |
| 519 | 521 | tcc_error("alignment must be a positive power of two"); |
| 520 | 522 | offset = (ind + n - 1) & -n; |
| 521 | 523 | size = offset - ind; |
| @@ -677,17 +679,21 @@ static void asm_parse_directive(TCCState *s1, int global) · 155 unmodified lines | ||
| 677 | 679 | } |
| 678 | 680 | case TOK_ASMDIR_org: |
| 679 | 681 | { |
| 680 | − unsigned long n; | |
| 681 | 682 | ExprValue e; |
| 682 | 683 | ElfSym *esym; |
| 683 | 684 | next(); |
| 684 | 685 | asm_expr(s1, &e); |
| 685 | 686 | n = e.v; |
| 687 | + if (n != e.v || n < 0) | |
| 688 | + range: | |
| 689 | + tcc_error(".org out of range"); | |
| 686 | 690 | esym = elfsym(e.sym); |
| 687 | 691 | if (esym) { |
| 688 | 692 | if (esym->st_shndx != cur_text_section->sh_num) |
| 689 | 693 | expect("constant or same-section symbol"); |
| 690 | 694 | n += esym->st_value; |
| 695 | + if (n < esym->st_value) | |
| 696 | + goto range; | |
| 691 | 697 | } |
| 692 | 698 | if (n < ind) |
| 693 | 699 | tcc_error("attempt to .org backwards"); |
| @@ -713,6 +719,8 @@ static void asm_parse_directive(TCCState *s1, int global) · 19 unmodified lines | ||
| 713 | 719 | do { |
| 714 | 720 | Sym *sym; |
| 715 | 721 | next(); |
| 722 | + if (tok < TOK_IDENT || tok >= SYM_FIRST_ANOM) | |
| 723 | + tcc_error("Illegal symbol %s", get_tok_str(tok1, NULL)); | |
| 716 | 724 | sym = get_asm_sym(tok, NULL); |
| 717 | 725 | if (tok1 != TOK_ASMDIR_hidden) |
| 718 | 726 | sym->type.t &= ~VT_STATIC; |
| @@ -799,7 +807,7 @@ static void asm_parse_directive(TCCState *s1, int global) · 80 unmodified lines | ||
| 799 | 807 | if (tok == TOK_STR) |
| 800 | 808 | pstrcat(ident, sizeof(ident), tokc.str.data); |
| 801 | 809 | else |
| 802 | − pstrcat(ident, sizeof(ident), get_tok_str(tok, NULL)); | |
| 810 | + pstrcat(ident, sizeof(ident), get_tok_str(tok, &tokc)); | |
| 803 | 811 | tcc_warning_c(warn_unsupported)("ignoring .ident %s", ident); |
| 804 | 812 | next(); |
| 805 | 813 | } |
| @@ -808,10 +816,11 @@ static void asm_parse_directive(TCCState *s1, int global) · 2 unmodified lines | ||
| 808 | 816 | { |
| 809 | 817 | Sym *sym; |
| 810 | 818 | |
| 819 | + tok1 = tok; | |
| 811 | 820 | next(); |
| 812 | 821 | sym = asm_label_find(tok); |
| 813 | 822 | 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)); | |
| 815 | 824 | } |
| 816 | 825 | /* XXX .size name,label2-label1 */ |
| 817 | 826 | 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) · 10 unmodified lines | ||
| 828 | 837 | const char *newtype; |
| 829 | 838 | int st_type; |
| 830 | 839 | |
| 840 | + tok1 = tok; | |
| 831 | 841 | next(); |
| 842 | + if (tok < TOK_IDENT || tok >= SYM_FIRST_ANOM) | |
| 843 | + tcc_error("Illegal symbol %s", get_tok_str(tok1, NULL)); | |
| 832 | 844 | sym = get_asm_sym(tok, NULL); |
| 833 | 845 | next(); |
| 834 | 846 | skip(','); |
| @@ -1177,11 +1189,14 @@ static void subst_asm_operands(ASMOperand *operands, int nb_operands, · 342 unmodified lines | ||
| 1177 | 1189 | modifier = *str++; |
| 1178 | 1190 | index = find_constraint(operands, nb_operands, str, &str); |
| 1179 | 1191 | if (index < 0) |
| 1192 | + error: | |
| 1180 | 1193 | tcc_error("invalid operand reference after %%"); |
| 1181 | 1194 | op = &operands[index]; |
| 1182 | 1195 | if (modifier == 'l') { |
| 1183 | 1196 | cstr_cat(out_str, get_tok_str(op->is_label, NULL), -1); |
| 1184 | 1197 | } else { |
| 1198 | + if (op->vt == NULL) | |
| 1199 | + goto error; | |
| 1185 | 1200 | sv = *op->vt; |
| 1186 | 1201 | if (op->reg >= 0) { |
| 1187 | 1202 | sv.r = op->reg; |
| @@ -1318,6 +1333,8 @@ ST_FUNC void asm_instr(void) · 130 unmodified lines | ||
| 1318 | 1333 | tcc_error("too many asm operands"); |
| 1319 | 1334 | if (tok < TOK_UIDENT) |
| 1320 | 1335 | expect("label identifier"); |
| 1336 | + memset(operands + nb_operands + nb_labels, 0, | |
| 1337 | + sizeof(operands[0])); | |
| 1321 | 1338 | operands[nb_operands + nb_labels++].id = tok; |
| 1322 | 1339 | |
| 1323 | 1340 | csym = label_find(tok); |
| @@ -7837,6 +7837,9 @@ static void init_putv(init_params *p, CType *type, unsigned long c) · 7836 unmodified lines | ||
| 7837 | 7837 | ElfW_Rel *rel; |
| 7838 | 7838 | esym = elfsym(vtop->sym); |
| 7839 | 7839 | 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); | |
| 7840 | 7843 | memmove (ptr, ssec->data + esym->st_value + (int)vtop->c.i, size); |
| 7841 | 7844 | if (ssec->reloc) { |
| 7842 | 7845 | /* We need to copy over all memory contents, and that |
| @@ -551,4 +551,84 @@ int main(int argc, char **argv) · 550 unmodified lines | ||
| 551 | 551 | |
| 552 | 552 | } |
| 553 | 553 | |
| 554 | +#elif defined test_jmp_label | |
| 555 | + | |
| 556 | +int main(void) { | |
| 557 | + asm goto("jmp %[label]" : : : : label); | |
| 558 | +} | |
| 559 | + | |
| 560 | +#elif defined test_void_ternary | |
| 561 | + | |
| 562 | +int main() { | |
| 563 | + unsigned long b = 0; | |
| 564 | + if ((b ? (void)0 : (long long)b)) | |
| 565 | +} | |
| 566 | + | |
| 567 | +#elif defined test_init_int_string | |
| 568 | + | |
| 569 | +int fsB = ""; | |
| 570 | + | |
| 571 | +//#elif defined test_constant1 | |
| 572 | +// results differs on 32/64 bits targets | |
| 573 | +// reports 64: constant expression expected | |
| 574 | +// reports 32: constant exceeds 32 bit | |
| 575 | +//e[1.0 < r() | |
| 576 | +// | |
| 577 | +//#elif defined test_constant2 | |
| 578 | +// results differs on 32/64 bits targets | |
| 579 | +// reports 64: constant expression expected | |
| 580 | +// reports 32: constant exceeds 32 bit | |
| 581 | +//e[1 < r()-1. | |
| 582 | + | |
| 583 | +#elif defined test_asm1 | |
| 584 | + | |
| 585 | +asm (".align 8589934592"); | |
| 586 | + | |
| 587 | +#elif defined test_asm2 | |
| 588 | + | |
| 589 | +asm (".balign 8589934592"); | |
| 590 | + | |
| 591 | +#elif defined test_asm3 | |
| 592 | + | |
| 593 | +asm (".global "); | |
| 594 | + | |
| 595 | +#elif defined test_asm4 | |
| 596 | + | |
| 597 | +asm (".type (a,cr0,digit)"); | |
| 598 | + | |
| 599 | +#elif defined test_asm5 | |
| 600 | + | |
| 601 | +asm (".type $6"); | |
| 602 | + | |
| 603 | +#elif defined test_asm6 | |
| 604 | + | |
| 605 | +asm (".global $-3"); | |
| 606 | + | |
| 607 | +#elif defined test_asm7 | |
| 608 | + | |
| 609 | +asm (".global (dx,0X2D,digit)"); | |
| 610 | + | |
| 611 | +#elif defined test_asm8 | |
| 612 | + | |
| 613 | +asm (".size 0XA"); | |
| 614 | + | |
| 615 | +#elif defined test_asm9 | |
| 616 | + | |
| 617 | +asm (".weak (fs:0)"); | |
| 618 | + | |
| 619 | +#elif defined test_asm10 | |
| 620 | + | |
| 621 | +asm (".align 0"); | |
| 622 | + | |
| 623 | +#elif defined test_asm11 | |
| 624 | + | |
| 625 | +asm (".org 33824993159184"); | |
| 626 | + | |
| 627 | +//#elif defined test_big | |
| 628 | +// results differs on 32/64 bits targets | |
| 629 | +// reports 64: error: program too big | |
| 630 | +// reports 32: memory full | |
| 631 | +//asm (".org 0x7fffffff"); | |
| 632 | +//asm (".byte 1, 2, 3, 4"); | |
| 633 | + | |
| 554 | 634 | #endif |
| @@ -262,3 +262,45 @@ bar 15 12 34 · 261 unmodified lines | ||
| 262 | 262 | [test_scope_3] |
| 263 | 263 | 60_errors_and_warnings.c:548: warning: assignment from incompatible pointer type |
| 264 | 264 | 60_errors_and_warnings.c:549: error: initialization of incomplete type |
| 265 | + | |
| 266 | +[test_jmp_label] | |
| 267 | +60_errors_and_warnings.c:557: error: invalid operand reference after % | |
| 268 | + | |
| 269 | +[test_void_ternary] | |
| 270 | +60_errors_and_warnings.c:564: error: invalid operand types for binary operation | |
| 271 | + | |
| 272 | +[test_init_int_string] | |
| 273 | +60_errors_and_warnings.c:569: warning: assignment makes integer from pointer without a cast | |
| 274 | + | |
| 275 | +[test_asm1] | |
| 276 | +60_errors_and_warnings.c:584: error: integer out of range 8589934592 | |
| 277 | + | |
| 278 | +[test_asm2] | |
| 279 | +60_errors_and_warnings.c:588: error: integer out of range 8589934592 | |
| 280 | + | |
| 281 | +[test_asm3] | |
| 282 | +60_errors_and_warnings.c:592: error: Illegal symbol .global | |
| 283 | + | |
| 284 | +[test_asm4] | |
| 285 | +60_errors_and_warnings.c:597: error: Illegal symbol .type | |
| 286 | + | |
| 287 | +[test_asm5] | |
| 288 | +60_errors_and_warnings.c:601: error: Illegal symbol .type | |
| 289 | + | |
| 290 | +[test_asm6] | |
| 291 | +60_errors_and_warnings.c:605: error: Illegal symbol .global | |
| 292 | + | |
| 293 | +[test_asm7] | |
| 294 | +60_errors_and_warnings.c:609: error: Illegal symbol .global | |
| 295 | + | |
| 296 | +[test_asm8] | |
| 297 | +60_errors_and_warnings.c:613: error: label not found: .size | |
| 298 | + | |
| 299 | +[test_asm9] | |
| 300 | +60_errors_and_warnings.c:617: error: Illegal symbol .weak | |
| 301 | + | |
| 302 | +[test_asm10] | |
| 303 | +60_errors_and_warnings.c:620: error: alignment must be a positive power of two | |
| 304 | + | |
| 305 | +[test_asm11] | |
| 306 | +60_errors_and_warnings.c:624: error: .org out of range | |
| @@ -175,8 +175,11 @@ ST_FUNC void g(int c) · 174 unmodified lines | ||
| 175 | 175 | if (nocode_wanted) |
| 176 | 176 | return; |
| 177 | 177 | ind1 = ind + 1; |
| 178 | − if (ind1 > cur_text_section->data_allocated) | |
| 178 | + if ((unsigned)ind1 > cur_text_section->data_allocated) { | |
| 179 | + if (ind1 < 0) | |
| 180 | + tcc_error("program too big"); | |
| 179 | 181 | section_realloc(cur_text_section, ind1); |
| 182 | + } | |
| 180 | 183 | cur_text_section->data[ind] = c; |
| 181 | 184 | ind = ind1; |
| 182 | 185 | } |
| @@ -444,7 +447,8 @@ void load(int r, SValue *sv) · 261 unmodified lines | ||
| 444 | 447 | b = 0xdb, r = 5; /* fldt */ |
| 445 | 448 | } else if ((ft & VT_TYPE) == VT_BYTE || (ft & VT_TYPE) == VT_BOOL) { |
| 446 | 449 | b = 0xbe0f; /* movsbl */ |
| 447 | − } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) { | |
| 450 | + } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED) || | |
| 451 | + (ft & VT_TYPE) == (VT_BOOL | VT_UNSIGNED)) { | |
| 448 | 452 | b = 0xb60f; /* movzbl */ |
| 449 | 453 | } else if ((ft & VT_TYPE) == VT_SHORT) { |
| 450 | 454 | b = 0xbf0f; /* movswl */ |
| @@ -538,7 +542,8 @@ void load(int r, SValue *sv) · 87 unmodified lines | ||
| 538 | 542 | o(0x44 + REG_VALUE(r)*8); /* %xmmN */ |
| 539 | 543 | o(0xf024); |
| 540 | 544 | } else { |
| 541 | − assert((v >= TREG_XMM0) && (v <= TREG_XMM7)); | |
| 545 | + if (!nocode_wanted) | |
| 546 | + assert((v >= TREG_XMM0) && (v <= TREG_XMM7)); | |
| 542 | 547 | if ((ft & VT_BTYPE) == VT_FLOAT) { |
| 543 | 548 | o(0x100ff3); |
| 544 | 549 | } else { |
| @@ -548,7 +553,8 @@ void load(int r, SValue *sv) · 3 unmodified lines | ||
| 548 | 553 | o(0xc0 + REG_VALUE(v) + REG_VALUE(r)*8); |
| 549 | 554 | } |
| 550 | 555 | } else if (r == TREG_ST0) { |
| 551 | − assert((v >= TREG_XMM0) && (v <= TREG_XMM7)); | |
| 556 | + if (!nocode_wanted) | |
| 557 | + assert((v >= TREG_XMM0) && (v <= TREG_XMM7)); | |
| 552 | 558 | /* gen_cvt_ftof(VT_LDOUBLE); */ |
| 553 | 559 | /* movsd %xmmN,-0x10(%rsp) */ |
| 554 | 560 | o(0x110ff2); |