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 | VPATH = $(TOPSRC) | 24 | VPATH = $(TOPSRC) |
| 25 | -LTCC = $(TOP)/$(LIBTCC) | 25 | -LTCC = $(TOP)/$(LIBTCC) |
| 26 | 26 | ||
| 27 | ifeq ($(CONFIG_pie),yes) | ||
| 28 | CFLAGS += -fPIE | ||
| 29 | LDFLAGS += -pie | ||
| 30 | endif | ||
| 31 | |||
| 27 | ifdef CONFIG_WIN32 | 32 | ifdef CONFIG_WIN32 |
| 28 | CFG = -win | 33 | CFG = -win |
| 29 | ifneq ($(CONFIG_static),yes) | 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 | if (svr == (VT_CONST | VT_LVAL)) { | 505 | if (svr == (VT_CONST | VT_LVAL)) { |
| 506 | uint64_t i = sv->c.i; | ||
| 507 | |||
| 506 | if (sv->sym) | 508 | if (sv->sym) |
| 507 | arm64_sym(30, sv->sym, // use x30 for address | 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 | else | 511 | else |
| 510 | arm64_movimm (30, sv->c.i); | 512 | arm64_movimm (30, i), i = 0; |
| 511 | if (IS_FREG(r)) | 513 | if (IS_FREG(r)) |
| 512 | arm64_ldrv(arm64_type_size(svtt), fltr(r), 30, | 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 | else | 516 | else |
| 515 | arm64_ldrx(!(svtt&VT_UNSIGNED), arm64_type_size(svtt), intr(r), 30, | 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 | return; | 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 | if (svr == (VT_CONST | VT_LVAL)) { | 625 | if (svr == (VT_CONST | VT_LVAL)) { |
| 626 | uint64_t i = sv->c.i; | ||
| 627 | |||
| 624 | if (sv->sym) | 628 | if (sv->sym) |
| 625 | arm64_sym(30, sv->sym, // use x30 for address | 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 | else | 631 | else |
| 628 | arm64_movimm (30, sv->c.i); | 632 | arm64_movimm (30, i), i = 0; |
| 629 | if (IS_FREG(r)) | 633 | if (IS_FREG(r)) |
| 630 | arm64_strv(arm64_type_size(svtt), fltr(r), 30, | 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 | else | 636 | else |
| 633 | arm64_strx(arm64_type_size(svtt), intr(r), 30, | 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 | return; | 639 | return; |
| 636 | } | 640 | } |
| 637 | 641 | ||
| @@ -230,6 +230,7 @@ Advanced options (experts only): · 229 unmodified lines | |||
| 230 | --config-new_dtags=yes use new ELF DTAGs (DT_RUNPATH instead of DT_RPATH) | 230 | --config-new_dtags=yes use new ELF DTAGs (DT_RUNPATH instead of DT_RPATH) |
| 231 | --config-codesign=no do not use codesign on apple to sign executables | 231 | --config-codesign=no do not use codesign on apple to sign executables |
| 232 | --config-dwarf=x use dwarf debug info instead of stabs (x=2..5) | 232 | --config-dwarf=x use dwarf debug info instead of stabs (x=2..5) |
| 233 | --config-pie compile with pie | ||
| 233 | 234 | ||
| 234 | Cross build options (experimental): | 235 | Cross build options (experimental): |
| 235 | --cpu=CPU target CPU [$cpu] | 236 | --cpu=CPU target CPU [$cpu] |
| @@ -3313,8 +3313,12 @@ typedef Elf32_Addr Elf32_Conflict; · 3312 unmodified lines | |||
| 3313 | #define R_RISCV_SET16 55 | 3313 | #define R_RISCV_SET16 55 |
| 3314 | #define R_RISCV_SET32 56 | 3314 | #define R_RISCV_SET32 56 |
| 3315 | #define R_RISCV_32_PCREL 57 | 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 | #endif /* elf.h */ | 3324 | #endif /* elf.h */ |
| @@ -1674,6 +1674,7 @@ static const TCCOption tcc_options[] = { · 1673 unmodified lines | |||
| 1674 | { "C", 0, 0 }, | 1674 | { "C", 0, 0 }, |
| 1675 | { "-param", 0, TCC_OPTION_HAS_ARG }, | 1675 | { "-param", 0, TCC_OPTION_HAS_ARG }, |
| 1676 | { "pedantic", 0, 0 }, | 1676 | { "pedantic", 0, 0 }, |
| 1677 | { "pie", 0, 0 }, | ||
| 1677 | { "pipe", 0, 0 }, | 1678 | { "pipe", 0, 0 }, |
| 1678 | { "s", 0, 0 }, | 1679 | { "s", 0, 0 }, |
| 1679 | { "traditional", 0, 0 }, | 1680 | { "traditional", 0, 0 }, |
| @@ -51,6 +51,8 @@ ST_FUNC int code_reloc (int reloc_type) · 50 unmodified lines | |||
| 51 | case R_RISCV_SUB64: | 51 | case R_RISCV_SUB64: |
| 52 | case R_RISCV_32: | 52 | case R_RISCV_32: |
| 53 | case R_RISCV_64: | 53 | case R_RISCV_64: |
| 54 | case R_RISCV_SET_ULEB128: | ||
| 55 | case R_RISCV_SUB_ULEB128: | ||
| 54 | return 0; | 56 | return 0; |
| 55 | 57 | ||
| 56 | case R_RISCV_CALL_PLT: | 58 | case R_RISCV_CALL_PLT: |
| @@ -77,6 +79,8 @@ ST_FUNC int gotplt_entry_type (int reloc_type) · 20 unmodified lines | |||
| 77 | case R_RISCV_ADD16: | 79 | case R_RISCV_ADD16: |
| 78 | case R_RISCV_SUB8: | 80 | case R_RISCV_SUB8: |
| 79 | case R_RISCV_SUB16: | 81 | case R_RISCV_SUB16: |
| 82 | case R_RISCV_SET_ULEB128: | ||
| 83 | case R_RISCV_SUB_ULEB128: | ||
| 80 | return NO_GOTPLT_ENTRY; | 84 | return NO_GOTPLT_ENTRY; |
| 81 | 85 | ||
| 82 | case R_RISCV_BRANCH: | 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 | add32le(ptr, val - addr); | 372 | add32le(ptr, val - addr); |
| 369 | return; | 373 | return; |
| 374 | case R_RISCV_SET_ULEB128: | ||
| 375 | case R_RISCV_SUB_ULEB128: | ||
| 376 | /* ignore. used in section .debug_loclists */ | ||
| 377 | return; | ||
| 370 | case R_RISCV_COPY: | 378 | case R_RISCV_COPY: |
| 371 | /* XXX */ | 379 | /* XXX */ |
| 372 | return; | 380 | return; |
| @@ -221,6 +221,10 @@ ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 220 unmodified lines | |||
| 221 | qrel->r_addend = (int)read32le(ptr) + val; | 221 | qrel->r_addend = (int)read32le(ptr) + val; |
| 222 | qrel++; | 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 | add32le(ptr, val); | 228 | add32le(ptr, val); |
| 225 | break; | 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 | /* ignore overflow with undefined weak symbols */ | 255 | /* ignore overflow with undefined weak symbols */ |
| 252 | if (((ElfW(Sym)*)symtab_section->data)[sym_index].st_shndx != SHN_UNDEF) | 256 | if (((ElfW(Sym)*)symtab_section->data)[sym_index].st_shndx != SHN_UNDEF) |
| 253 | #endif | 257 | #endif |
| 254 | tcc_error_noabort("internal error: relocation failed"); | 258 | tcc_error_noabort("internal error: relocation %d failed", type); |
| 255 | } | 259 | } |
| 256 | add32le(ptr, diff); | 260 | add32le(ptr, diff); |
| 257 | } | 261 | } |