I found some problems with a testcase from mailing list. On x86_64 an overflow on reloc R_X86_64_32 occurred that was not reported when using -run -ltcc. The problem could be solved by compiling tcc with -fPIE, -pie or --disable-static. Makefile, configure, libtcc.c, x86_64-link.c: - add --config-pie to configure help. Ignore -pie in libtcc.c and check reloc overflow in x86_64-link.c arm64-gen.c: - Fix reading from constant like '*(int *)0x7fffb7f1280c' elf.h, riscv64-link.c: - fix for -run -ltcc. Ignore reloc R_RISCV_SET_ULEB128 and R_RISCV_SUB_ULEB128 that are used in .debug_loclists section.
Unified · Split
| @@ -24,6 +24,11 @@ CFLAGS += $(CPPFLAGS) · 23 unmodified lines | ||
| 24 | 24 | VPATH = $(TOPSRC) |
| 25 | 25 | -LTCC = $(TOP)/$(LIBTCC) |
| 26 | 26 | |
| 27 | +ifeq ($(CONFIG_pie),yes) | |
| 28 | +CFLAGS += -fPIE | |
| 29 | +LDFLAGS += -pie | |
| 30 | +endif | |
| 31 | + | |
| 27 | 32 | ifdef CONFIG_WIN32 |
| 28 | 33 | CFG = -win |
| 29 | 34 | ifneq ($(CONFIG_static),yes) |
| @@ -503,17 +503,19 @@ ST_FUNC void load(int r, SValue *sv) · 502 unmodified lines | ||
| 503 | 503 | } |
| 504 | 504 | |
| 505 | 505 | if (svr == (VT_CONST | VT_LVAL)) { |
| 506 | + uint64_t i = sv->c.i; | |
| 507 | + | |
| 506 | 508 | if (sv->sym) |
| 507 | 509 | arm64_sym(30, sv->sym, // use x30 for address |
| 508 | − arm64_check_offset(0, arm64_type_size(svtt), sv->c.i)); | |
| 510 | + arm64_check_offset(0, arm64_type_size(svtt), i)); | |
| 509 | 511 | else |
| 510 | − arm64_movimm (30, sv->c.i); | |
| 512 | + arm64_movimm (30, i), i = 0; | |
| 511 | 513 | if (IS_FREG(r)) |
| 512 | 514 | arm64_ldrv(arm64_type_size(svtt), fltr(r), 30, |
| 513 | − arm64_check_offset(1, arm64_type_size(svtt), sv->c.i)); | |
| 515 | + arm64_check_offset(1, arm64_type_size(svtt), i)); | |
| 514 | 516 | else |
| 515 | 517 | arm64_ldrx(!(svtt&VT_UNSIGNED), arm64_type_size(svtt), intr(r), 30, |
| 516 | − arm64_check_offset(1, arm64_type_size(svtt), sv->c.i)); | |
| 518 | + arm64_check_offset(1, arm64_type_size(svtt), i)); | |
| 517 | 519 | return; |
| 518 | 520 | } |
| 519 | 521 | |
| @@ -621,17 +623,19 @@ ST_FUNC void store(int r, SValue *sv) · 101 unmodified lines | ||
| 621 | 623 | } |
| 622 | 624 | |
| 623 | 625 | if (svr == (VT_CONST | VT_LVAL)) { |
| 626 | + uint64_t i = sv->c.i; | |
| 627 | + | |
| 624 | 628 | if (sv->sym) |
| 625 | 629 | arm64_sym(30, sv->sym, // use x30 for address |
| 626 | − arm64_check_offset(0, arm64_type_size(svtt), sv->c.i)); | |
| 630 | + arm64_check_offset(0, arm64_type_size(svtt), i)); | |
| 627 | 631 | else |
| 628 | − arm64_movimm (30, sv->c.i); | |
| 632 | + arm64_movimm (30, i), i = 0; | |
| 629 | 633 | if (IS_FREG(r)) |
| 630 | 634 | arm64_strv(arm64_type_size(svtt), fltr(r), 30, |
| 631 | − arm64_check_offset(1, arm64_type_size(svtt), sv->c.i)); | |
| 635 | + arm64_check_offset(1, arm64_type_size(svtt), i)); | |
| 632 | 636 | else |
| 633 | 637 | arm64_strx(arm64_type_size(svtt), intr(r), 30, |
| 634 | − arm64_check_offset(1, arm64_type_size(svtt), sv->c.i)); | |
| 638 | + arm64_check_offset(1, arm64_type_size(svtt), i)); | |
| 635 | 639 | return; |
| 636 | 640 | } |
| 637 | 641 | |
| @@ -230,6 +230,7 @@ Advanced options (experts only): · 229 unmodified lines | ||
| 230 | 230 | --config-new_dtags=yes use new ELF DTAGs (DT_RUNPATH instead of DT_RPATH) |
| 231 | 231 | --config-codesign=no do not use codesign on apple to sign executables |
| 232 | 232 | --config-dwarf=x use dwarf debug info instead of stabs (x=2..5) |
| 233 | + --config-pie compile with pie | |
| 233 | 234 | |
| 234 | 235 | Cross build options (experimental): |
| 235 | 236 | --cpu=CPU target CPU [$cpu] |
| @@ -3313,8 +3313,12 @@ typedef Elf32_Addr Elf32_Conflict; · 3312 unmodified lines | ||
| 3313 | 3313 | #define R_RISCV_SET16 55 |
| 3314 | 3314 | #define R_RISCV_SET32 56 |
| 3315 | 3315 | #define R_RISCV_32_PCREL 57 |
| 3316 | +#define R_RISCV_IRELATIVE 58 | |
| 3317 | +#define R_RISCV_PLT32 59 | |
| 3318 | +#define R_RISCV_SET_ULEB128 60 | |
| 3319 | +#define R_RISCV_SUB_ULEB128 61 | |
| 3316 | 3320 | |
| 3317 | −#define R_RISCV_NUM 58 | |
| 3321 | +#define R_RISCV_NUM 62 | |
| 3318 | 3322 | |
| 3319 | 3323 | |
| 3320 | 3324 | #endif /* elf.h */ |
| @@ -1674,6 +1674,7 @@ static const TCCOption tcc_options[] = { · 1673 unmodified lines | ||
| 1674 | 1674 | { "C", 0, 0 }, |
| 1675 | 1675 | { "-param", 0, TCC_OPTION_HAS_ARG }, |
| 1676 | 1676 | { "pedantic", 0, 0 }, |
| 1677 | + { "pie", 0, 0 }, | |
| 1677 | 1678 | { "pipe", 0, 0 }, |
| 1678 | 1679 | { "s", 0, 0 }, |
| 1679 | 1680 | { "traditional", 0, 0 }, |
| @@ -51,6 +51,8 @@ ST_FUNC int code_reloc (int reloc_type) · 50 unmodified lines | ||
| 51 | 51 | case R_RISCV_SUB64: |
| 52 | 52 | case R_RISCV_32: |
| 53 | 53 | case R_RISCV_64: |
| 54 | + case R_RISCV_SET_ULEB128: | |
| 55 | + case R_RISCV_SUB_ULEB128: | |
| 54 | 56 | return 0; |
| 55 | 57 | |
| 56 | 58 | case R_RISCV_CALL_PLT: |
| @@ -77,6 +79,8 @@ ST_FUNC int gotplt_entry_type (int reloc_type) · 20 unmodified lines | ||
| 77 | 79 | case R_RISCV_ADD16: |
| 78 | 80 | case R_RISCV_SUB8: |
| 79 | 81 | case R_RISCV_SUB16: |
| 82 | + case R_RISCV_SET_ULEB128: | |
| 83 | + case R_RISCV_SUB_ULEB128: | |
| 80 | 84 | return NO_GOTPLT_ENTRY; |
| 81 | 85 | |
| 82 | 86 | case R_RISCV_BRANCH: |
| @@ -367,6 +371,10 @@ ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 284 unmodified lines | ||
| 367 | 371 | } |
| 368 | 372 | add32le(ptr, val - addr); |
| 369 | 373 | return; |
| 374 | + case R_RISCV_SET_ULEB128: | |
| 375 | + case R_RISCV_SUB_ULEB128: | |
| 376 | + /* ignore. used in section .debug_loclists */ | |
| 377 | + return; | |
| 370 | 378 | case R_RISCV_COPY: |
| 371 | 379 | /* XXX */ |
| 372 | 380 | return; |
| @@ -221,6 +221,10 @@ ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 220 unmodified lines | ||
| 221 | 221 | qrel->r_addend = (int)read32le(ptr) + val; |
| 222 | 222 | qrel++; |
| 223 | 223 | } |
| 224 | + if ((type == R_X86_64_32 && (unsigned long long)val > 4294967295ULL) || | |
| 225 | + (type == R_X86_64_32S && | |
| 226 | + ((long long)val < -2147483648LL || (long long)val > 2147483647LL))) | |
| 227 | + tcc_error_noabort("internal error: relocation %d failed", type); | |
| 224 | 228 | add32le(ptr, val); |
| 225 | 229 | break; |
| 226 | 230 | |
| @@ -251,7 +255,7 @@ ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 24 unmodified lines | ||
| 251 | 255 | /* ignore overflow with undefined weak symbols */ |
| 252 | 256 | if (((ElfW(Sym)*)symtab_section->data)[sym_index].st_shndx != SHN_UNDEF) |
| 253 | 257 | #endif |
| 254 | − tcc_error_noabort("internal error: relocation failed"); | |
| 258 | + tcc_error_noabort("internal error: relocation %d failed", type); | |
| 255 | 259 | } |
| 256 | 260 | add32le(ptr, diff); |
| 257 | 261 | } |