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
218 break;218 break;
219 }219 }
220 }220 }
221 write32le(ptr, val - addr);221 add32le(ptr, val - addr);
222 return;222 return;
223 case R_AARCH64_MOVW_UABS_G0_NC:223 case R_AARCH64_MOVW_UABS_G0_NC:
224 write32le(ptr, ((read32le(ptr) & 0xffe0001f) |224 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
352 case R_RISCV_SUB6:352 case R_RISCV_SUB6:
353 *ptr = (*ptr & ~0x3f) | ((*ptr - val) & 0x3f);353 *ptr = (*ptr & ~0x3f) | ((*ptr - val) & 0x3f);
354 return;354 return;
355
356 case R_RISCV_32_PCREL:355 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;
357 case R_RISCV_COPY:370 case R_RISCV_COPY:
358 /* XXX */371 /* XXX */
359 return;372 return;
tcc.h+57−0
@@ -925,6 +925,10 @@ struct TCCState { · 924 unmodified lines
925 Section *dynsym;925 Section *dynsym;
926 /* got & plt handling */926 /* got & plt handling */
927 Section *got, *plt;927 Section *got, *plt;
928 /* exception handling */
929 Section *eh_frame_section;
930 Section *eh_frame_hdr_section;
931 unsigned long eh_start;
928 /* debug sections */932 /* debug sections */
929 Section *stab_section;933 Section *stab_section;
930 Section *dwarf_info_section;934 Section *dwarf_info_section;
@@ -1673,6 +1677,53 @@ static inline void write64le(unsigned char *p, uint64_t x) { · 742 unmodified lines
1673static inline void add64le(unsigned char *p, int64_t x) {1677static inline void add64le(unsigned char *p, int64_t x) {
1674 write64le(p, read64le(p) + x);1678 write64le(p, read64le(p) + x);
1675}1679}
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)
1689static inline uint64_t
1690dwarf_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}
1706static inline int64_t
1707dwarf_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
1676 1727
1677/* ------------ i386-gen.c ------------ */1728/* ------------ i386-gen.c ------------ */
1678#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM1729#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
1818 1869
1819/* ------------ tccdbg.c ------------ */1870/* ------------ tccdbg.c ------------ */
1820 1871
1872ST_FUNC void tcc_eh_frame_start(TCCState *s1);
1873ST_FUNC void tcc_eh_frame_end(TCCState *s1);
1874ST_FUNC void tcc_eh_frame_hdr(TCCState *s1, int final);
1875
1821ST_FUNC void tcc_debug_new(TCCState *s);1876ST_FUNC void tcc_debug_new(TCCState *s);
1822 1877
1823ST_FUNC void tcc_debug_start(TCCState *s1);1878ST_FUNC void tcc_debug_start(TCCState *s1);
@@ -1846,6 +1901,8 @@ ST_FUNC void tcc_tcov_reset_ind(TCCState *s1); · 22 unmodified lines
1846#define stab_section s1->stab_section1901#define stab_section s1->stab_section
1847#define stabstr_section stab_section->link1902#define stabstr_section stab_section->link
1848#define tcov_section s1->tcov_section1903#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
1849#define dwarf_info_section s1->dwarf_info_section1906#define dwarf_info_section s1->dwarf_info_section
1850#define dwarf_abbrev_section s1->dwarf_abbrev_section1907#define dwarf_abbrev_section s1->dwarf_abbrev_section
1851#define dwarf_line_section s1->dwarf_line_section1908#define dwarf_line_section s1->dwarf_line_section
tccdbg.c+298−2
@@ -71,7 +71,7 @@ static const struct { · 70 unmodified lines
71 { VT_BOOL, 1, DW_ATE_boolean, "bool:t26=r26;0;255;" },71 { VT_BOOL, 1, DW_ATE_boolean, "bool:t26=r26;0;255;" },
72#if LONG_SIZE == 472#if LONG_SIZE == 4
73 { VT_VOID, 1, DW_ATE_unsigned_char, "void:t27=27" },73 { VT_VOID, 1, DW_ATE_unsigned_char, "void:t27=27" },
74#else 74#else
75 /* bitfields use these */75 /* bitfields use these */
76 { VT_LONG | VT_INT, 8, DW_ATE_signed, "long int:t27=r27;-9223372036854775808;9223372036854775807;" },76 { VT_LONG | VT_INT, 8, DW_ATE_signed, "long int:t27=r27;-9223372036854775808;9223372036854775807;" },
77 { VT_LONG | VT_INT | VT_UNSIGNED, 8, DW_ATE_unsigned, "long unsigned int:t28=r28;0;01777777777777777777777;" },77 { 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
407#define dwarf_info s1->dState->dwarf_info407#define dwarf_info s1->dState->dwarf_info
408#define tcov_data s1->dState->tcov_data408#define tcov_data s1->dState->tcov_data
409 409
410#define FDE_ENCODING (DW_EH_PE_udata4 | DW_EH_PE_signed | DW_EH_PE_pcrel)
411
410/* ------------------------------------------------------------------------- */412/* ------------------------------------------------------------------------- */
411static void put_stabs(TCCState *s1, const char *str, int type, int other,413static void put_stabs(TCCState *s1, const char *str, int type, int other,
412 int desc, unsigned long value);414 int desc, unsigned long value);
@@ -611,7 +613,7 @@ static void dwarf_file(TCCState *s1) · 198 unmodified lines
611 }613 }
612 if (i == dwarf_line.dir_size) {614 if (i == dwarf_line.dir_size) {
613 dwarf_line.dir_size++;615 dwarf_line.dir_size++;
614 dwarf_line.dir_table = 616 dwarf_line.dir_table =
615 (char **) tcc_realloc(dwarf_line.dir_table,617 (char **) tcc_realloc(dwarf_line.dir_table,
616 dwarf_line.dir_size *618 dwarf_line.dir_size *
617 sizeof (char *));619 sizeof (char *));
@@ -710,6 +712,299 @@ static void dwarf_sleb128_op (TCCState *s1, long long value) · 92 unmodified lines
710 } while (more);712 } while (more);
711}713}
712 714
715ST_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
788static 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
908ST_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
915struct eh_search_table {
916 uint32_t pc_offset;
917 uint32_t fde_offset;
918};
919
920static 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
928ST_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);
1000next:
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
713/* start of translation unit info */1008/* start of translation unit info */
714ST_FUNC void tcc_debug_start(TCCState *s1)1009ST_FUNC void tcc_debug_start(TCCState *s1)
715{1010{
@@ -1875,6 +2170,7 @@ ST_FUNC void tcc_debug_funcend(TCCState *s1, int size) · 1159 unmodified lines
1875 /* lldb does not like function end and next function start at same pc */2170 /* lldb does not like function end and next function start at same pc */
1876 int min_instr_len;2171 int min_instr_len;
1877 2172
2173 tcc_debug_frame_end(s1, size);
1878 if (!s1->do_debug)2174 if (!s1->do_debug)
1879 return;2175 return;
1880 min_instr_len = dwarf_line.last_pc == ind ? 0 : DWARF_MIN_INSTR_LEN;2176 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
95 tcc_debug_new(s);95 tcc_debug_new(s);
96 }96 }
97 97
98 tcc_eh_frame_start(s);
99
98#ifdef CONFIG_TCC_BCHECK100#ifdef CONFIG_TCC_BCHECK
99 if (s->do_bounds_check) {101 if (s->do_bounds_check) {
100 /* if bound checking, then add corresponding sections */102 /* 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
2271 ++phnum;2273 ++phnum;
2272 if (d->dynamic)2274 if (d->dynamic)
2273 ++phnum;2275 ++phnum;
2276 if (eh_frame_hdr_section)
2277 ++phnum;
2274 if (d->roinf)2278 if (d->roinf)
2275 ++phnum;2279 ++phnum;
2276 d->phnum = phnum;2280 d->phnum = phnum;
@@ -2391,6 +2395,12 @@ static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d) · 114 unmodified lines
2391 fill_phdr(++ph, PT_NOTE, d->note);2395 fill_phdr(++ph, PT_NOTE, d->note);
2392 if (d->dynamic)2396 if (d->dynamic)
2393 fill_phdr(++ph, PT_DYNAMIC, d->dynamic)->p_flags |= PF_W;2397 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 }
2394 if (d->roinf)2404 if (d->roinf)
2395 fill_phdr(++ph, PT_GNU_RELRO, d->roinf)->p_flags |= PF_W;2405 fill_phdr(++ph, PT_GNU_RELRO, d->roinf)->p_flags |= PF_W;
2396 if (d->interp)2406 if (d->interp)
@@ -2859,6 +2869,10 @@ static int elf_output_file(TCCState *s1, const char *filename) · 462 unmodified lines
2859 /* shared library case: simply export all global symbols */2869 /* shared library case: simply export all global symbols */
2860 export_global_syms(s1);2870 export_global_syms(s1);
2861 }2871 }
2872
2873 /* fill with initial data */
2874 tcc_eh_frame_hdr(s1, 0);
2875
2862 dyninf.gnu_hash = create_gnu_hash(s1);2876 dyninf.gnu_hash = create_gnu_hash(s1);
2863 } else {2877 } else {
2864 build_got_entries(s1, 0);2878 build_got_entries(s1, 0);
@@ -2943,6 +2957,9 @@ static int elf_output_file(TCCState *s1, const char *filename) · 78 unmodified lines
2943 2957
2944 reorder_sections(s1, sec_order);2958 reorder_sections(s1, sec_order);
2945 2959
2960 /* fill with final data */
2961 tcc_eh_frame_hdr(s1, 1);
2962
2946 /* Create the ELF file with name 'filename' */2963 /* Create the ELF file with name 'filename' */
2947 ret = tcc_write_elf_file(s1, filename, dyninf.phnum, dyninf.phdr);2964 ret = tcc_write_elf_file(s1, filename, dyninf.phnum, dyninf.phdr);
2948 the_end:2965 the_end:
tccgen.c+1−0
@@ -402,6 +402,7 @@ ST_FUNC int tccgen_compile(TCCState *s1) · 401 unmodified lines
402 gen_inline_functions(s1);402 gen_inline_functions(s1);
403 check_vstack();403 check_vstack();
404 /* end of translation unit info */404 /* end of translation unit info */
405 tcc_eh_frame_end(s1);
405 tcc_debug_end(s1);406 tcc_debug_end(s1);
406 tcc_tcov_end(s1);407 tcc_tcov_end(s1);
407 return 0;408 return 0;
tccrun.c+0−49
@@ -760,19 +760,9 @@ found: · 759 unmodified lines
760/* ------------------------------------------------------------- */760/* ------------------------------------------------------------- */
761/* rt_printline - dwarf version */761/* rt_printline - dwarf version */
762 762
763#define MAX_128 ((8 * sizeof (long long) + 6) / 7)
764
765#define DIR_TABLE_SIZE (64)763#define DIR_TABLE_SIZE (64)
766#define FILE_TABLE_SIZE (512)764#define FILE_TABLE_SIZE (512)
767 765
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)
776#define dwarf_ignore_type(ln, end) /* timestamp/size/md5/... */ \766#define dwarf_ignore_type(ln, end) /* timestamp/size/md5/... */ \
777 switch (entry_format[j].form) { \767 switch (entry_format[j].form) { \
778 case DW_FORM_data1: (ln) += 1; break; \768 case DW_FORM_data1: (ln) += 1; break; \
@@ -784,45 +774,6 @@ found: · 5 unmodified lines
784 default: goto next_line; \774 default: goto next_line; \
785 }775 }
786 776
787static unsigned long long
788dwarf_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
805static long long
806dwarf_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
826static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc, bt_info *bi)777static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc, bt_info *bi)
827{778{
828 unsigned char *ln;779 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