Skip to content

Commit be59731

Browse files
Ryan Brownrsc
Ryan Brown
authored andcommitted
cmd/internal/ld: output dwarf in external link mode on darwin
Fixes #8973 Change-Id: I746fae430db6d8f9ebd33586b8cffcb31d688cc8 Reviewed-on: https://go-review.googlesource.com/10284 Run-TryBot: Minux Ma <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Russ Cox <[email protected]>
1 parent 5b66e5d commit be59731

File tree

8 files changed

+528
-46
lines changed

8 files changed

+528
-46
lines changed

src/cmd/5l/asm.go

+6-8
Original file line numberDiff line numberDiff line change
@@ -533,14 +533,12 @@ func asmb() {
533533
fmt.Fprintf(&ld.Bso, "%5.2f dwarf\n", obj.Cputime())
534534
}
535535

536-
if ld.Debug['w'] == 0 { // TODO(minux): enable DWARF Support
537-
dwarfoff := uint32(ld.Rnd(int64(uint64(ld.HEADR)+ld.Segtext.Length), int64(ld.INITRND)) + ld.Rnd(int64(ld.Segdata.Filelen), int64(ld.INITRND)))
538-
ld.Cseek(int64(dwarfoff))
536+
dwarfoff := uint32(ld.Rnd(int64(uint64(ld.HEADR)+ld.Segtext.Length), int64(ld.INITRND)) + ld.Rnd(int64(ld.Segdata.Filelen), int64(ld.INITRND)))
537+
ld.Cseek(int64(dwarfoff))
539538

540-
ld.Segdwarf.Fileoff = uint64(ld.Cpos())
541-
ld.Dwarfemitdebugsections()
542-
ld.Segdwarf.Filelen = uint64(ld.Cpos()) - ld.Segdwarf.Fileoff
543-
}
539+
ld.Segdwarf.Fileoff = uint64(ld.Cpos())
540+
ld.Dwarfemitdebugsections()
541+
ld.Segdwarf.Filelen = uint64(ld.Cpos()) - ld.Segdwarf.Fileoff
544542

545543
machlink = uint32(ld.Domacholink())
546544
}
@@ -567,7 +565,7 @@ func asmb() {
567565
symo = uint32(ld.Segdata.Fileoff + ld.Segdata.Filelen)
568566

569567
case obj.Hdarwin:
570-
symo = uint32(ld.Rnd(int64(uint64(ld.HEADR)+ld.Segtext.Filelen), int64(ld.INITRND)) + ld.Rnd(int64(ld.Segdata.Filelen), int64(ld.INITRND)) + int64(machlink))
568+
symo = uint32(ld.Segdwarf.Fileoff + uint64(ld.Rnd(int64(ld.Segdwarf.Filelen), int64(ld.INITRND))) + uint64(machlink))
571569
}
572570

573571
ld.Cseek(int64(symo))

src/cmd/6l/asm.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ func asmb() {
710710
symo = int64(ld.Segdata.Fileoff + ld.Segdata.Filelen)
711711

712712
case obj.Hdarwin:
713-
symo = int64(ld.Segdata.Fileoff + uint64(ld.Rnd(int64(ld.Segdata.Filelen), int64(ld.INITRND))) + uint64(machlink))
713+
symo = int64(ld.Segdwarf.Fileoff + uint64(ld.Rnd(int64(ld.Segdwarf.Filelen), int64(ld.INITRND))) + uint64(machlink))
714714

715715
case obj.Hlinux,
716716
obj.Hfreebsd,

src/cmd/7l/asm.go

+6-8
Original file line numberDiff line numberDiff line change
@@ -317,14 +317,12 @@ func asmb() {
317317
fmt.Fprintf(&ld.Bso, "%5.2f dwarf\n", obj.Cputime())
318318
}
319319

320-
if ld.Debug['w'] == 0 { // TODO(minux): enable DWARF Support
321-
dwarfoff := uint32(ld.Rnd(int64(uint64(ld.HEADR)+ld.Segtext.Length), int64(ld.INITRND)) + ld.Rnd(int64(ld.Segdata.Filelen), int64(ld.INITRND)))
322-
ld.Cseek(int64(dwarfoff))
320+
dwarfoff := uint32(ld.Rnd(int64(uint64(ld.HEADR)+ld.Segtext.Length), int64(ld.INITRND)) + ld.Rnd(int64(ld.Segdata.Filelen), int64(ld.INITRND)))
321+
ld.Cseek(int64(dwarfoff))
323322

324-
ld.Segdwarf.Fileoff = uint64(ld.Cpos())
325-
ld.Dwarfemitdebugsections()
326-
ld.Segdwarf.Filelen = uint64(ld.Cpos()) - ld.Segdwarf.Fileoff
327-
}
323+
ld.Segdwarf.Fileoff = uint64(ld.Cpos())
324+
ld.Dwarfemitdebugsections()
325+
ld.Segdwarf.Filelen = uint64(ld.Cpos()) - ld.Segdwarf.Fileoff
328326

329327
machlink = uint32(ld.Domacholink())
330328
}
@@ -351,7 +349,7 @@ func asmb() {
351349
symo = uint32(ld.Segdata.Fileoff + ld.Segdata.Filelen)
352350

353351
case obj.Hdarwin:
354-
symo = uint32(ld.Rnd(int64(uint64(ld.HEADR)+ld.Segtext.Filelen), int64(ld.INITRND)) + ld.Rnd(int64(ld.Segdata.Filelen), int64(ld.INITRND)) + int64(machlink))
352+
symo = uint32(ld.Segdwarf.Fileoff + uint64(ld.Rnd(int64(ld.Segdwarf.Filelen), int64(ld.INITRND))) + uint64(machlink))
355353
}
356354

