From eca41af0124d4c6f29b571815ebcb25dd06fb324 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Mon, 19 Feb 2018 15:26:49 +0100 Subject: [PATCH] cmd/link: fix up debug_range for dsymutil (revert CL 72371) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Dsymutil, an utility used on macOS when externally linking executables, does not support base address selector entries in debug_ranges. CL 73271 worked around this problem by removing base address selectors and emitting CU-relative relocations for each list entry. This commit, as an optimization, reintroduces the base address selectors and changes the linker to remove them again, but only when it knows that it will have to invoke the external linker on macOS. Compilecmp comparing master with a branch that has scope tracking always enabled: completed 15 of 15, estimated time remaining 0s (eta 2:43PM) name old time/op new time/op delta Template 272ms ± 8% 257ms ± 5% -5.33% (p=0.000 n=15+14) Unicode 124ms ± 7% 122ms ± 5% ~ (p=0.210 n=14+14) GoTypes 873ms ± 3% 870ms ± 5% ~ (p=0.856 n=15+13) Compiler 4.49s ± 2% 4.49s ± 5% ~ (p=0.982 n=14+14) SSA 11.8s ± 4% 11.8s ± 3% ~ (p=0.653 n=15+15) Flate 163ms ± 6% 164ms ± 9% ~ (p=0.914 n=14+15) GoParser 203ms ± 6% 202ms ±10% ~ (p=0.571 n=14+14) Reflect 547ms ± 7% 542ms ± 4% ~ (p=0.914 n=15+14) Tar 244ms ± 7% 237ms ± 3% -2.80% (p=0.002 n=14+13) XML 289ms ± 6% 289ms ± 5% ~ (p=0.839 n=14+14) [Geo mean] 537ms 531ms -1.10% name old user-time/op new user-time/op delta Template 360ms ± 4% 341ms ± 7% -5.16% (p=0.000 n=14+14) Unicode 189ms ±11% 190ms ± 8% ~ (p=0.844 n=15+15) GoTypes 1.13s ± 4% 1.14s ± 7% ~ (p=0.582 n=15+14) Compiler 5.34s ± 2% 5.40s ± 4% +1.19% (p=0.036 n=11+13) SSA 14.7s ± 2% 14.7s ± 3% ~ (p=0.602 n=15+15) Flate 211ms ± 7% 214ms ± 8% ~ (p=0.252 n=14+14) GoParser 267ms ±12% 266ms ± 2% ~ (p=0.837 n=15+11) Reflect 706ms ± 4% 701ms ± 3% ~ (p=0.213 n=14+12) Tar 331ms ± 9% 320ms ± 5% -3.30% (p=0.025 n=15+14) XML 378ms ± 4% 373ms ± 6% ~ (p=0.253 n=14+15) [Geo mean] 704ms 700ms -0.58% name old alloc/op new alloc/op delta Template 38.0MB ± 0% 38.4MB ± 0% +1.12% (p=0.000 n=15+15) Unicode 28.8MB ± 0% 28.8MB ± 0% +0.17% (p=0.000 n=15+15) GoTypes 112MB ± 0% 114MB ± 0% +1.47% (p=0.000 n=15+15) Compiler 465MB ± 0% 473MB ± 0% +1.71% (p=0.000 n=15+15) SSA 1.48GB ± 0% 1.53GB ± 0% +3.07% (p=0.000 n=15+15) Flate 24.3MB ± 0% 24.7MB ± 0% +1.67% (p=0.000 n=15+15) GoParser 30.7MB ± 0% 31.0MB ± 0% +1.15% (p=0.000 n=12+15) Reflect 76.3MB ± 0% 77.1MB ± 0% +0.97% (p=0.000 n=15+15) Tar 39.2MB ± 0% 39.6MB ± 0% +0.91% (p=0.000 n=15+15) XML 41.5MB ± 0% 42.0MB ± 0% +1.29% (p=0.000 n=15+15) [Geo mean] 77.5MB 78.6MB +1.35% name old allocs/op new allocs/op delta Template 385k ± 0% 387k ± 0% +0.51% (p=0.000 n=15+15) Unicode 342k ± 0% 343k ± 0% +0.10% (p=0.000 n=14+15) GoTypes 1.19M ± 0% 1.19M ± 0% +0.62% (p=0.000 n=15+15) Compiler 4.51M ± 0% 4.54M ± 0% +0.50% (p=0.000 n=14+15) SSA 12.2M ± 0% 12.4M ± 0% +1.12% (p=0.000 n=14+15) Flate 234k ± 0% 236k ± 0% +0.60% (p=0.000 n=15+15) GoParser 318k ± 0% 320k ± 0% +0.60% (p=0.000 n=15+15) Reflect 974k ± 0% 977k ± 0% +0.27% (p=0.000 n=15+15) Tar 395k ± 0% 397k ± 0% +0.37% (p=0.000 n=14+15) XML 404k ± 0% 407k ± 0% +0.53% (p=0.000 n=15+15) [Geo mean] 794k 798k +0.52% name old text-bytes new text-bytes delta HelloSize 680kB ± 0% 680kB ± 0% ~ (all equal) name old data-bytes new data-bytes delta HelloSize 9.62kB ± 0% 9.62kB ± 0% ~ (all equal) name old bss-bytes new bss-bytes delta HelloSize 125kB ± 0% 125kB ± 0% ~ (all equal) name old exe-bytes new exe-bytes delta HelloSize 1.11MB ± 0% 1.13MB ± 0% +1.85% (p=0.000 n=15+15) Change-Id: I61c98ba0340cb798034b2bb55e3ab3a58ac1cf23 Reviewed-on: https://go-review.googlesource.com/98075 Reviewed-by: Heschi Kreinick --- src/cmd/internal/dwarf/dwarf.go | 18 +++++++----------- src/cmd/internal/obj/data.go | 20 ++++---------------- src/cmd/internal/obj/objfile.go | 5 ----- src/cmd/link/internal/ld/dwarf.go | 22 ++++++++++++---------- src/cmd/link/internal/sym/symbol.go | 12 ++---------- 5 files changed, 25 insertions(+), 52 deletions(-) diff --git a/src/cmd/internal/dwarf/dwarf.go b/src/cmd/internal/dwarf/dwarf.go index 3b352aa5aa..303499db7c 100644 --- a/src/cmd/internal/dwarf/dwarf.go +++ b/src/cmd/internal/dwarf/dwarf.go @@ -174,7 +174,6 @@ type Context interface { AddInt(s Sym, size int, i int64) AddBytes(s Sym, b []byte) AddAddress(s Sym, t interface{}, ofs int64) - AddCURelativeAddress(s Sym, t interface{}, ofs int64) AddSectionOffset(s Sym, size int, t interface{}, ofs int64) CurrentOffset(s Sym) int64 RecordDclReference(from Sym, to Sym, dclIdx int, inlIndex int) @@ -951,18 +950,15 @@ func PutIntConst(ctxt Context, info, typ Sym, name string, val int64) { // attribute). func PutRanges(ctxt Context, sym Sym, base Sym, ranges []Range) { ps := ctxt.PtrSize() + // Write base address entry. + if base != nil { + ctxt.AddInt(sym, ps, -1) + ctxt.AddAddress(sym, base, 0) + } // Write ranges. - // We do not emit base address entries here, even though they would reduce - // the number of relocations, because dsymutil (which is used on macOS when - // linking externally) does not support them. for _, r := range ranges { - if base == nil { - ctxt.AddInt(sym, ps, r.Start) - ctxt.AddInt(sym, ps, r.End) - } else { - ctxt.AddCURelativeAddress(sym, base, r.Start) - ctxt.AddCURelativeAddress(sym, base, r.End) - } + ctxt.AddInt(sym, ps, r.Start) + ctxt.AddInt(sym, ps, r.End) } // Write trailer. ctxt.AddInt(sym, ps, 0) diff --git a/src/cmd/internal/obj/data.go b/src/cmd/internal/obj/data.go index ce0dd09a4f..23d1809e0c 100644 --- a/src/cmd/internal/obj/data.go +++ b/src/cmd/internal/obj/data.go @@ -117,7 +117,9 @@ func (s *LSym) WriteInt(ctxt *Link, off int64, siz int, i int64) { } } -func (s *LSym) writeAddr(ctxt *Link, off int64, siz int, rsym *LSym, roff int64, rtype objabi.RelocType) { +// WriteAddr writes an address of size siz into s at offset off. +// rsym and roff specify the relocation for the address. +func (s *LSym) WriteAddr(ctxt *Link, off int64, siz int, rsym *LSym, roff int64) { // Allow 4-byte addresses for DWARF. if siz != ctxt.Arch.PtrSize && siz != 4 { ctxt.Diag("WriteAddr: bad address size %d in %s", siz, s.Name) @@ -130,24 +132,10 @@ func (s *LSym) writeAddr(ctxt *Link, off int64, siz int, rsym *LSym, roff int64, } r.Siz = uint8(siz) r.Sym = rsym - r.Type = rtype + r.Type = objabi.R_ADDR r.Add = roff } -// WriteAddr writes an address of size siz into s at offset off. -// rsym and roff specify the relocation for the address. -func (s *LSym) WriteAddr(ctxt *Link, off int64, siz int, rsym *LSym, roff int64) { - s.writeAddr(ctxt, off, siz, rsym, roff, objabi.R_ADDR) -} - -// WriteCURelativeAddr writes a pointer-sized address into s at offset off. -// rsym and roff specify the relocation for the address which will be -// resolved by the linker to an offset from the DW_AT_low_pc attribute of -// the DWARF Compile Unit of rsym. -func (s *LSym) WriteCURelativeAddr(ctxt *Link, off int64, rsym *LSym, roff int64) { - s.writeAddr(ctxt, off, ctxt.Arch.PtrSize, rsym, roff, objabi.R_ADDRCUOFF) -} - // WriteOff writes a 4 byte offset to rsym+roff into s at offset off. // After linking the 4 bytes stored at s+off will be // rsym+roff-(start of section that s is in). diff --git a/src/cmd/internal/obj/objfile.go b/src/cmd/internal/obj/objfile.go index 2501bba663..b5f5790a50 100644 --- a/src/cmd/internal/obj/objfile.go +++ b/src/cmd/internal/obj/objfile.go @@ -456,11 +456,6 @@ func (c dwCtxt) AddAddress(s dwarf.Sym, data interface{}, value int64) { ls.WriteInt(c.Link, ls.Size, size, value) } } -func (c dwCtxt) AddCURelativeAddress(s dwarf.Sym, data interface{}, value int64) { - ls := s.(*LSym) - rsym := data.(*LSym) - ls.WriteCURelativeAddr(c.Link, ls.Size, rsym, value) -} func (c dwCtxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64) { ls := s.(*LSym) rsym := t.(*LSym) diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go index 6cf97379c0..3a739fb3d5 100644 --- a/src/cmd/link/internal/ld/dwarf.go +++ b/src/cmd/link/internal/ld/dwarf.go @@ -49,13 +49,6 @@ func (c dwctxt) AddAddress(s dwarf.Sym, data interface{}, value int64) { s.(*sym.Symbol).AddAddrPlus(c.linkctxt.Arch, data.(*sym.Symbol), value) } -func (c dwctxt) AddCURelativeAddress(s dwarf.Sym, data interface{}, value int64) { - if value != 0 { - value -= (data.(*sym.Symbol)).Value - } - s.(*sym.Symbol).AddCURelativeAddrPlus(c.linkctxt.Arch, data.(*sym.Symbol), value) -} - func (c dwctxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64) { ls := s.(*sym.Symbol) switch size { @@ -1481,6 +1474,11 @@ func writeranges(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol { } rangeSym.Attr |= sym.AttrReachable | sym.AttrNotInSymbolTable rangeSym.Type = sym.SDWARFRANGE + // LLVM doesn't support base address entries. Strip them out so LLDB and dsymutil don't get confused. + if ctxt.HeadType == objabi.Hdarwin { + fn := ctxt.Syms.ROLookup(dwarf.InfoPrefix+s.Name, int(s.Version)) + removeDwarfAddrListBaseAddress(ctxt, fn, rangeSym, false) + } syms = append(syms, rangeSym) } return syms @@ -1761,7 +1759,7 @@ func collectlocs(ctxt *Link, syms []*sym.Symbol, units []*compilationUnit) []*sy empty = false // LLVM doesn't support base address entries. Strip them out so LLDB and dsymutil don't get confused. if ctxt.HeadType == objabi.Hdarwin { - removeLocationListBaseAddress(ctxt, fn, reloc.Sym) + removeDwarfAddrListBaseAddress(ctxt, fn, reloc.Sym, true) } // One location list entry per function, but many relocations to it. Don't duplicate. break @@ -1779,7 +1777,9 @@ func collectlocs(ctxt *Link, syms []*sym.Symbol, units []*compilationUnit) []*sy return syms } -func removeLocationListBaseAddress(ctxt *Link, info, list *sym.Symbol) { +// removeDwarfAddrListBaseAddress removes base address selector entries from +// DWARF location lists and range lists. +func removeDwarfAddrListBaseAddress(ctxt *Link, info, list *sym.Symbol, isloclist bool) { // The list symbol contains multiple lists, but they're all for the // same function, and it's not empty. fn := list.R[0].Sym @@ -1820,7 +1820,9 @@ func removeLocationListBaseAddress(ctxt *Link, info, list *sym.Symbol) { // Skip past the actual location. i += ctxt.Arch.PtrSize * 2 - i += 2 + int(ctxt.Arch.ByteOrder.Uint16(list.P[i:])) + if isloclist { + i += 2 + int(ctxt.Arch.ByteOrder.Uint16(list.P[i:])) + } } // Rewrite the DIE's relocations to point to the first location entry, diff --git a/src/cmd/link/internal/sym/symbol.go b/src/cmd/link/internal/sym/symbol.go index 6faedf4fe2..b3ff6c4e19 100644 --- a/src/cmd/link/internal/sym/symbol.go +++ b/src/cmd/link/internal/sym/symbol.go @@ -133,7 +133,7 @@ func (s *Symbol) SetUint(arch *sys.Arch, r int64, v uint64) int64 { return s.setUintXX(arch, r, v, int64(arch.PtrSize)) } -func (s *Symbol) addAddrPlus(arch *sys.Arch, t *Symbol, add int64, typ objabi.RelocType) int64 { +func (s *Symbol) AddAddrPlus(arch *sys.Arch, t *Symbol, add int64) int64 { if s.Type == 0 { s.Type = SDATA } @@ -145,19 +145,11 @@ func (s *Symbol) addAddrPlus(arch *sys.Arch, t *Symbol, add int64, typ objabi.Re r.Sym = t r.Off = int32(i) r.Siz = uint8(arch.PtrSize) - r.Type = typ + r.Type = objabi.R_ADDR r.Add = add return i + int64(r.Siz) } -func (s *Symbol) AddAddrPlus(arch *sys.Arch, t *Symbol, add int64) int64 { - return s.addAddrPlus(arch, t, add, objabi.R_ADDR) -} - -func (s *Symbol) AddCURelativeAddrPlus(arch *sys.Arch, t *Symbol, add int64) int64 { - return s.addAddrPlus(arch, t, add, objabi.R_ADDRCUOFF) -} - func (s *Symbol) AddPCRelPlus(arch *sys.Arch, t *Symbol, add int64) int64 { if s.Type == 0 { s.Type = SDATA -- 2.50.0