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.
This commit is contained in:
herman ten brugge
2025-12-23 06:46:22 +01:00
parent 64cf0b816b
commit 5a370d8a6b
3 changed files with 34 additions and 9 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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;