]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: fix up debug_range for dsymutil (revert CL 72371)
authorAlessandro Arzilli <alessandro.arzilli@gmail.com>
Mon, 19 Feb 2018 14:26:49 +0000 (15:26 +0100)
committerHeschi Kreinick <heschi@google.com>
Fri, 2 Mar 2018 19:33:44 +0000 (19:33 +0000)
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 <heschi@google.com>
src/cmd/internal/dwarf/dwarf.go
src/cmd/internal/obj/data.go
src/cmd/internal/obj/objfile.go
src/cmd/link/internal/ld/dwarf.go
src/cmd/link/internal/sym/symbol.go

index 3b352aa5aab559c21c2ed47d2c18d598bb0fdcbd..303499db7c165d778e54da835ee16821581d40d9 100644 (file)
@@ -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)
index ce0dd09a4f0939ca4a74bc3c0e01e8cb2077038b..23d1809e0c146386a44341a7d0a2d9d0dd0a1831 100644 (file)
@@ -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).
index 2501bba663803bd771e17f6d91dfca181a6d7c89..b5f5790a5033b7de149ec04902baddbdcbc9fe46 100644 (file)
@@ -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)
index 6cf97379c0ce5ba2efe435e715bdd933d8d2de14..3a739fb3d56758640db74c8b164427bbded5772e 100644 (file)
@@ -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,
index 6faedf4fe277748da60d7b5ff2083ae38a9d4d3b..b3ff6c4e19079dc8fc658f5486d70623312eef6b 100644 (file)
@@ -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