Commit eca41af0 authored by Alessandro Arzilli's avatar Alessandro Arzilli Committed by Heschi Kreinick

cmd/link: fix up debug_range for dsymutil (revert CL 72371)

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/98075Reviewed-by: 's avatarHeschi Kreinick <heschi@google.com>
parent 9dc351be
......@@ -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)
......
......@@ -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).
......
......@@ -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)
......
......@@ -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,
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment