History

Add debug support to macos

lldb now works with this push. In tccmacho.c add S_ATTR_DEBUG to all debug sections. Add __DWARF section and rearange struct skinfo. In tccdbg.c The first filename in dwarf_line can not be used. Also had to fix structure/union/lexical_block/subroutine to allow empty childs. dwarfdump --verify complained about this.

herman ten brugge committed 3 years ago

Commit 62096261 parent ac0604a2 files · +107 −57Browse files

Unified · Split

2 files
  1. tccdbg.c +71 −33
  2. tccmacho.c +36 −24
tccdbg.c+71−33
@@ -111,12 +111,16 @@ static const struct { · 110 unmodified lines
111111 #define DWARF_ABBREV_MEMBER 14
112112 #define DWARF_ABBREV_MEMBER_BF 15
113113 #define DWARF_ABBREV_STRUCTURE_TYPE 16
114−#define DWARF_ABBREV_UNION_TYPE 17
115−#define DWARF_ABBREV_SUBPROGRAM_EXTERNAL 18
116−#define DWARF_ABBREV_SUBPROGRAM_STATIC 19
117−#define DWARF_ABBREV_LEXICAL_BLOCK 20
118−#define DWARF_ABBREV_SUBROUTINE_TYPE 21
119−#define DWARF_ABBREV_FORMAL_PARAMETER2 22
114+#define DWARF_ABBREV_STRUCTURE_EMPTY_TYPE 17
115+#define DWARF_ABBREV_UNION_TYPE 18
116+#define DWARF_ABBREV_UNION_EMPTY_TYPE 19
117+#define DWARF_ABBREV_SUBPROGRAM_EXTERNAL 20
118+#define DWARF_ABBREV_SUBPROGRAM_STATIC 21
119+#define DWARF_ABBREV_LEXICAL_BLOCK 22
120+#define DWARF_ABBREV_LEXICAL_EMPTY_BLOCK 23
121+#define DWARF_ABBREV_SUBROUTINE_TYPE 24
122+#define DWARF_ABBREV_SUBROUTINE_EMPTY_TYPE 25
123+#define DWARF_ABBREV_FORMAL_PARAMETER2 26
120124
121125 /* all entries should have been generated with dwarf_uleb128 except
122126 has_children. All values are currently below 128 so this currently
@@ -222,6 +226,12 @@ static const unsigned char dwarf_abbrev_init[] = { · 99 unmodified lines
222226 DW_AT_decl_line, DW_FORM_udata,
223227 DW_AT_sibling, DW_FORM_ref4,
224228 0, 0,
229+ DWARF_ABBREV_STRUCTURE_EMPTY_TYPE, DW_TAG_structure_type, 0,
230+ DW_AT_name, DW_FORM_strp,
231+ DW_AT_byte_size, DW_FORM_udata,
232+ DW_AT_decl_file, DW_FORM_udata,
233+ DW_AT_decl_line, DW_FORM_udata,
234+ 0, 0,
225235 DWARF_ABBREV_UNION_TYPE, DW_TAG_union_type, 1,
226236 DW_AT_name, DW_FORM_strp,
227237 DW_AT_byte_size, DW_FORM_udata,
@@ -229,6 +239,12 @@ static const unsigned char dwarf_abbrev_init[] = { · 1 unmodified line
229239 DW_AT_decl_line, DW_FORM_udata,
230240 DW_AT_sibling, DW_FORM_ref4,
231241 0, 0,
242+ DWARF_ABBREV_UNION_EMPTY_TYPE, DW_TAG_union_type, 0,
243+ DW_AT_name, DW_FORM_strp,
244+ DW_AT_byte_size, DW_FORM_udata,
245+ DW_AT_decl_file, DW_FORM_udata,
246+ DW_AT_decl_line, DW_FORM_udata,
247+ 0, 0,
232248 DWARF_ABBREV_SUBPROGRAM_EXTERNAL, DW_TAG_subprogram, 1,
233249 DW_AT_external, DW_FORM_flag,
234250 DW_AT_name, DW_FORM_strp,
@@ -264,12 +280,23 @@ static const unsigned char dwarf_abbrev_init[] = { · 29 unmodified lines
264280 DW_AT_high_pc, DW_FORM_data4,
265281 #else
266282 DW_AT_high_pc, DW_FORM_data8,
283+#endif
284+ 0, 0,
285+ DWARF_ABBREV_LEXICAL_EMPTY_BLOCK, DW_TAG_lexical_block, 0,
286+ DW_AT_low_pc, DW_FORM_addr,
287+#if PTR_SIZE == 4
288+ DW_AT_high_pc, DW_FORM_data4,
289+#else
290+ DW_AT_high_pc, DW_FORM_data8,
267291 #endif
268292 0, 0,
269293 DWARF_ABBREV_SUBROUTINE_TYPE, DW_TAG_subroutine_type, 1,
270294 DW_AT_type, DW_FORM_ref4,
271295 DW_AT_sibling, DW_FORM_ref4,
272296 0, 0,
297+ DWARF_ABBREV_SUBROUTINE_EMPTY_TYPE, DW_TAG_subroutine_type, 0,
298+ DW_AT_type, DW_FORM_ref4,
299+ 0, 0,
273300 DWARF_ABBREV_FORMAL_PARAMETER2, DW_TAG_formal_parameter, 0,
274301 DW_AT_type, DW_FORM_ref4,
275302 0, 0,
@@ -546,7 +573,7 @@ static void dwarf_file(TCCState *s1) · 270 unmodified lines
546573
547574 filename = strrchr(file->filename, '/');
548575 if (filename == NULL) {
549− for (i = 0; i < dwarf_line.filename_size; i++)
576+ for (i = 1; i < dwarf_line.filename_size; i++)
550577 if (dwarf_line.filename_table[i].dir_entry == 0 &&
551578 strcmp(dwarf_line.filename_table[i].name,
552579 file->filename) == 0) {
@@ -789,11 +816,9 @@ ST_FUNC void tcc_debug_start(TCCState *s1) · 236 unmodified lines
789816 tcc_malloc(2*sizeof (struct dwarf_filename_struct));
790817 dwarf_line.filename_table[0].dir_entry = 0;
791818 if (undo) {
792− dwarf_line.filename_table[0].name = tcc_strdup(filename);
819+ dwarf_line.filename_table[0].name = tcc_strdup(undo + 1);
793820 dwarf_line.filename_table[1].dir_entry = 1;
794821 dwarf_line.filename_table[1].name = tcc_strdup(undo + 1);
795− *undo = '/';
796− dwarf_line.filename_table[0].name = tcc_strdup(filename);
797822 }
798823 else {
799824 dwarf_line.filename_table[0].name = tcc_strdup(filename);
@@ -849,17 +874,14 @@ ST_FUNC void tcc_debug_end(TCCState *s1) · 49 unmodified lines
849874 int pos = dwarf_info_section->data_offset;
850875
851876 dwarf_data1(dwarf_info_section,
852− IS_UNION (t->type.t) ? DWARF_ABBREV_UNION_TYPE
853− : DWARF_ABBREV_STRUCTURE_TYPE);
877+ IS_UNION (t->type.t) ? DWARF_ABBREV_UNION_EMPTY_TYPE
878+ : DWARF_ABBREV_STRUCTURE_EMPTY_TYPE);
854879 dwarf_strp(dwarf_info_section,
855880 (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
856881 ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL));
857882 dwarf_uleb128(dwarf_info_section, 0);
858883 dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
859884 dwarf_uleb128(dwarf_info_section, file->line_num);
860− j = dwarf_info_section->data_offset + 5 - dwarf_info.start;
861− dwarf_data4(dwarf_info_section, j);
862− dwarf_data1(dwarf_info_section, 0);
863885 for (j = 0; j < debug_anon_hash[i].n_debug_type; j++)
864886 write32le(dwarf_info_section->data +
865887 debug_anon_hash[i].debug_type[j],
@@ -1032,7 +1054,7 @@ ST_FUNC void tcc_debug_bincl(TCCState *s1) · 166 unmodified lines
10321054 *undo = '/';
10331055 }
10341056 if (strcmp(filename, "<command line>")) {
1035− for (j = 0; j < dwarf_line.filename_size; j++)
1057+ for (j = 1; j < dwarf_line.filename_size; j++)
10361058 if (dwarf_line.filename_table[j].dir_entry == i &&
10371059 strcmp (dwarf_line.filename_table[j].name, filename) == 0)
10381060 break;
@@ -1417,7 +1439,7 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s) · 378 unmodified lines
14171439 t = t->type.ref;
14181440 debug_type = tcc_debug_find(s1, t, 1);
14191441 if (debug_type == -1) {
1420− int pos_sib, i, *pos_type;
1442+ int pos_sib = 0, i, *pos_type;
14211443
14221444 debug_type = tcc_debug_add(s1, t, 1);
14231445 e = t;
@@ -1428,16 +1450,21 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s) · 4 unmodified lines
14281450 }
14291451 pos_type = (int *) tcc_malloc(i * sizeof(int));
14301452 dwarf_data1(dwarf_info_section,
1431− IS_UNION (t->type.t) ? DWARF_ABBREV_UNION_TYPE
1432− : DWARF_ABBREV_STRUCTURE_TYPE);
1453+ IS_UNION (t->type.t)
1454+ ? t->next ? DWARF_ABBREV_UNION_TYPE
1455+ : DWARF_ABBREV_UNION_EMPTY_TYPE
1456+ : t->next ? DWARF_ABBREV_STRUCTURE_TYPE
1457+ : DWARF_ABBREV_STRUCTURE_EMPTY_TYPE);
14331458 dwarf_strp(dwarf_info_section,
14341459 (t->v & ~SYM_STRUCT) >= SYM_FIRST_ANOM
14351460 ? "" : get_tok_str(t->v & ~SYM_STRUCT, NULL));
14361461 dwarf_uleb128(dwarf_info_section, t->c);
14371462 dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file);
14381463 dwarf_uleb128(dwarf_info_section, file->line_num);
1439− pos_sib = dwarf_info_section->data_offset;
1440− dwarf_data4(dwarf_info_section, 0);
1464+ if (t->next) {
1465+ pos_sib = dwarf_info_section->data_offset;
1466+ dwarf_data4(dwarf_info_section, 0);
1467+ }
14411468 e = t;
14421469 i = 0;
14431470 while (e->next) {
@@ -1462,9 +1489,11 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s) · 18 unmodified lines
14621489 else
14631490 dwarf_uleb128(dwarf_info_section, e->c);
14641491 }
1465− dwarf_data1(dwarf_info_section, 0);
1466− write32le(dwarf_info_section->data + pos_sib,
1467− dwarf_info_section->data_offset - dwarf_info.start);
1492+ if (t->next) {
1493+ dwarf_data1(dwarf_info_section, 0);
1494+ write32le(dwarf_info_section->data + pos_sib,
1495+ dwarf_info_section->data_offset - dwarf_info.start);
1496+ }
14681497 e = t;
14691498 i = 0;
14701499 while (e->next) {
@@ -1602,14 +1631,16 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s) · 131 unmodified lines
16021631 dwarf_info_section->data_offset - dwarf_info.start);
16031632 }
16041633 else if (type == VT_FUNC) {
1605− int sib_pos, *pos_type;
1634+ int sib_pos = 0, *pos_type;
16061635 Sym *f;
16071636
16081637 i = dwarf_info_section->data_offset;
16091638 debug_type = tcc_get_dwarf_info(s1, t->type.ref);
16101639 if (retval == debug_type)
16111640 retval = i;
1612− dwarf_data1(dwarf_info_section, DWARF_ABBREV_SUBROUTINE_TYPE);
1641+ dwarf_data1(dwarf_info_section,
1642+ t->type.ref->next ? DWARF_ABBREV_SUBROUTINE_TYPE
1643+ : DWARF_ABBREV_SUBROUTINE_EMPTY_TYPE);
16131644 if (last_pos != -1) {
16141645 tcc_debug_check_anon(s1, e, last_pos);
16151646 write32le(dwarf_info_section->data + last_pos,
@@ -1618,8 +1649,10 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s) · 2 unmodified lines
16181649 last_pos = dwarf_info_section->data_offset;
16191650 e = t->type.ref;
16201651 dwarf_data4(dwarf_info_section, 0);
1621− sib_pos = dwarf_info_section->data_offset;
1622− dwarf_data4(dwarf_info_section, 0);
1652+ if (t->type.ref->next) {
1653+ sib_pos = dwarf_info_section->data_offset;
1654+ dwarf_data4(dwarf_info_section, 0);
1655+ }
16231656 f = t->type.ref;
16241657 i = 0;
16251658 while (f->next) {
@@ -1635,9 +1668,11 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s) · 9 unmodified lines
16351668 pos_type[i++] = dwarf_info_section->data_offset;
16361669 dwarf_data4(dwarf_info_section, 0);
16371670 }
1638− dwarf_data1(dwarf_info_section, 0);
1639− write32le(dwarf_info_section->data + sib_pos,
1640− dwarf_info_section->data_offset - dwarf_info.start);
1671+ if (t->type.ref->next) {
1672+ dwarf_data1(dwarf_info_section, 0);
1673+ write32le(dwarf_info_section->data + sib_pos,
1674+ dwarf_info_section->data_offset - dwarf_info.start);
1675+ }
16411676 f = t->type.ref;
16421677 i = 0;
16431678 while (f->next) {
@@ -1710,7 +1745,9 @@ static void tcc_debug_finish (TCCState *s1, struct _debug_info *cur) · 66 unmodified lines
17101745 tcc_free (s->str);
17111746 }
17121747 tcc_free (cur->sym);
1713− dwarf_data1(dwarf_info_section, DWARF_ABBREV_LEXICAL_BLOCK);
1748+ dwarf_data1(dwarf_info_section,
1749+ cur->child ? DWARF_ABBREV_LEXICAL_BLOCK
1750+ : DWARF_ABBREV_LEXICAL_EMPTY_BLOCK);
17141751 dwarf_reloc(dwarf_info_section, section_sym, R_DATA_PTR);
17151752 #if PTR_SIZE == 4
17161753 dwarf_data4(dwarf_info_section, func_ind + cur->start);
@@ -1720,7 +1757,8 @@ static void tcc_debug_finish (TCCState *s1, struct _debug_info *cur) · 3 unmodified lines
17201757 dwarf_data8(dwarf_info_section, cur->end - cur->start);
17211758 #endif
17221759 tcc_debug_finish (s1, cur->child);
1723− dwarf_data1(dwarf_info_section, 0);
1760+ if (cur->child)
1761+ dwarf_data1(dwarf_info_section, 0);
17241762 }
17251763 else
17261764 {
tccmacho.c+36−24
@@ -228,6 +228,8 @@ struct dyld_chained_ptr_64_bind · 227 unmodified lines
228228
229229 #define S_ATTR_PURE_INSTRUCTIONS 0x80000000
230230 #define S_ATTR_SOME_INSTRUCTIONS 0x00000400
231+#define S_ATTR_DEBUG 0x02000000
232+
231233
232234 typedef uint32_t lc_str;
233235
@@ -372,18 +374,18 @@ enum skind { · 138 unmodified lines
372374 sk_ro_data,
373375 sk_uw_info,
374376 sk_nl_ptr, // non-lazy pointers, aka GOT
375− sk_la_ptr, // lazy pointers
376− sk_init,
377− sk_fini,
378− sk_rw_data,
379− sk_stab,
380− sk_stab_str,
381377 sk_debug_info,
382378 sk_debug_abbrev,
383379 sk_debug_line,
384380 sk_debug_aranges,
385381 sk_debug_str,
386382 sk_debug_line_str,
383+ sk_stab,
384+ sk_stab_str,
385+ sk_la_ptr, // lazy pointers
386+ sk_init,
387+ sk_fini,
388+ sk_rw_data,
387389 sk_bss,
388390 sk_linkedit,
389391 sk_last
@@ -407,7 +409,7 @@ struct nlist_64 { · 17 unmodified lines
407409
408410 struct macho {
409411 struct mach_header_64 mh;
410− int seg2lc[5], nseg;
412+ int seg2lc[6], nseg;
411413 struct load_command **lc;
412414 struct entry_point_command *ep;
413415 int nlc;
@@ -1202,20 +1204,20 @@ const struct { · 788 unmodified lines
12021204 /*[sk_ro_data] =*/ { 2, S_REGULAR, "__rodata" },
12031205 /*[sk_uw_info] =*/ { 0 },
12041206 /*[sk_nl_ptr] =*/ { 2, S_NON_LAZY_SYMBOL_POINTERS, "__got" },
1205− /*[sk_la_ptr] =*/ { 3, S_LAZY_SYMBOL_POINTERS, "__la_symbol_ptr" },
1206− /*[sk_init] =*/ { 3, S_MOD_INIT_FUNC_POINTERS, "__mod_init_func" },
1207− /*[sk_fini] =*/ { 3, S_MOD_TERM_FUNC_POINTERS, "__mod_term_func" },
1208− /*[sk_rw_data] =*/ { 3, S_REGULAR, "__data" },
1209− /*[sk_stab] =*/ { 3, S_REGULAR, "__stab" },
1210− /*[sk_stab_str] =*/ { 3, S_REGULAR, "__stab_str" },
1211− /*[sk_debug_info] =*/ { 3, S_REGULAR, "__debug_info" },
1212− /*[sk_debug_abbrev] =*/ { 3, S_REGULAR, "__debug_abbrev" },
1213− /*[sk_debug_line] =*/ { 3, S_REGULAR, "__debug_line" },
1214− /*[sk_debug_aranges] =*/ { 3, S_REGULAR, "__debug_aranges" },
1215− /*[sk_debug_str] =*/ { 3, S_REGULAR, "__debug_str" },
1216− /*[sk_debug_line_str] =*/ { 3, S_REGULAR, "__debug_line_str" },
1217− /*[sk_bss] =*/ { 3, S_ZEROFILL, "__bss" },
1218− /*[sk_linkedit] =*/ { 4, S_REGULAR, NULL },
1207+ /*[sk_debug_info] =*/ { 3, S_REGULAR | S_ATTR_DEBUG, "__debug_info" },
1208+ /*[sk_debug_abbrev] =*/ { 3, S_REGULAR | S_ATTR_DEBUG, "__debug_abbrev" },
1209+ /*[sk_debug_line] =*/ { 3, S_REGULAR | S_ATTR_DEBUG, "__debug_line" },
1210+ /*[sk_debug_aranges] =*/ { 3, S_REGULAR | S_ATTR_DEBUG, "__debug_aranges" },
1211+ /*[sk_debug_str] =*/ { 3, S_REGULAR | S_ATTR_DEBUG, "__debug_str" },
1212+ /*[sk_debug_line_str] =*/ { 3, S_REGULAR | S_ATTR_DEBUG, "__debug_line_str" },
1213+ /*[sk_stab] =*/ { 4, S_REGULAR, "__stab" },
1214+ /*[sk_stab_str] =*/ { 4, S_REGULAR, "__stab_str" },
1215+ /*[sk_la_ptr] =*/ { 4, S_LAZY_SYMBOL_POINTERS, "__la_symbol_ptr" },
1216+ /*[sk_init] =*/ { 4, S_MOD_INIT_FUNC_POINTERS, "__mod_init_func" },
1217+ /*[sk_fini] =*/ { 4, S_MOD_TERM_FUNC_POINTERS, "__mod_term_func" },
1218+ /*[sk_rw_data] =*/ { 4, S_REGULAR, "__data" },
1219+ /*[sk_bss] =*/ { 4, S_ZEROFILL, "__bss" },
1220+ /*[sk_linkedit] =*/ { 5, S_REGULAR, NULL },
12191221 };
12201222
12211223 #ifdef CONFIG_NEW_MACHO
@@ -1285,7 +1287,7 @@ static void bind_rebase(TCCState *s1, struct macho *mo) · 63 unmodified lines
12851287 *ptr++ = BIND_OPCODE_SET_DYLIB_SPECIAL_IMM |
12861288 (BIND_SPECIAL_DYLIB_FLAT_LOOKUP & 0xf);
12871289 *ptr++ = BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM | 0;
1288− strcpy(ptr, name);
1290+ strcpy((char *)ptr, name);
12891291 ptr += strlen(name) + 1;
12901292 *ptr++ = BIND_OPCODE_DO_BIND;
12911293 *ptr = BIND_OPCODE_DONE;
@@ -1316,7 +1318,7 @@ static void bind_rebase(TCCState *s1, struct macho *mo) · 24 unmodified lines
13161318 *ptr++ = BIND_OPCODE_SET_DYLIB_SPECIAL_IMM |
13171319 (BIND_SPECIAL_DYLIB_FLAT_LOOKUP & 0xf);
13181320 *ptr++ = BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM | 0;
1319− strcpy(ptr, name);
1321+ strcpy((char *)ptr, name);
13201322 ptr += strlen(name) + 1;
13211323 *ptr++ = BIND_OPCODE_SET_TYPE_IMM | BIND_TYPE_POINTER;
13221324 set_segment_and_offset(mo, s->sh_addr, ptr,
@@ -1582,6 +1584,11 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 259 unmodified lines
15821584 seg->initprot = 3; // rw-
15831585 seg->flags = SG_READ_ONLY;
15841586
1587+ seg = add_segment(mo, "__DWARF");
1588+ seg->vmaddr = -1;
1589+ seg->maxprot = 7; // rwx
1590+ seg->initprot = 3; // rw-
1591+
15851592 seg = add_segment(mo, "__DATA");
15861593 seg->vmaddr = -1;
15871594 seg->maxprot = 3; // rw-
@@ -1592,6 +1599,10 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 4 unmodified lines
15921599 seg->maxprot = 1; // r--
15931600 seg->initprot = 1; // r--
15941601
1602+ /* trick to avoid __DWARF vmaddr = -1 */
1603+ if (dwarf_info_section == NULL)
1604+ dwarf_info_section = new_section(s1, ".debug_info", SHT_PROGBITS, 0);
1605+
15951606 #ifdef CONFIG_NEW_MACHO
15961607 chained_fixups_lc = add_lc(mo, LC_DYLD_CHAINED_FIXUPS,
15971608 sizeof(struct linkedit_data_command));
@@ -1638,7 +1649,8 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 40 unmodified lines
16381649 type = s->sh_type;
16391650 flags = s->sh_flags;
16401651 sk = sk_unknown;
1641− if (flags & SHF_ALLOC) {
1652+ /* debug sections have sometimes no SHF_ALLOC */
1653+ if ((flags & SHF_ALLOC) || !strncmp(s->name, ".debug_", 7)) {
16421654 switch (type) {
16431655 default: sk = sk_unknown; break;
16441656 case SHT_INIT_ARRAY: sk = sk_init; break;

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