11
11
12
12
// Emit Dwarf symbolic debug info
13
13
14
+ /*
15
+ Some generic information for debug info on macOS:
16
+
17
+ The linker on macOS will remove any debug info, i.e. every section with the
18
+ `S_ATTR_DEBUG` flag, this includes everything in the `__DWARF` section. By using
19
+ the `S_REGULAR` flag the linker will not remove this section. This allows to get
20
+ the filenames and line numbers for backtraces from the executable.
21
+
22
+ Normally the linker removes all the debug info but adds a reference to the
23
+ object files. The debugger can then read the object files to get filename and
24
+ line number information. It's also possible to use an additional tool that
25
+ generates a separate `.dSYM` file. This file can then later be deployed with the
26
+ application if debug info is needed when the application is deployed.
27
+ */
28
+
14
29
#if !SPP
15
30
#include <stdio.h>
16
31
#include <string.h>
@@ -115,12 +130,12 @@ bool doUnwindEhFrame()
115
130
116
131
#define OFFSET_FAC REGSIZE
117
132
118
- int dwarf_getsegment (const char * name , int align )
133
+ int dwarf_getsegment (const char * name , int align , int flags )
119
134
{
120
135
#if ELFOBJ
121
- return ElfObj ::getsegment (name , NULL , SHT_PROGBITS , 0 , align * 4 );
136
+ return ElfObj ::getsegment (name , NULL , flags , 0 , align * 4 );
122
137
#elif MACHOBJ
123
- return MachObj ::getsegment (name , "__DWARF" , align * 2 , S_ATTR_DEBUG );
138
+ return MachObj ::getsegment (name , "__DWARF" , align * 2 , flags );
124
139
#else
125
140
assert (0 );
126
141
return 0 ;
@@ -458,12 +473,13 @@ struct Section
458
473
IDXSEC secidx ;
459
474
Outbuffer * buf ;
460
475
const char * name ;
476
+ int flags ;
461
477
462
478
/* Allocate and initialize Section
463
479
*/
464
480
void initialize ()
465
481
{
466
- const segidx_t segi = dwarf_getsegment (name , 0 );
482
+ const segidx_t segi = dwarf_getsegment (name , 0 , flags );
467
483
seg = segi ;
468
484
secidx = SegData [segi ]-> SDshtidx ;
469
485
buf = SegData [segi ]-> SDbuf ;
@@ -472,23 +488,25 @@ struct Section
472
488
};
473
489
474
490
#if MACHOBJ
475
- static Section debug_pubnames = { 0 ,0 ,0 , "__debug_pubnames" };
476
- static Section debug_aranges = { 0 ,0 ,0 , "__debug_aranges" };
477
- static Section debug_ranges = { 0 ,0 ,0 , "__debug_ranges" };
478
- static Section debug_loc = { 0 ,0 ,0 , "__debug_loc" };
479
- static Section debug_abbrev = { 0 ,0 ,0 , "__debug_abbrev" };
480
- static Section debug_info = { 0 ,0 ,0 , "__debug_info" };
481
- static Section debug_str = { 0 ,0 ,0 , "__debug_str" };
482
- static Section debug_line = { 0 ,0 ,0 , "__debug_line" };
491
+ static Section debug_pubnames = { 0 ,0 ,0 , "__debug_pubnames" , S_ATTR_DEBUG };
492
+ static Section debug_aranges = { 0 ,0 ,0 , "__debug_aranges" , S_ATTR_DEBUG };
493
+ static Section debug_ranges = { 0 ,0 ,0 , "__debug_ranges" , S_ATTR_DEBUG };
494
+ static Section debug_loc = { 0 ,0 ,0 , "__debug_loc" , S_ATTR_DEBUG };
495
+ static Section debug_abbrev = { 0 ,0 ,0 , "__debug_abbrev" , S_ATTR_DEBUG };
496
+ static Section debug_info = { 0 ,0 ,0 , "__debug_info" , S_ATTR_DEBUG };
497
+ static Section debug_str = { 0 ,0 ,0 , "__debug_str" , S_ATTR_DEBUG };
498
+ // We use S_REGULAR to make sure the linker doesn't remove this section. Needed
499
+ // for filenames and line numbers in backtraces.
500
+ static Section debug_line = { 0 ,0 ,0 , "__debug_line" , S_REGULAR };
483
501
#elif ELFOBJ
484
- static Section debug_pubnames = { 0 ,0 ,0 , ".debug_pubnames" };
485
- static Section debug_aranges = { 0 ,0 ,0 , ".debug_aranges" };
486
- static Section debug_ranges = { 0 ,0 ,0 , ".debug_ranges" };
487
- static Section debug_loc = { 0 ,0 ,0 , ".debug_loc" };
488
- static Section debug_abbrev = { 0 ,0 ,0 , ".debug_abbrev" };
489
- static Section debug_info = { 0 ,0 ,0 , ".debug_info" };
490
- static Section debug_str = { 0 ,0 ,0 , ".debug_str" };
491
- static Section debug_line = { 0 ,0 ,0 , ".debug_line" };
502
+ static Section debug_pubnames = { 0 ,0 ,0 , ".debug_pubnames" , SHT_PROGBITS };
503
+ static Section debug_aranges = { 0 ,0 ,0 , ".debug_aranges" , SHT_PROGBITS };
504
+ static Section debug_ranges = { 0 ,0 ,0 , ".debug_ranges" , SHT_PROGBITS };
505
+ static Section debug_loc = { 0 ,0 ,0 , ".debug_loc" , SHT_PROGBITS };
506
+ static Section debug_abbrev = { 0 ,0 ,0 , ".debug_abbrev" , SHT_PROGBITS };
507
+ static Section debug_info = { 0 ,0 ,0 , ".debug_info" , SHT_PROGBITS };
508
+ static Section debug_str = { 0 ,0 ,0 , ".debug_str" , SHT_PROGBITS };
509
+ static Section debug_line = { 0 ,0 ,0 , ".debug_line" , SHT_PROGBITS };
492
510
#endif
493
511
494
512
#if MACHOBJ
@@ -1012,7 +1030,12 @@ void dwarf_initfile(const char *filename)
1012
1030
return ;
1013
1031
if (config .ehmethod == EH_DM )
1014
1032
{
1015
- int seg = dwarf_getsegment (debug_frame_name , 1 );
1033
+ #if MACHOBJ
1034
+ int flags = S_ATTR_DEBUG ;
1035
+ #elif ELFOBJ
1036
+ int flags = SHT_PROGBITS ;
1037
+ #endif
1038
+ int seg = dwarf_getsegment (debug_frame_name , 1 , flags );
1016
1039
Outbuffer * buf = SegData [seg ]-> SDbuf ;
1017
1040
buf -> reserve (1000 );
1018
1041
writeDebugFrameHeader (buf );
@@ -1515,7 +1538,12 @@ void dwarf_func_term(Symbol *sfunc)
1515
1538
1516
1539
if (ehmethod (sfunc ) == EH_DM )
1517
1540
{
1518
- IDXSEC dfseg = dwarf_getsegment (debug_frame_name , 1 );
1541
+ #if MACHOBJ
1542
+ int flags = S_ATTR_DEBUG ;
1543
+ #elif ELFOBJ
1544
+ int flags = SHT_PROGBITS ;
1545
+ #endif
1546
+ IDXSEC dfseg = dwarf_getsegment (debug_frame_name , 1 , flags );
1519
1547
writeDebugFrameFDE (dfseg , sfunc );
1520
1548
}
1521
1549
0 commit comments