Add support for backtrace()

This requires adding .eh_frame and .eh_frame_hdr sections.

There are 3 new functions to setup the sections:
tcc_eh_frame_start: create cie in .eh_frame
tcc_debug_frame_end: add fde in .eh_frame for every function
tcc_eh_frame_hdr: create .eh_frame_hdr

The PT_GNU_EH_FRAME header is created.

The dwarf read functions are moved from tccrun.c to tcc.h

The backtrace() function is not supported on all targets.
windows, apple, bsd and arm are disabled.
arm uses its own sections .ARM.extab and .ARM.exidx.
This commit is contained in:
herman ten brugge 2024-11-09 08:04:45 +01:00
parent a21b5f1fd7
commit 322c4dc275
7 changed files with 388 additions and 53 deletions

View file

@ -218,7 +218,7 @@ ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr,
break;
}
}
write32le(ptr, val - addr);
add32le(ptr, val - addr);
return;
case R_AARCH64_MOVW_UABS_G0_NC:
write32le(ptr, ((read32le(ptr) & 0xffe0001f) |

View file

@ -352,8 +352,21 @@ ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr,
case R_RISCV_SUB6:
*ptr = (*ptr & ~0x3f) | ((*ptr - val) & 0x3f);
return;
case R_RISCV_32_PCREL:
if (s1->output_type & TCC_OUTPUT_DYN) {
/* DLL relocation */
esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;
if (esym_index) {
qrel->r_offset = rel->r_offset;
qrel->r_info = ELFW(R_INFO)(esym_index, R_RISCV_32_PCREL);
/* Use sign extension! */
qrel->r_addend = (int)read32le(ptr) + rel->r_addend;
qrel++;
break;
}
}
add32le(ptr, val - addr);
return;
case R_RISCV_COPY:
/* XXX */
return;

57
tcc.h
View file

@ -925,6 +925,10 @@ struct TCCState {
Section *dynsym;
/* got & plt handling */
Section *got, *plt;
/* exception handling */
Section *eh_frame_section;
Section *eh_frame_hdr_section;
unsigned long eh_start;
/* debug sections */
Section *stab_section;
Section *dwarf_info_section;
@ -1673,6 +1677,53 @@ static inline void write64le(unsigned char *p, uint64_t x) {
static inline void add64le(unsigned char *p, int64_t x) {
write64le(p, read64le(p) + x);
}
#define DWARF_MAX_128 ((8 * sizeof (int64_t) + 6) / 7)
#define dwarf_read_1(ln,end) \
((ln) < (end) ? *(ln)++ : 0)
#define dwarf_read_2(ln,end) \
((ln) + 1 < (end) ? (ln) += 2, read16le((ln) - 2) : 0)
#define dwarf_read_4(ln,end) \
((ln) + 3 < (end) ? (ln) += 4, read32le((ln) - 4) : 0)
#define dwarf_read_8(ln,end) \
((ln) + 7 < (end) ? (ln) += 8, read64le((ln) - 8) : 0)
static inline uint64_t
dwarf_read_uleb128(unsigned char **ln, unsigned char *end)
{
unsigned char *cp = *ln;
uint64_t retval = 0;
int i;
for (i = 0; i < DWARF_MAX_128; i++) {
uint64_t byte = dwarf_read_1(cp, end);
retval |= (byte & 0x7f) << (i * 7);
if ((byte & 0x80) == 0)
break;
}
*ln = cp;
return retval;
}
static inline int64_t
dwarf_read_sleb128(unsigned char **ln, unsigned char *end)
{
unsigned char *cp = *ln;
int64_t retval = 0;
int i;
for (i = 0; i < DWARF_MAX_128; i++) {
uint64_t byte = dwarf_read_1(cp, end);
retval |= (byte & 0x7f) << (i * 7);
if ((byte & 0x80) == 0) {
if ((byte & 0x40) && (i + 1) * 7 < 64)
retval |= -1LL << ((i + 1) * 7);
break;
}
}
*ln = cp;
return retval;
}
/* ------------ i386-gen.c ------------ */
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM
@ -1818,6 +1869,10 @@ ST_FUNC int gen_makedeps(TCCState *s, const char *target, const char *filename);
/* ------------ tccdbg.c ------------ */
ST_FUNC void tcc_eh_frame_start(TCCState *s1);
ST_FUNC void tcc_eh_frame_end(TCCState *s1);
ST_FUNC void tcc_eh_frame_hdr(TCCState *s1, int final);
ST_FUNC void tcc_debug_new(TCCState *s);
ST_FUNC void tcc_debug_start(TCCState *s1);
@ -1846,6 +1901,8 @@ ST_FUNC void tcc_tcov_reset_ind(TCCState *s1);
#define stab_section s1->stab_section
#define stabstr_section stab_section->link
#define tcov_section s1->tcov_section
#define eh_frame_section s1->eh_frame_section
#define eh_frame_hdr_section s1->eh_frame_hdr_section
#define dwarf_info_section s1->dwarf_info_section
#define dwarf_abbrev_section s1->dwarf_abbrev_section
#define dwarf_line_section s1->dwarf_line_section

300
tccdbg.c
View file

@ -71,7 +71,7 @@ static const struct {
{ VT_BOOL, 1, DW_ATE_boolean, "bool:t26=r26;0;255;" },
#if LONG_SIZE == 4
{ VT_VOID, 1, DW_ATE_unsigned_char, "void:t27=27" },
#else
#else
/* bitfields use these */
{ VT_LONG | VT_INT, 8, DW_ATE_signed, "long int:t27=r27;-9223372036854775808;9223372036854775807;" },
{ VT_LONG | VT_INT | VT_UNSIGNED, 8, DW_ATE_unsigned, "long unsigned int:t28=r28;0;01777777777777777777777;" },
@ -407,6 +407,8 @@ struct _tccdbg {
#define dwarf_info s1->dState->dwarf_info
#define tcov_data s1->dState->tcov_data
#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,
int desc, unsigned long value);
@ -611,7 +613,7 @@ static void dwarf_file(TCCState *s1)
}
if (i == dwarf_line.dir_size) {
dwarf_line.dir_size++;
dwarf_line.dir_table =
dwarf_line.dir_table =
(char **) tcc_realloc(dwarf_line.dir_table,
dwarf_line.dir_size *
sizeof (char *));
@ -710,6 +712,299 @@ static void dwarf_sleb128_op (TCCState *s1, long long value)
} while (more);
}
ST_FUNC void tcc_eh_frame_start(TCCState *s1)
{
#if !(defined _WIN32 || defined __APPLE__ || defined TCC_TARGET_ARM || \
defined TARGETOS_BSD)
eh_frame_section = new_section(s1, ".eh_frame", SHT_PROGBITS, SHF_ALLOC);
s1->eh_start = eh_frame_section->data_offset;
dwarf_data4(eh_frame_section, 0); // length
dwarf_data4(eh_frame_section, 0); // CIE ID
dwarf_data1(eh_frame_section, 1); // Version
dwarf_data1(eh_frame_section, 'z'); // Augmentation String
dwarf_data1(eh_frame_section, 'R');
dwarf_data1(eh_frame_section, 0);
#if defined TCC_TARGET_I386
dwarf_uleb128(eh_frame_section, 1); // code_alignment_factor
dwarf_sleb128(eh_frame_section, -4); // data_alignment_factor
dwarf_uleb128(eh_frame_section, 8); // return address column
dwarf_uleb128(eh_frame_section, 1); // Augmentation len
dwarf_data1(eh_frame_section, FDE_ENCODING);
dwarf_data1(eh_frame_section, DW_CFA_def_cfa);
dwarf_uleb128(eh_frame_section, 4); // r4 (esp)
dwarf_uleb128(eh_frame_section, 4); // ofs 4
dwarf_data1(eh_frame_section, DW_CFA_offset + 8); // r8 (eip)
dwarf_uleb128(eh_frame_section, 1); // cfa-4
#elif defined TCC_TARGET_X86_64
dwarf_uleb128(eh_frame_section, 1); // code_alignment_factor
dwarf_sleb128(eh_frame_section, -8); // data_alignment_factor
dwarf_uleb128(eh_frame_section, 16); // return address column
dwarf_uleb128(eh_frame_section, 1); // Augmentation len
dwarf_data1(eh_frame_section, FDE_ENCODING);
dwarf_data1(eh_frame_section, DW_CFA_def_cfa);
dwarf_uleb128(eh_frame_section, 7); // r7 (rsp)
dwarf_uleb128(eh_frame_section, 8); // ofs 8
dwarf_data1(eh_frame_section, DW_CFA_offset + 16); // r16 (rip)
dwarf_uleb128(eh_frame_section, 1); // cfa-8
#elif defined TCC_TARGET_ARM
/* TODO: arm must be compiled with: -funwind-tables */
/* arm also uses .ARM.extab and .ARM.exidx sections */
dwarf_uleb128(eh_frame_section, 2); // code_alignment_factor
dwarf_sleb128(eh_frame_section, -4); // data_alignment_factor
dwarf_uleb128(eh_frame_section, 14); // return address column
dwarf_uleb128(eh_frame_section, 1); // Augmentation len
dwarf_data1(eh_frame_section, FDE_ENCODING);
dwarf_data1(eh_frame_section, DW_CFA_def_cfa);
dwarf_uleb128(eh_frame_section, 13); // r13 (sp)
dwarf_uleb128(eh_frame_section, 0); // ofs 0
#elif defined TCC_TARGET_ARM64
dwarf_uleb128(eh_frame_section, 4); // code_alignment_factor
dwarf_sleb128(eh_frame_section, -8); // data_alignment_factor
dwarf_uleb128(eh_frame_section, 30); // return address column
dwarf_uleb128(eh_frame_section, 1); // Augmentation len
dwarf_data1(eh_frame_section, FDE_ENCODING);
dwarf_data1(eh_frame_section, DW_CFA_def_cfa);
dwarf_uleb128(eh_frame_section, 31); // x31 (sp)
dwarf_uleb128(eh_frame_section, 0); // ofs 0
#elif defined TCC_TARGET_RISCV64
eh_frame_section->data[s1->eh_start + 8] = 3; // version = 3
dwarf_uleb128(eh_frame_section, 1); // code_alignment_factor
dwarf_sleb128(eh_frame_section, -4); // data_alignment_factor
dwarf_uleb128(eh_frame_section, 1); // return address column
dwarf_uleb128(eh_frame_section, 1); // Augmentation len
dwarf_data1(eh_frame_section, FDE_ENCODING);
dwarf_data1(eh_frame_section, DW_CFA_def_cfa);
dwarf_uleb128(eh_frame_section, 2); // r2 (sp)
dwarf_uleb128(eh_frame_section, 0); // ofs 0
#endif
while ((eh_frame_section->data_offset - s1->eh_start) & 3)
dwarf_data1(eh_frame_section, DW_CFA_nop);
write32le(eh_frame_section->data + s1->eh_start, // length
eh_frame_section->data_offset - s1->eh_start - 4);
#endif
}
static void tcc_debug_frame_end(TCCState *s1, int size)
{
int eh_section_sym;
unsigned long fde_start;
if (!eh_frame_section)
return;
eh_section_sym = dwarf_get_section_sym(text_section);
fde_start = eh_frame_section->data_offset;
dwarf_data4(eh_frame_section, 0); // length
dwarf_data4(eh_frame_section,
fde_start - s1->eh_start + 4); // CIE Pointer
#if TCC_TARGET_I386
dwarf_reloc(eh_frame_section, eh_section_sym, R_386_PC32);
#elif defined TCC_TARGET_X86_64
dwarf_reloc(eh_frame_section, eh_section_sym, R_X86_64_PC32);
#elif defined TCC_TARGET_ARM
dwarf_reloc(eh_frame_section, eh_section_sym, R_ARM_REL32);
#elif defined TCC_TARGET_ARM64
dwarf_reloc(eh_frame_section, eh_section_sym, R_AARCH64_PREL32);
#elif defined TCC_TARGET_RISCV64
dwarf_reloc(eh_frame_section, eh_section_sym, R_RISCV_32_PCREL);
#endif
dwarf_data4(eh_frame_section, func_ind); // PC Begin
dwarf_data4(eh_frame_section, size); // PC Range
dwarf_data1(eh_frame_section, 0); // Augmentation Length
#if TCC_TARGET_I386
dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 1);
dwarf_data1(eh_frame_section, DW_CFA_def_cfa_offset);
dwarf_uleb128(eh_frame_section, 8);
dwarf_data1(eh_frame_section, DW_CFA_offset + 5); // r5 (ebp)
dwarf_uleb128(eh_frame_section, 2); // cfa-8
dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 2);
dwarf_data1(eh_frame_section, DW_CFA_def_cfa_register);
dwarf_uleb128(eh_frame_section, 5); // r5 (ebp)
dwarf_data1(eh_frame_section, DW_CFA_advance_loc4);
dwarf_data4(eh_frame_section, size - 5);
dwarf_data1(eh_frame_section, DW_CFA_restore + 5); // r5 (ebp)
dwarf_data1(eh_frame_section, DW_CFA_def_cfa);
dwarf_uleb128(eh_frame_section, 4); // r4 (esp)
dwarf_uleb128(eh_frame_section, 4); // ofs 4
#elif defined TCC_TARGET_X86_64
dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 1);
dwarf_data1(eh_frame_section, DW_CFA_def_cfa_offset);
dwarf_uleb128(eh_frame_section, 16);
dwarf_data1(eh_frame_section, DW_CFA_offset + 6); // r6 (rbp)
dwarf_uleb128(eh_frame_section, 2); // cfa-16
dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 3);
dwarf_data1(eh_frame_section, DW_CFA_def_cfa_register);
dwarf_uleb128(eh_frame_section, 6); // r6 (rbp)
dwarf_data1(eh_frame_section, DW_CFA_advance_loc4);
dwarf_data4(eh_frame_section, size - 5);
dwarf_data1(eh_frame_section, DW_CFA_def_cfa);
dwarf_uleb128(eh_frame_section, 7); // r7 (rsp)
dwarf_uleb128(eh_frame_section, 8); // ofs 8
#elif defined TCC_TARGET_ARM
/* TODO */
dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 2);
dwarf_data1(eh_frame_section, DW_CFA_def_cfa_offset);
dwarf_uleb128(eh_frame_section, 8);
dwarf_data1(eh_frame_section, DW_CFA_offset + 14); // r14 (lr)
dwarf_uleb128(eh_frame_section, 1);
dwarf_data1(eh_frame_section, DW_CFA_offset + 11); // r11 (fp)
dwarf_uleb128(eh_frame_section, 2);
dwarf_data1(eh_frame_section, DW_CFA_advance_loc4);
dwarf_data4(eh_frame_section, size / 2 - 5);
dwarf_data1(eh_frame_section, DW_CFA_def_cfa_register);
dwarf_uleb128(eh_frame_section, 11); // r11 (fp)
#elif defined TCC_TARGET_ARM64
dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 1);
dwarf_data1(eh_frame_section, DW_CFA_def_cfa_offset);
dwarf_uleb128(eh_frame_section, 224);
dwarf_data1(eh_frame_section, DW_CFA_offset + 29); // x29 (fp)
dwarf_uleb128(eh_frame_section, 28); // cfa-224
dwarf_data1(eh_frame_section, DW_CFA_offset + 30); // x30 (lr)
dwarf_uleb128(eh_frame_section, 27); // cfa-216
dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 3);
dwarf_data1(eh_frame_section, DW_CFA_def_cfa_offset);
dwarf_uleb128(eh_frame_section, 224 + ((-loc + 15) & ~15));
dwarf_data1(eh_frame_section, DW_CFA_advance_loc4);
dwarf_data4(eh_frame_section, size / 4 - 5);
dwarf_data1(eh_frame_section, DW_CFA_restore + 30); // x30 (lr)
dwarf_data1(eh_frame_section, DW_CFA_restore + 29); // x29 (fp)
dwarf_data1(eh_frame_section, DW_CFA_def_cfa_offset);
dwarf_uleb128(eh_frame_section, 0);
#elif defined TCC_TARGET_RISCV64
dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 4);
dwarf_data1(eh_frame_section, DW_CFA_def_cfa_offset);
dwarf_uleb128(eh_frame_section, 16); // ofs 16
dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 8);
dwarf_data1(eh_frame_section, DW_CFA_offset + 1); // r1 (ra, lr)
dwarf_uleb128(eh_frame_section, 2); // cfa-8
dwarf_data1(eh_frame_section, DW_CFA_offset + 8); // r8 (s0, fp)
dwarf_uleb128(eh_frame_section, 4); // cfa-16
dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 8);
dwarf_data1(eh_frame_section, DW_CFA_def_cfa);
dwarf_uleb128(eh_frame_section, 8); // r8 (s0, fp)
dwarf_uleb128(eh_frame_section, 0); // ofs 0
dwarf_data1(eh_frame_section, DW_CFA_advance_loc4);
while (size >= 4 &&
read32le(cur_text_section->data + func_ind + size - 4) != 0x00008067)
size -= 4;
dwarf_data4(eh_frame_section, size - 36);
dwarf_data1(eh_frame_section, DW_CFA_def_cfa);
dwarf_uleb128(eh_frame_section, 2); // r2 (r2, sp)
dwarf_uleb128(eh_frame_section, 16); // ofs 16
dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 4);
dwarf_data1(eh_frame_section, DW_CFA_restore + 1); // r1 (lr)
dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 4);
dwarf_data1(eh_frame_section, DW_CFA_restore + 8); // r8 (s0, fp)
dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 4);
dwarf_data1(eh_frame_section, DW_CFA_def_cfa_offset);
dwarf_uleb128(eh_frame_section, 0); // ofs 0
#endif
while ((eh_frame_section->data_offset - fde_start) & 3)
dwarf_data1(eh_frame_section, DW_CFA_nop);
write32le(eh_frame_section->data + fde_start, // length
eh_frame_section->data_offset - fde_start - 4);
}
ST_FUNC void tcc_eh_frame_end(TCCState *s1)
{
if (!eh_frame_section)
return;
dwarf_data4(eh_frame_section, 0);
}
struct eh_search_table {
uint32_t pc_offset;
uint32_t fde_offset;
};
static int sort_eh_table(const void *a, const void *b)
{
uint32_t pc1 = ((const struct eh_search_table *)a)->pc_offset;
uint32_t pc2 = ((const struct eh_search_table *)b)->pc_offset;
return pc1 < pc2 ? -1 : pc1 > pc2 ? 1 : 0;
}
ST_FUNC void tcc_eh_frame_hdr(TCCState *s1, int final)
{
int count = 0, offset;
unsigned long count_offset, tab_offset;
unsigned char *ln, *end;
unsigned int last_cie_offset = 0xffffffff;
if (!eh_frame_section || !eh_frame_section->data_offset)
return;
if (final && !eh_frame_hdr_section)
return;
if (final == 0)
eh_frame_hdr_section =
new_section(s1, ".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC);
eh_frame_hdr_section->data_offset = 0;
dwarf_data1(eh_frame_hdr_section, 1); // Version
// Pointer Encoding Format
dwarf_data1(eh_frame_hdr_section, DW_EH_PE_sdata4 | DW_EH_PE_pcrel);
// Count Encoding Format
dwarf_data1(eh_frame_hdr_section, DW_EH_PE_udata4 | DW_EH_PE_absptr);
// Table Encoding Format
dwarf_data1(eh_frame_hdr_section, DW_EH_PE_sdata4 | DW_EH_PE_datarel);
offset = eh_frame_section->sh_addr -
eh_frame_hdr_section->sh_addr -
eh_frame_hdr_section->data_offset;
dwarf_data4(eh_frame_hdr_section, offset); // eh_frame_ptr
// Count
count_offset = eh_frame_hdr_section->data_offset;
dwarf_data4(eh_frame_hdr_section, 0);
tab_offset = eh_frame_hdr_section->data_offset;
ln = eh_frame_section->data;
end = eh_frame_section->data + eh_frame_section->data_offset;
while (ln < end) {
unsigned char *fde = ln, *rd = ln;
unsigned int cie_offset, version, length = dwarf_read_4(rd, end);
unsigned int pc_offset, fde_offset;
if (length == 0)
goto next;
cie_offset = dwarf_read_4(rd, end);
if (cie_offset == 0)
goto next;
if (cie_offset != last_cie_offset) {
unsigned char *cie = rd - cie_offset + 4;
if (cie < eh_frame_section->data)
goto next;
version = dwarf_read_1(cie, end);
if ((version == 1 || version == 3) &&
dwarf_read_1(cie, end) == 'z' && // Augmentation String
dwarf_read_1(cie, end) == 'R' &&
dwarf_read_1(cie, end) == 0) {
dwarf_read_uleb128(&cie, end); // code_alignment_factor
dwarf_read_sleb128(&cie, end); // data_alignment_factor
dwarf_read_1(cie, end); // return address column
if (dwarf_read_uleb128(&cie, end) == 1 &&
dwarf_read_1(cie, end) == FDE_ENCODING) {
last_cie_offset = cie_offset;
}
else
goto next;
}
else
goto next;
}
count++;
fde_offset = eh_frame_section->sh_addr +
(fde - eh_frame_section->data) -
eh_frame_hdr_section->sh_addr;
pc_offset = dwarf_read_4(rd, end) + fde_offset + 8;
dwarf_data4(eh_frame_hdr_section, pc_offset);
dwarf_data4(eh_frame_hdr_section, fde_offset);
next:
ln += length + 4;
}
add32le(eh_frame_hdr_section->data + count_offset, count);
qsort(eh_frame_hdr_section->data + tab_offset, count,
sizeof(struct eh_search_table), sort_eh_table);
}
/* start of translation unit info */
ST_FUNC void tcc_debug_start(TCCState *s1)
{
@ -1875,6 +2170,7 @@ ST_FUNC void tcc_debug_funcend(TCCState *s1, int size)
/* lldb does not like function end and next function start at same pc */
int min_instr_len;
tcc_debug_frame_end(s1, size);
if (!s1->do_debug)
return;
min_instr_len = dwarf_line.last_pc == ind ? 0 : DWARF_MIN_INSTR_LEN;

View file

@ -95,6 +95,8 @@ ST_FUNC void tccelf_new(TCCState *s)
tcc_debug_new(s);
}
tcc_eh_frame_start(s);
#ifdef CONFIG_TCC_BCHECK
if (s->do_bounds_check) {
/* if bound checking, then add corresponding sections */
@ -2271,6 +2273,8 @@ static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d)
++phnum;
if (d->dynamic)
++phnum;
if (eh_frame_hdr_section)
++phnum;
if (d->roinf)
++phnum;
d->phnum = phnum;
@ -2391,6 +2395,12 @@ static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d)
fill_phdr(++ph, PT_NOTE, d->note);
if (d->dynamic)
fill_phdr(++ph, PT_DYNAMIC, d->dynamic)->p_flags |= PF_W;
if (eh_frame_hdr_section) {
add32le(eh_frame_hdr_section->data + 4,
eh_frame_section->sh_offset -
eh_frame_hdr_section->sh_offset - 4);
fill_phdr(++ph, PT_GNU_EH_FRAME, eh_frame_hdr_section);
}
if (d->roinf)
fill_phdr(++ph, PT_GNU_RELRO, d->roinf)->p_flags |= PF_W;
if (d->interp)
@ -2859,6 +2869,10 @@ static int elf_output_file(TCCState *s1, const char *filename)
/* shared library case: simply export all global symbols */
export_global_syms(s1);
}
/* fill with initial data */
tcc_eh_frame_hdr(s1, 0);
dyninf.gnu_hash = create_gnu_hash(s1);
} else {
build_got_entries(s1, 0);
@ -2943,6 +2957,9 @@ static int elf_output_file(TCCState *s1, const char *filename)
reorder_sections(s1, sec_order);
/* fill with final data */
tcc_eh_frame_hdr(s1, 1);
/* Create the ELF file with name 'filename' */
ret = tcc_write_elf_file(s1, filename, dyninf.phnum, dyninf.phdr);
the_end:

View file

@ -402,6 +402,7 @@ ST_FUNC int tccgen_compile(TCCState *s1)
gen_inline_functions(s1);
check_vstack();
/* end of translation unit info */
tcc_eh_frame_end(s1);
tcc_debug_end(s1);
tcc_tcov_end(s1);
return 0;

View file

@ -760,19 +760,9 @@ found:
/* ------------------------------------------------------------- */
/* rt_printline - dwarf version */
#define MAX_128 ((8 * sizeof (long long) + 6) / 7)
#define DIR_TABLE_SIZE (64)
#define FILE_TABLE_SIZE (512)
#define dwarf_read_1(ln,end) \
((ln) < (end) ? *(ln)++ : 0)
#define dwarf_read_2(ln,end) \
((ln) + 2 < (end) ? (ln) += 2, read16le((ln) - 2) : 0)
#define dwarf_read_4(ln,end) \
((ln) + 4 < (end) ? (ln) += 4, read32le((ln) - 4) : 0)
#define dwarf_read_8(ln,end) \
((ln) + 8 < (end) ? (ln) += 8, read64le((ln) - 8) : 0)
#define dwarf_ignore_type(ln, end) /* timestamp/size/md5/... */ \
switch (entry_format[j].form) { \
case DW_FORM_data1: (ln) += 1; break; \
@ -784,45 +774,6 @@ found:
default: goto next_line; \
}
static unsigned long long
dwarf_read_uleb128(unsigned char **ln, unsigned char *end)
{
unsigned char *cp = *ln;
unsigned long long retval = 0;
int i;
for (i = 0; i < MAX_128; i++) {
unsigned long long byte = dwarf_read_1(cp, end);
retval |= (byte & 0x7f) << (i * 7);
if ((byte & 0x80) == 0)
break;
}
*ln = cp;
return retval;
}
static long long
dwarf_read_sleb128(unsigned char **ln, unsigned char *end)
{
unsigned char *cp = *ln;
long long retval = 0;
int i;
for (i = 0; i < MAX_128; i++) {
unsigned long long byte = dwarf_read_1(cp, end);
retval |= (byte & 0x7f) << (i * 7);
if ((byte & 0x80) == 0) {
if ((byte & 0x40) && (i + 1) * 7 < 64)
retval |= -1LL << ((i + 1) * 7);
break;
}
}
*ln = cp;
return retval;
}
static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc, bt_info *bi)
{
unsigned char *ln;