From 5a370d8a6beeb5855cd686033c5d805c04edf2a4 Mon Sep 17 00:00:00 2001 From: herman ten brugge Date: Tue, 23 Dec 2025 06:46:22 +0100 Subject: [PATCH] Relocation updates x86_64-link.c: Check relocations R_X86_64_32/R_X86_64_32S. These relocations can become to large if not configured with '--disable-static' or '--config-pie' and code is run with -run -ltcc. This only happens on x86_64. tccdbg.c: 1) Add some .debug (dummy) sections when dwarf is used. These sections are otherwise not relocated correctly for R_DATA_32DW. 2) Fix stab problem when reloc is applied twice. --- Makefile | 2 +- tccdbg.c | 32 ++++++++++++++++++++++++-------- x86_64-link.c | 9 +++++++++ 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index d9641d2e..b1b97cb8 100644 --- a/Makefile +++ b/Makefile @@ -476,7 +476,7 @@ tcc_c$(EXESUF): $($T_FILES) sani-tes% : tcc_s$(EXESUF) @$(MAKE) --no-print-directory TCC_LOCAL=$(CURDIR)/$< tes$* tcc_s$(EXESUF): $($T_FILES) - $S$(CC) tcc.c -o $@ -fsanitize=address,undefined $(DEFINES) $(CFLAGS) $(LIBS) + $S$(CC) tcc.c -o $@ -fsanitize=address,undefined $(DEFINES) $(CFLAGS) $(LDFLAGS) $(LIBS) # test the installed tcc instead test-install: $(TCCDEFS_H) @$(MAKE) -C tests TESTINSTALL=yes #_all diff --git a/tccdbg.c b/tccdbg.c index ccd944c8..67e85643 100644 --- a/tccdbg.c +++ b/tccdbg.c @@ -431,7 +431,7 @@ struct _tccdbg { #define FDE_ENCODING (DW_EH_PE_udata4 | DW_EH_PE_signed | DW_EH_PE_pcrel) /* ------------------------------------------------------------------------- */ -static void put_stabs(TCCState *s1, const char *str, int type, int other, +static int put_stabs(TCCState *s1, const char *str, int type, int other, int desc, unsigned long value); ST_FUNC void tcc_debug_new(TCCState *s1) @@ -449,6 +449,19 @@ ST_FUNC void tcc_debug_new(TCCState *s1) #endif if (s1->dwarf) { + int i; + /* The sections below are just to make reloctions with + R_DATA_32DW work correctly. See tccelf.c */ + static const char *const debug[] = { + ".debug_macro", + ".debug_loc", + ".debug_ranges", + ".debug_loclists", + ".debug_rnglists", + ".debug_str_offsets", + ".debug_addr" + }; + s1->dwlo = s1->nb_sections; dwarf_info_section = new_section(s1, ".debug_info", SHT_PROGBITS, shf); @@ -458,6 +471,8 @@ ST_FUNC void tcc_debug_new(TCCState *s1) new_section(s1, ".debug_line", SHT_PROGBITS, shf); dwarf_aranges_section = new_section(s1, ".debug_aranges", SHT_PROGBITS, shf); + for (i = 0; i < sizeof(debug)/sizeof(debug[0]); i++) + new_section(s1, debug[i], SHT_PROGBITS, 0)->sh_addralign = 1; shf |= SHF_MERGE | SHF_STRINGS; dwarf_str_section = new_section(s1, ".debug_str", SHT_PROGBITS, shf); @@ -487,7 +502,7 @@ ST_FUNC void tcc_debug_new(TCCState *s1) } /* put stab debug information */ -static void put_stabs(TCCState *s1, const char *str, int type, int other, int desc, +static int put_stabs(TCCState *s1, const char *str, int type, int other, int desc, unsigned long value) { Stab_Sym *sym; @@ -500,7 +515,7 @@ static void put_stabs(TCCState *s1, const char *str, int type, int other, int de && sym->n_value == value) { /* just update line_number in previous entry */ sym->n_desc = desc; - return; + return 0; } sym = section_ptr_add(stab_section, sizeof(Stab_Sym)); @@ -513,16 +528,17 @@ static void put_stabs(TCCState *s1, const char *str, int type, int other, int de sym->n_other = other; sym->n_desc = desc; sym->n_value = value; + return 1; } static void put_stabs_r(TCCState *s1, const char *str, int type, int other, int desc, unsigned long value, Section *sec, int sym_index) { - put_elf_reloc(symtab_section, stab_section, - stab_section->data_offset + 8, - sizeof ((Stab_Sym*)0)->n_value == PTR_SIZE ? R_DATA_PTR : R_DATA_32, - sym_index); - put_stabs(s1, str, type, other, desc, value); + if (put_stabs(s1, str, type, other, desc, value)) + put_elf_reloc(symtab_section, stab_section, + stab_section->data_offset - 4, + sizeof ((Stab_Sym*)0)->n_value == PTR_SIZE ? R_DATA_PTR : R_DATA_32, + sym_index); } static void put_stabn(TCCState *s1, int type, int other, int desc, int value) diff --git a/x86_64-link.c b/x86_64-link.c index c9e546c3..7456bdf0 100644 --- a/x86_64-link.c +++ b/x86_64-link.c @@ -221,6 +221,15 @@ ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, qrel->r_addend = (int)read32le(ptr) + val; qrel++; } + /* ignore relocation check for stab section */ + if ((stab_section == NULL || + addr < stab_section->sh_addr || + addr >= (stab_section->sh_addr + stab_section->data_offset)) && + ((type == R_X86_64_32 && + (unsigned long long)val > 4294967295ULL) || + (type == R_X86_64_32S && + ((long long)val < -2147483648LL || (long long)val > 2147483647LL)))) + tcc_error_noabort("internal error: relocation %d failed", type); add32le(ptr, val); break;