History

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.

herman ten brugge committed 2 years ago

Commit 322c4dc1 parent a21b5f17 files · +388 −53Browse files

Unified · Split

7 files
  1. arm64-link.c +1 −1
  2. riscv64-link.c +14 −1
  3. tcc.h +57 −0
  4. tccdbg.c +298 −2
  5. tccelf.c +17 −0
  6. tccgen.c +1 −0
  7. tccrun.c +0 −49
arm64-link.c+1−1
@@ -218,7 +218,7 @@ ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 217 unmodified lines
218218 break;
219219 }
220220 }
221− write32le(ptr, val - addr);
221+ add32le(ptr, val - addr);
222222 return;
223223 case R_AARCH64_MOVW_UABS_G0_NC:
224224 write32le(ptr, ((read32le(ptr) & 0xffe0001f) |
riscv64-link.c+14−1
@@ -352,8 +352,21 @@ ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, · 351 unmodified lines
352352 case R_RISCV_SUB6:
353353 *ptr = (*ptr & ~0x3f) | ((*ptr - val) & 0x3f);
354354 return;
355−
356355 case R_RISCV_32_PCREL:
356+ if (s1->output_type & TCC_OUTPUT_DYN) {
357+ /* DLL relocation */
358+ esym_index = get_sym_attr(s1, sym_index, 0)->dyn_index;
359+ if (esym_index) {
360+ qrel->r_offset = rel->r_offset;
361+ qrel->r_info = ELFW(R_INFO)(esym_index, R_RISCV_32_PCREL);
362+ /* Use sign extension! */
363+ qrel->r_addend = (int)read32le(ptr) + rel->r_addend;
364+ qrel++;
365+ break;
366+ }
367+ }
368+ add32le(ptr, val - addr);
369+ return;
357370 case R_RISCV_COPY:
358371 /* XXX */
359372 return;
tcc.h+57−0
@@ -925,6 +925,10 @@ struct TCCState { · 924 unmodified lines
925925 Section *dynsym;
926926 /* got & plt handling */
927927 Section *got, *plt;
928+ /* exception handling */
929+ Section *eh_frame_section;
930+ Section *eh_frame_hdr_section;
931+ unsigned long eh_start;
928932 /* debug sections */
929933 Section *stab_section;
930934 Section *dwarf_info_section;
@@ -1673,6 +1677,53 @@ static inline void write64le(unsigned char *p, uint64_t x) { · 742 unmodified lines
16731677 static inline void add64le(unsigned char *p, int64_t x) {
16741678 write64le(p, read64le(p) + x);
16751679 }
1680+#define DWARF_MAX_128 ((8 * sizeof (int64_t) + 6) / 7)
1681+#define dwarf_read_1(ln,end) \
1682+ ((ln) < (end) ? *(ln)++ : 0)
1683+#define dwarf_read_2(ln,end) \
1684+ ((ln) + 1 < (end) ? (ln) += 2, read16le((ln) - 2) : 0)
1685+#define dwarf_read_4(ln,end) \
1686+ ((ln) + 3 < (end) ? (ln) += 4, read32le((ln) - 4) : 0)
1687+#define dwarf_read_8(ln,end) \
1688+ ((ln) + 7 < (end) ? (ln) += 8, read64le((ln) - 8) : 0)
1689+static inline uint64_t
1690+dwarf_read_uleb128(unsigned char **ln, unsigned char *end)
1691+{
1692+ unsigned char *cp = *ln;
1693+ uint64_t retval = 0;
1694+ int i;
1695+
1696+ for (i = 0; i < DWARF_MAX_128; i++) {
1697+ uint64_t byte = dwarf_read_1(cp, end);
1698+
1699+ retval |= (byte & 0x7f) << (i * 7);
1700+ if ((byte & 0x80) == 0)
1701+ break;
1702+ }
1703+ *ln = cp;
1704+ return retval;
1705+}
1706+static inline int64_t
1707+dwarf_read_sleb128(unsigned char **ln, unsigned char *end)
1708+{
1709+ unsigned char *cp = *ln;
1710+ int64_t retval = 0;
1711+ int i;
1712+
1713+ for (i = 0; i < DWARF_MAX_128; i++) {
1714+ uint64_t byte = dwarf_read_1(cp, end);
1715+
1716+ retval |= (byte & 0x7f) << (i * 7);
1717+ if ((byte & 0x80) == 0) {
1718+ if ((byte & 0x40) && (i + 1) * 7 < 64)
1719+ retval |= -1LL << ((i + 1) * 7);
1720+ break;
1721+ }
1722+ }
1723+ *ln = cp;
1724+ return retval;
1725+}
1726+
16761727
16771728 /* ------------ i386-gen.c ------------ */
16781729 #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); · 139 unmodified lines
18181869
18191870 /* ------------ tccdbg.c ------------ */
18201871
1872+ST_FUNC void tcc_eh_frame_start(TCCState *s1);
1873+ST_FUNC void tcc_eh_frame_end(TCCState *s1);
1874+ST_FUNC void tcc_eh_frame_hdr(TCCState *s1, int final);
1875+
18211876 ST_FUNC void tcc_debug_new(TCCState *s);
18221877
18231878 ST_FUNC void tcc_debug_start(TCCState *s1);
@@ -1846,6 +1901,8 @@ ST_FUNC void tcc_tcov_reset_ind(TCCState *s1); · 22 unmodified lines
18461901 #define stab_section s1->stab_section
18471902 #define stabstr_section stab_section->link
18481903 #define tcov_section s1->tcov_section
1904+#define eh_frame_section s1->eh_frame_section
1905+#define eh_frame_hdr_section s1->eh_frame_hdr_section
18491906 #define dwarf_info_section s1->dwarf_info_section
18501907 #define dwarf_abbrev_section s1->dwarf_abbrev_section
18511908 #define dwarf_line_section s1->dwarf_line_section
tccdbg.c+298−2
@@ -71,7 +71,7 @@ static const struct { · 70 unmodified lines
7171 { VT_BOOL, 1, DW_ATE_boolean, "bool:t26=r26;0;255;" },
7272 #if LONG_SIZE == 4
7373 { VT_VOID, 1, DW_ATE_unsigned_char, "void:t27=27" },
74−#else
74+#else
7575 /* bitfields use these */
7676 { VT_LONG | VT_INT, 8, DW_ATE_signed, "long int:t27=r27;-9223372036854775808;9223372036854775807;" },
7777 { VT_LONG | VT_INT | VT_UNSIGNED, 8, DW_ATE_unsigned, "long unsigned int:t28=r28;0;01777777777777777777777;" },
@@ -407,6 +407,8 @@ struct _tccdbg { · 329 unmodified lines
407407 #define dwarf_info s1->dState->dwarf_info
408408 #define tcov_data s1->dState->tcov_data
409409
410+#define FDE_ENCODING (DW_EH_PE_udata4 | DW_EH_PE_signed | DW_EH_PE_pcrel)
411+
410412 /* ------------------------------------------------------------------------- */
411413 static void put_stabs(TCCState *s1, const char *str, int type, int other,
412414 int desc, unsigned long value);
@@ -611,7 +613,7 @@ static void dwarf_file(TCCState *s1) · 198 unmodified lines
611613 }
612614 if (i == dwarf_line.dir_size) {
613615 dwarf_line.dir_size++;
614− dwarf_line.dir_table =
616+ dwarf_line.dir_table =
615617 (char **) tcc_realloc(dwarf_line.dir_table,
616618 dwarf_line.dir_size *
617619 sizeof (char *));
@@ -710,6 +712,299 @@ static void dwarf_sleb128_op (TCCState *s1, long long value) · 92 unmodified lines
710712 } while (more);
711713 }
712714
715+ST_FUNC void tcc_eh_frame_start(TCCState *s1)
716+{
717+#if !(defined _WIN32 || defined __APPLE__ || defined TCC_TARGET_ARM || \
718+ defined TARGETOS_BSD)
719+ eh_frame_section = new_section(s1, ".eh_frame", SHT_PROGBITS, SHF_ALLOC);
720+
721+ s1->eh_start = eh_frame_section->data_offset;
722+ dwarf_data4(eh_frame_section, 0); // length
723+ dwarf_data4(eh_frame_section, 0); // CIE ID
724+ dwarf_data1(eh_frame_section, 1); // Version
725+ dwarf_data1(eh_frame_section, 'z'); // Augmentation String
726+ dwarf_data1(eh_frame_section, 'R');
727+ dwarf_data1(eh_frame_section, 0);
728+#if defined TCC_TARGET_I386
729+ dwarf_uleb128(eh_frame_section, 1); // code_alignment_factor
730+ dwarf_sleb128(eh_frame_section, -4); // data_alignment_factor
731+ dwarf_uleb128(eh_frame_section, 8); // return address column
732+ dwarf_uleb128(eh_frame_section, 1); // Augmentation len
733+ dwarf_data1(eh_frame_section, FDE_ENCODING);
734+ dwarf_data1(eh_frame_section, DW_CFA_def_cfa);
735+ dwarf_uleb128(eh_frame_section, 4); // r4 (esp)
736+ dwarf_uleb128(eh_frame_section, 4); // ofs 4
737+ dwarf_data1(eh_frame_section, DW_CFA_offset + 8); // r8 (eip)
738+ dwarf_uleb128(eh_frame_section, 1); // cfa-4
739+#elif defined TCC_TARGET_X86_64
740+ dwarf_uleb128(eh_frame_section, 1); // code_alignment_factor
741+ dwarf_sleb128(eh_frame_section, -8); // data_alignment_factor
742+ dwarf_uleb128(eh_frame_section, 16); // return address column
743+ dwarf_uleb128(eh_frame_section, 1); // Augmentation len
744+ dwarf_data1(eh_frame_section, FDE_ENCODING);
745+ dwarf_data1(eh_frame_section, DW_CFA_def_cfa);
746+ dwarf_uleb128(eh_frame_section, 7); // r7 (rsp)
747+ dwarf_uleb128(eh_frame_section, 8); // ofs 8
748+ dwarf_data1(eh_frame_section, DW_CFA_offset + 16); // r16 (rip)
749+ dwarf_uleb128(eh_frame_section, 1); // cfa-8
750+#elif defined TCC_TARGET_ARM
751+ /* TODO: arm must be compiled with: -funwind-tables */
752+ /* arm also uses .ARM.extab and .ARM.exidx sections */
753+ dwarf_uleb128(eh_frame_section, 2); // code_alignment_factor
754+ dwarf_sleb128(eh_frame_section, -4); // data_alignment_factor
755+ dwarf_uleb128(eh_frame_section, 14); // return address column
756+ dwarf_uleb128(eh_frame_section, 1); // Augmentation len
757+ dwarf_data1(eh_frame_section, FDE_ENCODING);
758+ dwarf_data1(eh_frame_section, DW_CFA_def_cfa);
759+ dwarf_uleb128(eh_frame_section, 13); // r13 (sp)
760+ dwarf_uleb128(eh_frame_section, 0); // ofs 0
761+#elif defined TCC_TARGET_ARM64
762+ dwarf_uleb128(eh_frame_section, 4); // code_alignment_factor
763+ dwarf_sleb128(eh_frame_section, -8); // data_alignment_factor
764+ dwarf_uleb128(eh_frame_section, 30); // return address column
765+ dwarf_uleb128(eh_frame_section, 1); // Augmentation len
766+ dwarf_data1(eh_frame_section, FDE_ENCODING);
767+ dwarf_data1(eh_frame_section, DW_CFA_def_cfa);
768+ dwarf_uleb128(eh_frame_section, 31); // x31 (sp)
769+ dwarf_uleb128(eh_frame_section, 0); // ofs 0
770+#elif defined TCC_TARGET_RISCV64
771+ eh_frame_section->data[s1->eh_start + 8] = 3; // version = 3
772+ dwarf_uleb128(eh_frame_section, 1); // code_alignment_factor
773+ dwarf_sleb128(eh_frame_section, -4); // data_alignment_factor
774+ dwarf_uleb128(eh_frame_section, 1); // return address column
775+ dwarf_uleb128(eh_frame_section, 1); // Augmentation len
776+ dwarf_data1(eh_frame_section, FDE_ENCODING);
777+ dwarf_data1(eh_frame_section, DW_CFA_def_cfa);
778+ dwarf_uleb128(eh_frame_section, 2); // r2 (sp)
779+ dwarf_uleb128(eh_frame_section, 0); // ofs 0
780+#endif
781+ while ((eh_frame_section->data_offset - s1->eh_start) & 3)
782+ dwarf_data1(eh_frame_section, DW_CFA_nop);
783+ write32le(eh_frame_section->data + s1->eh_start, // length
784+ eh_frame_section->data_offset - s1->eh_start - 4);
785+#endif
786+}
787+
788+static void tcc_debug_frame_end(TCCState *s1, int size)
789+{
790+ int eh_section_sym;
791+ unsigned long fde_start;
792+
793+ if (!eh_frame_section)
794+ return;
795+ eh_section_sym = dwarf_get_section_sym(text_section);
796+ fde_start = eh_frame_section->data_offset;
797+ dwarf_data4(eh_frame_section, 0); // length
798+ dwarf_data4(eh_frame_section,
799+ fde_start - s1->eh_start + 4); // CIE Pointer
800+#if TCC_TARGET_I386
801+ dwarf_reloc(eh_frame_section, eh_section_sym, R_386_PC32);
802+#elif defined TCC_TARGET_X86_64
803+ dwarf_reloc(eh_frame_section, eh_section_sym, R_X86_64_PC32);
804+#elif defined TCC_TARGET_ARM
805+ dwarf_reloc(eh_frame_section, eh_section_sym, R_ARM_REL32);
806+#elif defined TCC_TARGET_ARM64
807+ dwarf_reloc(eh_frame_section, eh_section_sym, R_AARCH64_PREL32);
808+#elif defined TCC_TARGET_RISCV64
809+ dwarf_reloc(eh_frame_section, eh_section_sym, R_RISCV_32_PCREL);
810+#endif
811+ dwarf_data4(eh_frame_section, func_ind); // PC Begin
812+ dwarf_data4(eh_frame_section, size); // PC Range
813+ dwarf_data1(eh_frame_section, 0); // Augmentation Length
814+#if TCC_TARGET_I386
815+ dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 1);
816+ dwarf_data1(eh_frame_section, DW_CFA_def_cfa_offset);
817+ dwarf_uleb128(eh_frame_section, 8);
818+ dwarf_data1(eh_frame_section, DW_CFA_offset + 5); // r5 (ebp)
819+ dwarf_uleb128(eh_frame_section, 2); // cfa-8
820+ dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 2);
821+ dwarf_data1(eh_frame_section, DW_CFA_def_cfa_register);
822+ dwarf_uleb128(eh_frame_section, 5); // r5 (ebp)
823+ dwarf_data1(eh_frame_section, DW_CFA_advance_loc4);
824+ dwarf_data4(eh_frame_section, size - 5);
825+ dwarf_data1(eh_frame_section, DW_CFA_restore + 5); // r5 (ebp)
826+ dwarf_data1(eh_frame_section, DW_CFA_def_cfa);
827+ dwarf_uleb128(eh_frame_section, 4); // r4 (esp)
828+ dwarf_uleb128(eh_frame_section, 4); // ofs 4
829+#elif defined TCC_TARGET_X86_64
830+ dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 1);
831+ dwarf_data1(eh_frame_section, DW_CFA_def_cfa_offset);
832+ dwarf_uleb128(eh_frame_section, 16);
833+ dwarf_data1(eh_frame_section, DW_CFA_offset + 6); // r6 (rbp)
834+ dwarf_uleb128(eh_frame_section, 2); // cfa-16
835+ dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 3);
836+ dwarf_data1(eh_frame_section, DW_CFA_def_cfa_register);
837+ dwarf_uleb128(eh_frame_section, 6); // r6 (rbp)
838+ dwarf_data1(eh_frame_section, DW_CFA_advance_loc4);
839+ dwarf_data4(eh_frame_section, size - 5);
840+ dwarf_data1(eh_frame_section, DW_CFA_def_cfa);
841+ dwarf_uleb128(eh_frame_section, 7); // r7 (rsp)
842+ dwarf_uleb128(eh_frame_section, 8); // ofs 8
843+#elif defined TCC_TARGET_ARM
844+ /* TODO */
845+ dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 2);
846+ dwarf_data1(eh_frame_section, DW_CFA_def_cfa_offset);
847+ dwarf_uleb128(eh_frame_section, 8);
848+ dwarf_data1(eh_frame_section, DW_CFA_offset + 14); // r14 (lr)
849+ dwarf_uleb128(eh_frame_section, 1);
850+ dwarf_data1(eh_frame_section, DW_CFA_offset + 11); // r11 (fp)
851+ dwarf_uleb128(eh_frame_section, 2);
852+ dwarf_data1(eh_frame_section, DW_CFA_advance_loc4);
853+ dwarf_data4(eh_frame_section, size / 2 - 5);
854+ dwarf_data1(eh_frame_section, DW_CFA_def_cfa_register);
855+ dwarf_uleb128(eh_frame_section, 11); // r11 (fp)
856+#elif defined TCC_TARGET_ARM64
857+ dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 1);
858+ dwarf_data1(eh_frame_section, DW_CFA_def_cfa_offset);
859+ dwarf_uleb128(eh_frame_section, 224);
860+ dwarf_data1(eh_frame_section, DW_CFA_offset + 29); // x29 (fp)
861+ dwarf_uleb128(eh_frame_section, 28); // cfa-224
862+ dwarf_data1(eh_frame_section, DW_CFA_offset + 30); // x30 (lr)
863+ dwarf_uleb128(eh_frame_section, 27); // cfa-216
864+ dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 3);
865+ dwarf_data1(eh_frame_section, DW_CFA_def_cfa_offset);
866+ dwarf_uleb128(eh_frame_section, 224 + ((-loc + 15) & ~15));
867+ dwarf_data1(eh_frame_section, DW_CFA_advance_loc4);
868+ dwarf_data4(eh_frame_section, size / 4 - 5);
869+ dwarf_data1(eh_frame_section, DW_CFA_restore + 30); // x30 (lr)
870+ dwarf_data1(eh_frame_section, DW_CFA_restore + 29); // x29 (fp)
871+ dwarf_data1(eh_frame_section, DW_CFA_def_cfa_offset);
872+ dwarf_uleb128(eh_frame_section, 0);
873+#elif defined TCC_TARGET_RISCV64
874+ dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 4);
875+ dwarf_data1(eh_frame_section, DW_CFA_def_cfa_offset);
876+ dwarf_uleb128(eh_frame_section, 16); // ofs 16
877+ dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 8);
878+ dwarf_data1(eh_frame_section, DW_CFA_offset + 1); // r1 (ra, lr)
879+ dwarf_uleb128(eh_frame_section, 2); // cfa-8
880+ dwarf_data1(eh_frame_section, DW_CFA_offset + 8); // r8 (s0, fp)
881+ dwarf_uleb128(eh_frame_section, 4); // cfa-16
882+ dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 8);
883+ dwarf_data1(eh_frame_section, DW_CFA_def_cfa);
884+ dwarf_uleb128(eh_frame_section, 8); // r8 (s0, fp)
885+ dwarf_uleb128(eh_frame_section, 0); // ofs 0
886+ dwarf_data1(eh_frame_section, DW_CFA_advance_loc4);
887+ while (size >= 4 &&
888+ read32le(cur_text_section->data + func_ind + size - 4) != 0x00008067)
889+ size -= 4;
890+ dwarf_data4(eh_frame_section, size - 36);
891+ dwarf_data1(eh_frame_section, DW_CFA_def_cfa);
892+ dwarf_uleb128(eh_frame_section, 2); // r2 (r2, sp)
893+ dwarf_uleb128(eh_frame_section, 16); // ofs 16
894+ dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 4);
895+ dwarf_data1(eh_frame_section, DW_CFA_restore + 1); // r1 (lr)
896+ dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 4);
897+ dwarf_data1(eh_frame_section, DW_CFA_restore + 8); // r8 (s0, fp)
898+ dwarf_data1(eh_frame_section, DW_CFA_advance_loc + 4);
899+ dwarf_data1(eh_frame_section, DW_CFA_def_cfa_offset);
900+ dwarf_uleb128(eh_frame_section, 0); // ofs 0
901+#endif
902+ while ((eh_frame_section->data_offset - fde_start) & 3)
903+ dwarf_data1(eh_frame_section, DW_CFA_nop);
904+ write32le(eh_frame_section->data + fde_start, // length
905+ eh_frame_section->data_offset - fde_start - 4);
906+}
907+
908+ST_FUNC void tcc_eh_frame_end(TCCState *s1)
909+{
910+ if (!eh_frame_section)
911+ return;
912+ dwarf_data4(eh_frame_section, 0);
913+}
914+
915+struct eh_search_table {
916+ uint32_t pc_offset;
917+ uint32_t fde_offset;
918+};
919+
920+static int sort_eh_table(const void *a, const void *b)
921+{
922+ uint32_t pc1 = ((const struct eh_search_table *)a)->pc_offset;
923+ uint32_t pc2 = ((const struct eh_search_table *)b)->pc_offset;
924+
925+ return pc1 < pc2 ? -1 : pc1 > pc2 ? 1 : 0;
926+}
927+
928+ST_FUNC void tcc_eh_frame_hdr(TCCState *s1, int final)
929+{
930+ int count = 0, offset;
931+ unsigned long count_offset, tab_offset;
932+ unsigned char *ln, *end;
933+ unsigned int last_cie_offset = 0xffffffff;
934+
935+ if (!eh_frame_section || !eh_frame_section->data_offset)
936+ return;
937+ if (final && !eh_frame_hdr_section)
938+ return;
939+ if (final == 0)
940+ eh_frame_hdr_section =
941+ new_section(s1, ".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC);
942+ eh_frame_hdr_section->data_offset = 0;
943+ dwarf_data1(eh_frame_hdr_section, 1); // Version
944+ // Pointer Encoding Format
945+ dwarf_data1(eh_frame_hdr_section, DW_EH_PE_sdata4 | DW_EH_PE_pcrel);
946+ // Count Encoding Format
947+ dwarf_data1(eh_frame_hdr_section, DW_EH_PE_udata4 | DW_EH_PE_absptr);
948+ // Table Encoding Format
949+ dwarf_data1(eh_frame_hdr_section, DW_EH_PE_sdata4 | DW_EH_PE_datarel);
950+ offset = eh_frame_section->sh_addr -
951+ eh_frame_hdr_section->sh_addr -
952+ eh_frame_hdr_section->data_offset;
953+ dwarf_data4(eh_frame_hdr_section, offset); // eh_frame_ptr
954+ // Count
955+ count_offset = eh_frame_hdr_section->data_offset;
956+ dwarf_data4(eh_frame_hdr_section, 0);
957+ tab_offset = eh_frame_hdr_section->data_offset;
958+ ln = eh_frame_section->data;
959+ end = eh_frame_section->data + eh_frame_section->data_offset;
960+ while (ln < end) {
961+ unsigned char *fde = ln, *rd = ln;
962+ unsigned int cie_offset, version, length = dwarf_read_4(rd, end);
963+ unsigned int pc_offset, fde_offset;
964+
965+ if (length == 0)
966+ goto next;
967+ cie_offset = dwarf_read_4(rd, end);
968+ if (cie_offset == 0)
969+ goto next;
970+ if (cie_offset != last_cie_offset) {
971+ unsigned char *cie = rd - cie_offset + 4;
972+
973+ if (cie < eh_frame_section->data)
974+ goto next;
975+ version = dwarf_read_1(cie, end);
976+ if ((version == 1 || version == 3) &&
977+ dwarf_read_1(cie, end) == 'z' && // Augmentation String
978+ dwarf_read_1(cie, end) == 'R' &&
979+ dwarf_read_1(cie, end) == 0) {
980+ dwarf_read_uleb128(&cie, end); // code_alignment_factor
981+ dwarf_read_sleb128(&cie, end); // data_alignment_factor
982+ dwarf_read_1(cie, end); // return address column
983+ if (dwarf_read_uleb128(&cie, end) == 1 &&
984+ dwarf_read_1(cie, end) == FDE_ENCODING) {
985+ last_cie_offset = cie_offset;
986+ }
987+ else
988+ goto next;
989+ }
990+ else
991+ goto next;
992+ }
993+ count++;
994+ fde_offset = eh_frame_section->sh_addr +
995+ (fde - eh_frame_section->data) -
996+ eh_frame_hdr_section->sh_addr;
997+ pc_offset = dwarf_read_4(rd, end) + fde_offset + 8;
998+ dwarf_data4(eh_frame_hdr_section, pc_offset);
999+ dwarf_data4(eh_frame_hdr_section, fde_offset);
1000+next:
1001+ ln += length + 4;
1002+ }
1003+ add32le(eh_frame_hdr_section->data + count_offset, count);
1004+ qsort(eh_frame_hdr_section->data + tab_offset, count,
1005+ sizeof(struct eh_search_table), sort_eh_table);
1006+}
1007+
7131008 /* start of translation unit info */
7141009 ST_FUNC void tcc_debug_start(TCCState *s1)
7151010 {
@@ -1875,6 +2170,7 @@ ST_FUNC void tcc_debug_funcend(TCCState *s1, int size) · 1159 unmodified lines
18752170 /* lldb does not like function end and next function start at same pc */
18762171 int min_instr_len;
18772172
2173+ tcc_debug_frame_end(s1, size);
18782174 if (!s1->do_debug)
18792175 return;
18802176 min_instr_len = dwarf_line.last_pc == ind ? 0 : DWARF_MIN_INSTR_LEN;
tccelf.c+17−0
@@ -95,6 +95,8 @@ ST_FUNC void tccelf_new(TCCState *s) · 94 unmodified lines
9595 tcc_debug_new(s);
9696 }
9797
98+ tcc_eh_frame_start(s);
99+
98100 #ifdef CONFIG_TCC_BCHECK
99101 if (s->do_bounds_check) {
100102 /* if bound checking, then add corresponding sections */
@@ -2271,6 +2273,8 @@ static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d) · 2170 unmodified lines
22712273 ++phnum;
22722274 if (d->dynamic)
22732275 ++phnum;
2276+ if (eh_frame_hdr_section)
2277+ ++phnum;
22742278 if (d->roinf)
22752279 ++phnum;
22762280 d->phnum = phnum;
@@ -2391,6 +2395,12 @@ static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d) · 114 unmodified lines
23912395 fill_phdr(++ph, PT_NOTE, d->note);
23922396 if (d->dynamic)
23932397 fill_phdr(++ph, PT_DYNAMIC, d->dynamic)->p_flags |= PF_W;
2398+ if (eh_frame_hdr_section) {
2399+ add32le(eh_frame_hdr_section->data + 4,
2400+ eh_frame_section->sh_offset -
2401+ eh_frame_hdr_section->sh_offset - 4);
2402+ fill_phdr(++ph, PT_GNU_EH_FRAME, eh_frame_hdr_section);
2403+ }
23942404 if (d->roinf)
23952405 fill_phdr(++ph, PT_GNU_RELRO, d->roinf)->p_flags |= PF_W;
23962406 if (d->interp)
@@ -2859,6 +2869,10 @@ static int elf_output_file(TCCState *s1, const char *filename) · 462 unmodified lines
28592869 /* shared library case: simply export all global symbols */
28602870 export_global_syms(s1);
28612871 }
2872+
2873+ /* fill with initial data */
2874+ tcc_eh_frame_hdr(s1, 0);
2875+
28622876 dyninf.gnu_hash = create_gnu_hash(s1);
28632877 } else {
28642878 build_got_entries(s1, 0);
@@ -2943,6 +2957,9 @@ static int elf_output_file(TCCState *s1, const char *filename) · 78 unmodified lines
29432957
29442958 reorder_sections(s1, sec_order);
29452959
2960+ /* fill with final data */
2961+ tcc_eh_frame_hdr(s1, 1);
2962+
29462963 /* Create the ELF file with name 'filename' */
29472964 ret = tcc_write_elf_file(s1, filename, dyninf.phnum, dyninf.phdr);
29482965 the_end:
tccgen.c+1−0
@@ -402,6 +402,7 @@ ST_FUNC int tccgen_compile(TCCState *s1) · 401 unmodified lines
402402 gen_inline_functions(s1);
403403 check_vstack();
404404 /* end of translation unit info */
405+ tcc_eh_frame_end(s1);
405406 tcc_debug_end(s1);
406407 tcc_tcov_end(s1);
407408 return 0;
tccrun.c+0−49
@@ -760,19 +760,9 @@ found: · 759 unmodified lines
760760 /* ------------------------------------------------------------- */
761761 /* rt_printline - dwarf version */
762762
763−#define MAX_128 ((8 * sizeof (long long) + 6) / 7)
764−
765763 #define DIR_TABLE_SIZE (64)
766764 #define FILE_TABLE_SIZE (512)
767765
768−#define dwarf_read_1(ln,end) \
769− ((ln) < (end) ? *(ln)++ : 0)
770−#define dwarf_read_2(ln,end) \
771− ((ln) + 2 < (end) ? (ln) += 2, read16le((ln) - 2) : 0)
772−#define dwarf_read_4(ln,end) \
773− ((ln) + 4 < (end) ? (ln) += 4, read32le((ln) - 4) : 0)
774−#define dwarf_read_8(ln,end) \
775− ((ln) + 8 < (end) ? (ln) += 8, read64le((ln) - 8) : 0)
776766 #define dwarf_ignore_type(ln, end) /* timestamp/size/md5/... */ \
777767 switch (entry_format[j].form) { \
778768 case DW_FORM_data1: (ln) += 1; break; \
@@ -784,45 +774,6 @@ found: · 5 unmodified lines
784774 default: goto next_line; \
785775 }
786776
787−static unsigned long long
788−dwarf_read_uleb128(unsigned char **ln, unsigned char *end)
789−{
790− unsigned char *cp = *ln;
791− unsigned long long retval = 0;
792− int i;
793−
794− for (i = 0; i < MAX_128; i++) {
795− unsigned long long byte = dwarf_read_1(cp, end);
796−
797− retval |= (byte & 0x7f) << (i * 7);
798− if ((byte & 0x80) == 0)
799− break;
800− }
801− *ln = cp;
802− return retval;
803−}
804−
805−static long long
806−dwarf_read_sleb128(unsigned char **ln, unsigned char *end)
807−{
808− unsigned char *cp = *ln;
809− long long retval = 0;
810− int i;
811−
812− for (i = 0; i < MAX_128; i++) {
813− unsigned long long byte = dwarf_read_1(cp, end);
814−
815− retval |= (byte & 0x7f) << (i * 7);
816− if ((byte & 0x80) == 0) {
817− if ((byte & 0x40) && (i + 1) * 7 < 64)
818− retval |= -1LL << ((i + 1) * 7);
819− break;
820− }
821− }
822− *ln = cp;
823− return retval;
824−}
825−
826777 static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc, bt_info *bi)
827778 {
828779 unsigned char *ln;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t