357355
ld.Cseek(int64(symo))

src/cmd/8l/asm.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ func asmb() {
551551
symo = uint32(ld.Segdata.Fileoff + ld.Segdata.Filelen)
552552

553553
case obj.Hdarwin:
554-
symo = uint32(ld.Segdata.Fileoff + uint64(ld.Rnd(int64(ld.Segdata.Filelen), int64(ld.INITRND))) + uint64(machlink))
554+
symo = uint32(ld.Segdwarf.Fileoff + uint64(ld.Rnd(int64(ld.Segdwarf.Filelen), int64(ld.INITRND))) + uint64(machlink))
555555

556556
case obj.Hwindows:
557557
symo = uint32(ld.Segdata.Fileoff + ld.Segdata.Filelen)

src/cmd/internal/ld/dwarf.go

+120-24
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package ld
1717
import (
1818
"cmd/internal/obj"
1919
"fmt"
20+
"os"
2021
"strings"
2122
)
2223

@@ -240,6 +241,7 @@ var abbrevs = [DW_NABRV]DWAbbrev{
240241
{DW_AT_low_pc, DW_FORM_addr},
241242
{DW_AT_high_pc, DW_FORM_addr},
242243
{DW_AT_stmt_list, DW_FORM_data4},
244+
{DW_AT_comp_dir, DW_FORM_string},
243245
},
244246
},
245247

@@ -694,6 +696,9 @@ func adddwarfrel(sec *LSym, sym *LSym, offsetbase int64, siz int, addend int64)
694696
if Iself && Thearch.Thechar == '6' {
695697
addend = 0
696698
}
699+
if HEADTYPE == obj.Hdarwin {
700+
addend += sym.Value
701+
}
697702
switch siz {
698703
case 4:
699704
Thearch.Lput(uint32(addend))
@@ -1547,6 +1552,13 @@ func flushunit(dwinfo *DWDie, pc int64, pcsym *LSym, unitstart int64, header_len
15471552
}
15481553
}
15491554

1555+
func getCompilationDir() string {
1556+
if dir, err := os.Getwd(); err == nil {
1557+
return dir
1558+
}
1559+
return "/"
1560+
}
1561+
15501562
func writelines() {
15511563
if linesec == nil {
15521564
linesec = Linklookup(Ctxt, ".dwarfline", 0)
@@ -1571,6 +1583,9 @@ func writelines() {
15711583
newattr(dwinfo, DW_AT_language, DW_CLS_CONSTANT, int64(lang), 0)
15721584
newattr(dwinfo, DW_AT_stmt_list, DW_CLS_PTR, unitstart-lineo, 0)
15731585
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)
15741589

15751590
// Write .debug_line Line Number Program Header (sec 6.2.4)
15761591
// Fields marked with (*) must be changed for 64-bit dwarf
@@ -2083,6 +2098,14 @@ func writedwarfreloc(s *LSym) int64 {
20832098
return start
20842099
}
20852100

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+
20862109
/*
20872110
* This is the main entry point for generating dwarf. After emitting
20882111
* the mandatory debug_abbrev section, it calls writelines() to set up
@@ -2097,8 +2120,33 @@ func Dwarfemitdebugsections() {
20972120
return
20982121
}
20992122

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+
}
21022150
}
21032151

21042152
// For diagnostic messages.
@@ -2191,6 +2239,15 @@ func Dwarfemitdebugsections() {
21912239
for Cpos()&7 != 0 {
21922240
Cput(0)
21932241
}
2242+
if HEADTYPE != obj.Hdarwin {
2243+
dwarfemitreloc()
2244+
}
2245+
}
2246+
2247+
func dwarfemitreloc() {
2248+
if Debug['w'] != 0 { // disable dwarf
2249+
return
2250+
}
21942251
inforeloco = writedwarfreloc(infosec)
21952252
inforelocsize = Cpos() - inforeloco
21962253
align(inforelocsize)
@@ -2420,14 +2477,15 @@ func dwarfaddelfheaders() {
24202477
/*
24212478
* Macho
24222479
*/
2423-
func dwarfaddmachoheaders() {
2480+
func dwarfaddmachoheaders(ms *MachoSeg) {
24242481
if Debug['w'] != 0 { // disable dwarf
24252482
return
24262483
}
24272484

24282485
// Zero vsize segments won't be loaded in memory, even so they
24292486
// 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
24312489

24322490
nsect := 4
24332491
if pubnamessize > 0 {
@@ -2443,66 +2501,104 @@ func dwarfaddmachoheaders() {
24432501
nsect++
24442502
}
24452503

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+
}
24502510

24512511
msect := newMachoSect(ms, "__debug_abbrev", "__DWARF")
24522512
msect.off = uint32(abbrevo)
24532513
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+
}
24562520

24572521
msect = newMachoSect(ms, "__debug_line", "__DWARF")
24582522
msect.off = uint32(lineo)
24592523
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+
}
24622534

24632535
msect = newMachoSect(ms, "__debug_frame", "__DWARF")
24642536
msect.off = uint32(frameo)
24652537
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+
}
24682548

24692549
msect = newMachoSect(ms, "__debug_info", "__DWARF")
24702550
msect.off = uint32(infoo)
24712551
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+
}
24742562

