diff --git a/arm64-link.c b/arm64-link.c index 9cd8989b..cfdd95ea 100644 --- a/arm64-link.c +++ b/arm64-link.c @@ -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) | diff --git a/riscv64-link.c b/riscv64-link.c index f10e7c03..5cdbe2f7 100644 --- a/riscv64-link.c +++ b/riscv64-link.c @@ -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; diff --git a/tcc.h b/tcc.h index 7bae6aff..ef02e4d2 100644 --- a/tcc.h +++ b/tcc.h @@ -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 diff --git a/tccdbg.c b/tccdbg.c index 15d54b47..4176fd63 100644 --- a/tccdbg.c +++ b/tccdbg.c @@ -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; diff --git a/tccelf.c b/tccelf.c index 498cd278..50f365eb 100644 --- a/tccelf.c +++ b/tccelf.c @@ -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: diff --git a/tccgen.c b/tccgen.c index 1cf93304..9cb699bb 100644 --- a/tccgen.c +++ b/tccgen.c @@ -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; diff --git a/tccrun.c b/tccrun.c index b0cb4dba..61cd4717 100644 --- a/tccrun.c +++ b/tccrun.c @@ -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;