@@ -17,6 +17,7 @@ package ld
17
17
import (
18
18
"cmd/internal/obj"
19
19
"fmt"
20
+ "os"
20
21
"strings"
21
22
)
22
23
@@ -240,6 +241,7 @@ var abbrevs = [DW_NABRV]DWAbbrev{
240
241
{DW_AT_low_pc , DW_FORM_addr },
241
242
{DW_AT_high_pc , DW_FORM_addr },
242
243
{DW_AT_stmt_list , DW_FORM_data4 },
244
+ {DW_AT_comp_dir , DW_FORM_string },
243
245
},
244
246
},
245
247
@@ -694,6 +696,9 @@ func adddwarfrel(sec *LSym, sym *LSym, offsetbase int64, siz int, addend int64)
694
696
if Iself && Thearch .Thechar == '6' {
695
697
addend = 0
696
698
}
699
+ if HEADTYPE == obj .Hdarwin {
700
+ addend += sym .Value
701
+ }
697
702
switch siz {
698
703
case 4 :
699
704
Thearch .Lput (uint32 (addend ))
@@ -1547,6 +1552,13 @@ func flushunit(dwinfo *DWDie, pc int64, pcsym *LSym, unitstart int64, header_len
1547
1552
}
1548
1553
}
1549
1554
1555
+ func getCompilationDir () string {
1556
+ if dir , err := os .Getwd (); err == nil {
1557
+ return dir
1558
+ }
1559
+ return "/"
1560
+ }
1561
+
1550
1562
func writelines () {
1551
1563
if linesec == nil {
1552
1564
linesec = Linklookup (Ctxt , ".dwarfline" , 0 )
@@ -1571,6 +1583,9 @@ func writelines() {
1571
1583
newattr (dwinfo , DW_AT_language , DW_CLS_CONSTANT , int64 (lang ), 0 )
1572
1584
newattr (dwinfo , DW_AT_stmt_list , DW_CLS_PTR , unitstart - lineo , 0 )
1573
1585
newattr (dwinfo , DW_AT_low_pc , DW_CLS_ADDRESS , s .Value , s )
1586
+ // OS X linker requires compilation dir or absolute path in comp unit name to output debug info.
1587
+ compDir := getCompilationDir ()
1588
+ newattr (dwinfo , DW_AT_comp_dir , DW_CLS_STRING , int64 (len (compDir )), compDir )
1574
1589
1575
1590
// Write .debug_line Line Number Program Header (sec 6.2.4)
1576
1591
// Fields marked with (*) must be changed for 64-bit dwarf
@@ -2083,6 +2098,14 @@ func writedwarfreloc(s *LSym) int64 {
2083
2098
return start
2084
2099
}
2085
2100
2101
+ func addmachodwarfsect (prev * Section , name string ) * Section {
2102
+ sect := addsection (& Segdwarf , name , 04 )
2103
+ sect .Extnum = prev .Extnum + 1
2104
+ sym := Linklookup (Ctxt , name , 0 )
2105
+ sym .Sect = sect
2106
+ return sect
2107
+ }
2108
+
2086
2109
/*
2087
2110
* This is the main entry point for generating dwarf. After emitting
2088
2111
* the mandatory debug_abbrev section, it calls writelines() to set up
@@ -2097,8 +2120,33 @@ func Dwarfemitdebugsections() {
2097
2120
return
2098
2121
}
2099
2122
2100
- if Linkmode == LinkExternal && ! Iself {
2101
- return
2123
+ if Linkmode == LinkExternal {
2124
+ if ! Iself && HEADTYPE != obj .Hdarwin {
2125
+ return
2126
+ }
2127
+ if HEADTYPE == obj .Hdarwin {
2128
+ sect := Segdata .Sect
2129
+ // find the last section.
2130
+ for sect .Next != nil {
2131
+ sect = sect .Next
2132
+ }
2133
+ sect = addmachodwarfsect (sect , ".debug_abbrev" )
2134
+ sect = addmachodwarfsect (sect , ".debug_line" )
2135
+ sect = addmachodwarfsect (sect , ".debug_frame" )
2136
+ sect = addmachodwarfsect (sect , ".debug_info" )
2137
+
2138
+ infosym = Linklookup (Ctxt , ".debug_info" , 0 )
2139
+ infosym .Hide = 1
2140
+
2141
+ abbrevsym = Linklookup (Ctxt , ".debug_abbrev" , 0 )
2142
+ abbrevsym .Hide = 1
2143
+
2144
+ linesym = Linklookup (Ctxt , ".debug_line" , 0 )
2145
+ linesym .Hide = 1
2146
+
2147
+ framesym = Linklookup (Ctxt , ".debug_frame" , 0 )
2148
+ framesym .Hide = 1
2149
+ }
2102
2150
}
2103
2151
2104
2152
// For diagnostic messages.
@@ -2191,6 +2239,15 @@ func Dwarfemitdebugsections() {
2191
2239
for Cpos ()& 7 != 0 {
2192
2240
Cput (0 )
2193
2241
}
2242
+ if HEADTYPE != obj .Hdarwin {
2243
+ dwarfemitreloc ()
2244
+ }
2245
+ }
2246
+
2247
+ func dwarfemitreloc () {
2248
+ if Debug ['w' ] != 0 { // disable dwarf
2249
+ return
2250
+ }
2194
2251
inforeloco = writedwarfreloc (infosec )
2195
2252
inforelocsize = Cpos () - inforeloco
2196
2253
align (inforelocsize )
@@ -2420,14 +2477,15 @@ func dwarfaddelfheaders() {
2420
2477
/*
2421
2478
* Macho
2422
2479
*/
2423
- func dwarfaddmachoheaders () {
2480
+ func dwarfaddmachoheaders (ms * MachoSeg ) {
2424
2481
if Debug ['w' ] != 0 { // disable dwarf
2425
2482
return
2426
2483
}
2427
2484
2428
2485
// Zero vsize segments won't be loaded in memory, even so they
2429
2486
// have to be page aligned in the file.
2430
- fakestart := abbrevo &^ 0xfff
2487
+ fakestart := Rnd (int64 (Segdwarf .Fileoff ), 0x1000 )
2488
+ addr := Segdata .Vaddr + Segdata .Length
2431
2489
2432
2490
nsect := 4
2433
2491
if pubnamessize > 0 {
@@ -2443,66 +2501,104 @@ func dwarfaddmachoheaders() {
2443
2501
nsect ++
2444
2502
}
2445
2503
2446
- ms := newMachoSeg ("__DWARF" , nsect )
2447
- ms .fileoffset = uint64 (fakestart )
2448
- ms .filesize = uint64 (abbrevo ) - uint64 (fakestart )
2449
- ms .vaddr = ms .fileoffset + Segdata .Vaddr - Segdata .Fileoff
2504
+ if Linkmode != LinkExternal {
2505
+ ms = newMachoSeg ("__DWARF" , nsect )
2506
+ ms .fileoffset = uint64 (fakestart )
2507
+ ms .filesize = Segdwarf .Filelen
2508
+ ms .vaddr = addr
2509
+ }
2450
2510
2451
2511
msect := newMachoSect (ms , "__debug_abbrev" , "__DWARF" )
2452
2512
msect .off = uint32 (abbrevo )
2453
2513
msect .size = uint64 (abbrevsize )
2454
- msect .addr = uint64 (msect .off ) + Segdata .Vaddr - Segdata .Fileoff
2455
- ms .filesize += msect .size
2514
+ msect .addr = addr
2515
+ addr += msect .size
2516
+ msect .flag = 0x02000000
2517
+ if abbrevsym != nil {
2518
+ abbrevsym .Value = int64 (msect .addr )
2519
+ }
2456
2520
2457
2521
msect = newMachoSect (ms , "__debug_line" , "__DWARF" )
2458
2522
msect .off = uint32 (lineo )
2459
2523
msect .size = uint64 (linesize )
2460
- msect .addr = uint64 (msect .off ) + Segdata .Vaddr - Segdata .Fileoff
2461
- ms .filesize += msect .size
2524
+ msect .addr = addr
2525
+ addr += msect .size
2526
+ msect .flag = 0x02000000
2527
+ if linesym != nil {
2528
+ linesym .Value = int64 (msect .addr )
2529
+ }
2530
+ if linerelocsize > 0 {
2531
+ msect .nreloc = uint32 (len (linesec .R ))
2532
+ msect .reloc = uint32 (linereloco )
2533
+ }
2462
2534
2463
2535
msect = newMachoSect (ms , "__debug_frame" , "__DWARF" )
2464
2536
msect .off = uint32 (frameo )
2465
2537
msect .size = uint64 (framesize )
2466
- msect .addr = uint64 (msect .off ) + Segdata .Vaddr - Segdata .Fileoff
2467
- ms .filesize += msect .size
2538
+ msect .addr = addr
2539
+ addr += msect .size
2540
+ msect .flag = 0x02000000
2541
+ if framesym != nil {
2542
+ framesym .Value = int64 (msect .addr )
2543
+ }
2544
+ if framerelocsize > 0 {
2545
+ msect .nreloc = uint32 (len (framesec .R ))
2546
+ msect .reloc = uint32 (framereloco )
2547
+ }
2468
2548
2469
2549
msect = newMachoSect (ms , "__debug_info" , "__DWARF" )
2470
2550
msect .off = uint32 (infoo )
2471
2551
msect .size = uint64 (infosize )
2472
- msect .addr = uint64 (msect .off ) + Segdata .Vaddr - Segdata .Fileoff
2473
- ms .filesize += msect .size
2552
+ msect .addr = addr
2553
+ addr += msect .size
2554
+ msect .flag = 0x02000000
2555
+ if infosym != nil {
2556
+ infosym .Value = int64 (msect .addr )
2557
+ }
2558
+ if inforelocsize > 0 {
2559
+ msect .nreloc = uint32 (len (infosec .R ))
2560
+ msect .reloc = uint32 (inforeloco )
2561
+ }
2474
2562
2475
2563
if pubnamessize > 0 {
2476
2564
msect := newMachoSect (ms , "__debug_pubnames" , "__DWARF" )
2477
2565
msect .off = uint32 (pubnameso )
2478
2566
msect .size = uint64 (pubnamessize )
2479
- msect .addr = uint64 (msect .off ) + Segdata .Vaddr - Segdata .Fileoff
2480
- ms .filesize += msect .size
2567
+ msect .addr = addr
2568
+ addr += msect .size
2569
+ msect .flag = 0x02000000
2481
2570
}
2482
2571
2483
2572
if pubtypessize > 0 {
2484
2573
msect := newMachoSect (ms , "__debug_pubtypes" , "__DWARF" )
2485
2574
msect .off = uint32 (pubtypeso )
2486
2575
msect .size = uint64 (pubtypessize )
2487
- msect .addr = uint64 (msect .off ) + Segdata .Vaddr - Segdata .Fileoff
2488
- ms .filesize += msect .size
2576
+ msect .addr = addr
2577
+ addr += msect .size
2578
+ msect .flag = 0x02000000
2489
2579
}
2490
2580
2491
2581
if arangessize > 0 {
2492
2582
msect := newMachoSect (ms , "__debug_aranges" , "__DWARF" )
2493
2583
msect .off = uint32 (arangeso )
2494
2584
msect .size = uint64 (arangessize )
2495
- msect .addr = uint64 (msect .off ) + Segdata .Vaddr - Segdata .Fileoff
2496
- ms .filesize += msect .size
2585
+ msect .addr = addr
2586
+ addr += msect .size
2587
+ msect .flag = 0x02000000
2588
+ if arangesrelocsize > 0 {
2589
+ msect .nreloc = uint32 (len (arangessec .R ))
2590
+ msect .reloc = uint32 (arangesreloco )
2591
+ }
2497
2592
}
2498
2593
2499
2594
// TODO(lvd) fix gdb/python to load MachO (16 char section name limit)
2500
2595
if gdbscriptsize > 0 {
2501
2596
msect := newMachoSect (ms , "__debug_gdb_scripts" , "__DWARF" )
2502
2597
msect .off = uint32 (gdbscripto )
2503
2598
msect .size = uint64 (gdbscriptsize )
2504
- msect .addr = uint64 (msect .off ) + Segdata .Vaddr - Segdata .Fileoff
2505
- ms .filesize += msect .size
2599
+ msect .addr = addr
2600
+ addr += msect .size
2601
+ msect .flag = 0x02000000
2506
2602
}
2507
2603
}
2508
2604
0 commit comments