24752563
if pubnamessize > 0 {
24762564
msect := newMachoSect(ms, "__debug_pubnames", "__DWARF")
24772565
msect.off = uint32(pubnameso)
24782566
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
24812570
}
24822571

24832572
if pubtypessize > 0 {
24842573
msect := newMachoSect(ms, "__debug_pubtypes", "__DWARF")
24852574
msect.off = uint32(pubtypeso)
24862575
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
24892579
}
24902580

24912581
if arangessize > 0 {
24922582
msect := newMachoSect(ms, "__debug_aranges", "__DWARF")
24932583
msect.off = uint32(arangeso)
24942584
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+
}
24972592
}
24982593

24992594
// TODO(lvd) fix gdb/python to load MachO (16 char section name limit)
25002595
if gdbscriptsize > 0 {
25012596
msect := newMachoSect(ms, "__debug_gdb_scripts", "__DWARF")
25022597
msect.off = uint32(gdbscripto)
25032598
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
25062602
}
25072603
}
25082604

src/cmd/internal/ld/lib.go

+20-1
Original file line numberDiff line numberDiff line change
@@ -922,7 +922,7 @@ func hostlink() {
922922
}
923923

924924
if HEADTYPE == obj.Hdarwin {
925-
argv = append(argv, "-Wl,-no_pie,-pagezero_size,4000000")
925+
argv = append(argv, "-Wl,-no_pie,-pagezero_size,4000000,-headerpad,1144")
926926
}
927927
if HEADTYPE == obj.Hopenbsd {
928928
argv = append(argv, "-Wl,-nopie")
@@ -1029,6 +1029,25 @@ func hostlink() {
10291029
if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil {
10301030
Exitf("running %s failed: %v\n%s", argv[0], err, out)
10311031
}
1032+
1033+
if Debug['s'] == 0 && debug_s == 0 && HEADTYPE == obj.Hdarwin {
1034+
dsym := fmt.Sprintf("%s/go.dwarf", tmpdir)
1035+
if out, err := exec.Command("dsymutil", "-f", outfile, "-o", dsym).CombinedOutput(); err != nil {
1036+
Ctxt.Cursym = nil
1037+
Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out)
1038+
}
1039+
combinedOutput := fmt.Sprintf("%s/go.combined", tmpdir)
1040+
if err := machoCombineDwarf(outfile, dsym, combinedOutput); err != nil {
1041+
Ctxt.Cursym = nil
1042+
Exitf("%s: combining dwarf failed: %v", os.Args[0], err)
1043+
}
1044+
origOutput := fmt.Sprintf("%s/go.orig", tmpdir)
1045+
os.Rename(outfile, origOutput)
1046+
if err := os.Rename(combinedOutput, outfile); err != nil {
1047+
Ctxt.Cursym = nil
1048+
Exitf("%s: rename(%s, %s) failed: %v", os.Args[0], combinedOutput, outfile, err)
1049+
}
1050+
}
10321051
}
10331052

10341053
func ldobj(f *obj.Biobuf, pkg string, length int64, pn string, file string, whence int) {

src/cmd/internal/ld/macho.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,8 @@ func Asmbmacho() {
443443
ms = newMachoSeg("", 40)
444444

445445
ms.fileoffset = Segtext.Fileoff
446-
ms.filesize = Segdata.Fileoff + Segdata.Filelen - Segtext.Fileoff
446+
ms.filesize = Segdwarf.Fileoff + Segdwarf.Filelen - Segtext.Fileoff
447+
ms.vsize = ms.filesize
447448
}
448449

449450
/* segment for zero page */
@@ -561,8 +562,8 @@ func Asmbmacho() {
561562
}
562563

563564
// TODO: dwarf headers go in ms too
564-
if Debug['s'] == 0 && Linkmode != LinkExternal {
565-
dwarfaddmachoheaders()
565+
if Debug['s'] == 0 {
566+
dwarfaddmachoheaders(ms)
566567
}
567568

568569
a := machowrite()
@@ -850,4 +851,5 @@ func Machoemitreloc() {
850851
for sect := Segdata.Sect; sect != nil; sect = sect.Next {
851852
machorelocsect(sect, datap)
852853
}
854+
dwarfemitreloc()
853855
}

0 commit comments

Comments
 (0)