]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: use new sym builders in macho loader
authorJeremy Faller <jeremy@golang.org>
Wed, 22 Jan 2020 20:24:39 +0000 (15:24 -0500)
committerJeremy Faller <jeremy@golang.org>
Tue, 28 Jan 2020 16:26:01 +0000 (16:26 +0000)
Change-Id: Ia055559d1eb12736d0bdd5a30103cd4b9788d36e
Reviewed-on: https://go-review.googlesource.com/c/go/+/215917
Run-TryBot: Jeremy Faller <jeremy@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/link/internal/ld/lib.go
src/cmd/link/internal/loader/loader.go
src/cmd/link/internal/loader/symbolbuilder.go
src/cmd/link/internal/loadmacho/ldmacho.go

index 3e79b92d750c970d364bb07f65e7df5aaf22cf06..c1b56276b0f7142b8e580b3b7b9290bc7cb003b9 100644 (file)
@@ -457,7 +457,8 @@ func (ctxt *Link) loadlib() {
        }
 
        // Process cgo directives (has to be done before host object loading).
-       ctxt.loadcgodirectives(ctxt.IsELF && *FlagNewLdElf)
+       newCgo := (ctxt.IsELF && *FlagNewLdElf) || ctxt.HeadType == objabi.Hdarwin
+       ctxt.loadcgodirectives(newCgo)
 
        // Conditionally load host objects, or setup for external linking.
        hostobjs(ctxt)
@@ -1888,7 +1889,7 @@ func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string,
                                Errorf(nil, "%v", err)
                                return
                        }
-                       ctxt.Textp = append(ctxt.Textp, textp...)
+                       ctxt.Textp2 = append(ctxt.Textp2, textp...)
                }
                return ldhostobj(ldmacho, ctxt.HeadType, f, pkg, length, pn, file)
        }
index f7bbd7a38fda109b222c599778661417f552b079..47393a95843cbcb1a15e6ac6e46739ac90761657 100644 (file)
@@ -674,6 +674,9 @@ func (l *Loader) NDef() int {
 
 // Returns the raw (unpatched) name of the i-th symbol.
 func (l *Loader) RawSymName(i Sym) string {
+       if ov, ok := l.overwrite[i]; ok {
+               i = ov
+       }
        if l.IsExternal(i) {
                if s := l.Syms[i]; s != nil {
                        return s.Name
@@ -904,7 +907,7 @@ func (l *Loader) AttrExternal(i Sym) bool {
 // symbol (see AttrExternal).
 func (l *Loader) SetAttrExternal(i Sym, v bool) {
        if i < l.extStart {
-               panic("tried to set external attr on non-external symbol")
+               panic(fmt.Sprintf("tried to set external attr on non-external symbol %q", l.RawSymName(i)))
        }
        if v {
                l.attrExternal.set(i - l.extStart)
@@ -2110,6 +2113,7 @@ func (l *Loader) copyAttributes(src Sym, dst Sym) {
        l.SetAttrSpecial(dst, l.AttrSpecial(src))
        l.SetAttrCgoExportDynamic(dst, l.AttrCgoExportDynamic(src))
        l.SetAttrCgoExportStatic(dst, l.AttrCgoExportStatic(src))
+       l.SetAttrReadOnly(dst, l.AttrReadOnly(src))
 }
 
 // migrateAttributes copies over all of the attributes of symbol 'src' to
@@ -2128,6 +2132,7 @@ func (l *Loader) migrateAttributes(src Sym, dst *sym.Symbol) {
        dst.Attr.Set(sym.AttrSpecial, l.AttrSpecial(src))
        dst.Attr.Set(sym.AttrCgoExportDynamic, l.AttrCgoExportDynamic(src))
        dst.Attr.Set(sym.AttrCgoExportStatic, l.AttrCgoExportStatic(src))
+       dst.Attr.Set(sym.AttrReadOnly, l.AttrReadOnly(src))
 
        // Convert outer/sub relationships
        if outer, ok := l.outer[src]; ok {
index a815a696171cada339f2a7a7f338564fefe81312..20646349c72fda875c94c28d95a4662f220b8091 100644 (file)
@@ -8,6 +8,7 @@ import (
        "cmd/internal/objabi"
        "cmd/internal/sys"
        "cmd/link/internal/sym"
+       "fmt"
 )
 
 // SymbolBuilder is a helper designed to help with the construction
@@ -47,7 +48,7 @@ func (l *Loader) MakeSymbolUpdater(symIdx Sym) (*SymbolBuilder, Sym) {
                symIdx = l.cloneToExternal(symIdx)
        }
        if l.Syms[symIdx] != nil {
-               panic("can't build if sym.Symbol already present")
+               panic(fmt.Sprintf("can't build if sym.Symbol %q already present", l.RawSymName(symIdx)))
        }
 
        // Construct updater and return.
@@ -58,24 +59,30 @@ func (l *Loader) MakeSymbolUpdater(symIdx Sym) (*SymbolBuilder, Sym) {
 
 // Getters for properties of the symbol we're working on.
 
-func (sb *SymbolBuilder) Sym() Sym           { return sb.symIdx }
-func (sb *SymbolBuilder) Name() string       { return sb.name }
-func (sb *SymbolBuilder) Version() int       { return sb.ver }
-func (sb *SymbolBuilder) Type() sym.SymKind  { return sb.kind }
-func (sb *SymbolBuilder) Size() int64        { return sb.size }
-func (sb *SymbolBuilder) Data() []byte       { return sb.data }
-func (sb *SymbolBuilder) Value() int64       { return sb.l.SymValue(sb.symIdx) }
-func (sb *SymbolBuilder) Align() int32       { return sb.l.SymAlign(sb.symIdx) }
-func (sb *SymbolBuilder) Localentry() uint8  { return sb.l.SymLocalentry(sb.symIdx) }
-func (sb *SymbolBuilder) Extname() string    { return sb.l.SymExtname(sb.symIdx) }
-func (sb *SymbolBuilder) Dynimplib() string  { return sb.l.SymDynimplib(sb.symIdx) }
-func (sb *SymbolBuilder) Dynimpvers() string { return sb.l.SymDynimpvers(sb.symIdx) }
+func (sb *SymbolBuilder) Sym() Sym               { return sb.symIdx }
+func (sb *SymbolBuilder) Name() string           { return sb.name }
+func (sb *SymbolBuilder) Version() int           { return sb.ver }
+func (sb *SymbolBuilder) Type() sym.SymKind      { return sb.kind }
+func (sb *SymbolBuilder) Size() int64            { return sb.size }
+func (sb *SymbolBuilder) Data() []byte           { return sb.data }
+func (sb *SymbolBuilder) Value() int64           { return sb.l.SymValue(sb.symIdx) }
+func (sb *SymbolBuilder) Align() int32           { return sb.l.SymAlign(sb.symIdx) }
+func (sb *SymbolBuilder) Localentry() uint8      { return sb.l.SymLocalentry(sb.symIdx) }
+func (sb *SymbolBuilder) OnList() bool           { return sb.l.AttrOnList(sb.symIdx) }
+func (sb *SymbolBuilder) External() bool         { return sb.l.AttrExternal(sb.symIdx) }
+func (sb *SymbolBuilder) Extname() string        { return sb.l.SymExtname(sb.symIdx) }
+func (sb *SymbolBuilder) CgoExportDynamic() bool { return sb.l.AttrCgoExportDynamic(sb.symIdx) }
+func (sb *SymbolBuilder) Dynimplib() string      { return sb.l.SymDynimplib(sb.symIdx) }
+func (sb *SymbolBuilder) Dynimpvers() string     { return sb.l.SymDynimpvers(sb.symIdx) }
+func (sb *SymbolBuilder) SubSym() Sym            { return sb.l.SubSym(sb.symIdx) }
 
 // Setters for symbol properties.
 
 func (sb *SymbolBuilder) SetType(kind sym.SymKind)   { sb.kind = kind }
 func (sb *SymbolBuilder) SetSize(size int64)         { sb.size = size }
 func (sb *SymbolBuilder) SetData(data []byte)        { sb.data = data }
+func (sb *SymbolBuilder) SetOnList(v bool)           { sb.l.SetAttrOnList(sb.symIdx, v) }
+func (sb *SymbolBuilder) SetExternal(v bool)         { sb.l.SetAttrExternal(sb.symIdx, v) }
 func (sb *SymbolBuilder) SetValue(v int64)           { sb.l.SetSymValue(sb.symIdx, v) }
 func (sb *SymbolBuilder) SetAlign(align int32)       { sb.l.SetSymAlign(sb.symIdx, align) }
 func (sb *SymbolBuilder) SetLocalentry(value uint8)  { sb.l.SetSymLocalentry(sb.symIdx, value) }
@@ -112,6 +119,22 @@ func (sb *SymbolBuilder) setReachable() {
        sb.l.SetAttrReachable(sb.symIdx, true)
 }
 
+func (sb *SymbolBuilder) ReadOnly() bool {
+       return sb.l.AttrReadOnly(sb.symIdx)
+}
+
+func (sb *SymbolBuilder) SetReadOnly(v bool) {
+       sb.l.SetAttrReadOnly(sb.symIdx, v)
+}
+
+func (sb *SymbolBuilder) DuplicateOK() bool {
+       return sb.l.AttrDuplicateOK(sb.symIdx)
+}
+
+func (sb *SymbolBuilder) SetDuplicateOK(v bool) {
+       sb.l.SetAttrDuplicateOK(sb.symIdx, v)
+}
+
 func (sb *SymbolBuilder) Outer() Sym {
        return sb.l.OuterSym(sb.symIdx)
 }
index e27701403e1d18dfb66780e1970370bb72a45345..6e74e0a07683c874a9ad8ef1c0bb843a53c9f983 100644 (file)
@@ -100,7 +100,7 @@ type ldMachoSect struct {
        flags   uint32
        res1    uint32
        res2    uint32
-       sym     *sym.Symbol
+       sym     loader.Sym
        rel     []ldMachoRel
 }
 
@@ -131,7 +131,7 @@ type ldMachoSym struct {
        desc    uint16
        kind    int8
        value   uint64
-       sym     *sym.Symbol
+       sym     loader.Sym
 }
 
 type ldMachoDysymtab struct {
@@ -423,8 +423,8 @@ func macholoadsym(m *ldMachoObj, symtab *ldMachoSymtab) int {
 
 // Load the Mach-O file pn from f.
 // Symbols are written into syms, and a slice of the text symbols is returned.
-func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader, pkg string, length int64, pn string) (textp []*sym.Symbol, err error) {
-       errorf := func(str string, args ...interface{}) ([]*sym.Symbol, error) {
+func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader, pkg string, length int64, pn string) (textp []loader.Sym, err error) {
+       errorf := func(str string, args ...interface{}) ([]loader.Sym, error) {
                return nil, fmt.Errorf("loadmacho: %v: %v", pn, fmt.Sprintf(str, args...))
        }
 
@@ -559,31 +559,31 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader,
                        continue
                }
                name := fmt.Sprintf("%s(%s/%s)", pkg, sect.segname, sect.name)
-               s := l.LookupOrCreate(name, localSymVersion)
-               if s.Type != 0 {
+               bld, s := l.MakeSymbolUpdater(l.LookupOrCreateSym(name, localSymVersion))
+               if bld.Type() != 0 {
                        return errorf("duplicate %s/%s", sect.segname, sect.name)
                }
 
                if sect.flags&0xff == 1 { // S_ZEROFILL
-                       s.P = make([]byte, sect.size)
+                       bld.SetData(make([]byte, sect.size))
                } else {
-                       s.Attr.Set(sym.AttrReadOnly, readOnly)
-                       s.P = dat[sect.addr-c.seg.vmaddr:][:sect.size]
+                       bld.SetReadOnly(readOnly)
+                       bld.SetData(dat[sect.addr-c.seg.vmaddr:][:sect.size])
                }
-               s.Size = int64(len(s.P))
+               bld.SetSize(int64(len(bld.Data())))
 
                if sect.segname == "__TEXT" {
                        if sect.name == "__text" {
-                               s.Type = sym.STEXT
+                               bld.SetType(sym.STEXT)
                        } else {
-                               s.Type = sym.SRODATA
+                               bld.SetType(sym.SRODATA)
                        }
                } else {
                        if sect.name == "__bss" {
-                               s.Type = sym.SNOPTRBSS
-                               s.P = s.P[:0]
+                               bld.SetType(sym.SNOPTRBSS)
+                               bld.SetData(nil)
                        } else {
-                               s.Type = sym.SNOPTRDATA
+                               bld.SetType(sym.SNOPTRDATA)
                        }
                }
 
@@ -608,12 +608,12 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader,
                if machsym.type_&N_EXT == 0 {
                        v = localSymVersion
                }
-               s := l.LookupOrCreate(name, v)
+               s := l.LookupOrCreateSym(name, v)
                if machsym.type_&N_EXT == 0 {
-                       s.Attr |= sym.AttrDuplicateOK
+                       l.SetAttrDuplicateOK(s, true)
                }
                if machsym.desc&(N_WEAK_REF|N_WEAK_DEF) != 0 {
-                       s.Attr |= sym.AttrDuplicateOK
+                       l.SetAttrDuplicateOK(s, true)
                }
                machsym.sym = s
                if machsym.sectnum == 0 { // undefined
@@ -624,69 +624,72 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader,
                }
 
                sect := &c.seg.sect[machsym.sectnum-1]
+               bld, bldSym := l.MakeSymbolUpdater(s)
                outer := sect.sym
-               if outer == nil {
+               if outer == 0 {
                        continue // ignore reference to invalid section
                }
 
-               if s.Outer != nil {
-                       if s.Attr.DuplicateOK() {
+               if osym := l.OuterSym(s); osym != 0 {
+                       if l.AttrDuplicateOK(s) {
                                continue
                        }
-                       return errorf("duplicate symbol reference: %s in both %s and %s", s.Name, s.Outer.Name, sect.sym.Name)
+                       return errorf("duplicate symbol reference: %s in both %s and %s", l.SymName(s), l.SymName(osym), l.SymName(sect.sym))
                }
 
-               s.Type = outer.Type
-               s.Attr |= sym.AttrSubSymbol
-               s.Sub = outer.Sub
-               outer.Sub = s
-               s.Outer = outer
-               s.Value = int64(machsym.value - sect.addr)
-               if !s.Attr.CgoExportDynamic() {
-                       s.SetDynimplib("") // satisfy dynimport
+               bld.SetType(l.SymType(outer))
+               l.PrependSub(outer, bldSym)
+
+               bld.SetValue(int64(machsym.value - sect.addr))
+               if !l.AttrCgoExportDynamic(s) {
+                       bld.SetDynimplib("") // satisfy dynimport
                }
-               if outer.Type == sym.STEXT {
-                       if s.Attr.External() && !s.Attr.DuplicateOK() {
+               if l.SymType(outer) == sym.STEXT {
+                       if bld.External() && !bld.DuplicateOK() {
                                return errorf("%v: duplicate symbol definition", s)
                        }
-                       s.Attr |= sym.AttrExternal
+                       bld.SetExternal(true)
                }
 
-               machsym.sym = s
+               machsym.sym = bldSym
        }
 
        // Sort outer lists by address, adding to textp.
        // This keeps textp in increasing address order.
        for i := 0; uint32(i) < c.seg.nsect; i++ {
                sect := &c.seg.sect[i]
-               s := sect.sym
-               if s == nil {
+               sectSym := sect.sym
+               if sectSym == 0 {
                        continue
                }
-               if s.Sub != nil {
-                       s.Sub = sym.SortSub(s.Sub)
+               bld, s := l.MakeSymbolUpdater(sectSym)
+               if bld.SubSym() != 0 {
+
+                       bld.SortSub()
 
                        // assign sizes, now that we know symbols in sorted order.
-                       for s1 := s.Sub; s1 != nil; s1 = s1.Sub {
-                               if s1.Sub != nil {
-                                       s1.Size = s1.Sub.Value - s1.Value
+                       for s1 := bld.Sub(); s1 != 0; s1 = l.SubSym(s1) {
+                               s1Bld, _ := l.MakeSymbolUpdater(s1)
+                               if sub := l.SubSym(s1); sub != 0 {
+                                       s1Bld.SetSize(l.SymValue(sub) - l.SymValue(s1))
                                } else {
-                                       s1.Size = s.Value + s.Size - s1.Value
+                                       dlen := int64(len(l.Data(s)))
+                                       s1Bld.SetSize(l.SymValue(s) + dlen - l.SymValue(s1))
                                }
                        }
                }
 
-               if s.Type == sym.STEXT {
-                       if s.Attr.OnList() {
-                               return errorf("symbol %s listed multiple times", s.Name)
+               if bld.Type() == sym.STEXT {
+                       if bld.OnList() {
+                               return errorf("symbol %s listed multiple times", bld.Name())
                        }
-                       s.Attr |= sym.AttrOnList
+                       bld.SetOnList(true)
                        textp = append(textp, s)
-                       for s1 := s.Sub; s1 != nil; s1 = s1.Sub {
-                               if s1.Attr.OnList() {
-                                       return errorf("symbol %s listed multiple times", s1.Name)
+                       for s1 := bld.Sub(); s1 != 0; s1 = l.SubSym(s1) {
+                               if l.AttrOnList(s1) {
+                                       return errorf("symbol %s listed multiple times", l.RawSymName(s1))
                                }
-                               s1.Attr |= sym.AttrOnList
+                               l.SetAttrOnList(s1, true)
                                textp = append(textp, s1)
                        }
                }
@@ -696,14 +699,14 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader,
        for i := 0; uint32(i) < c.seg.nsect; i++ {
                sect := &c.seg.sect[i]
                s := sect.sym
-               if s == nil {
+               if s == 0 {
                        continue
                }
                macholoadrel(m, sect)
                if sect.rel == nil {
                        continue
                }
-               r := make([]sym.Reloc, sect.nreloc)
+               r := make([]loader.Reloc, sect.nreloc)
                rpi := 0
        Reloc:
                for j := uint32(0); j < sect.nreloc; j++ {
@@ -728,7 +731,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader,
                                        return errorf("unsupported scattered relocation %d/%d", int(rel.type_), int(sect.rel[j+1].type_))
                                }
 
-                               rp.Siz = rel.length
+                               rp.Size = rel.length
                                rp.Off = int32(rel.addr)
 
                                // NOTE(rsc): I haven't worked out why (really when)
@@ -752,7 +755,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader,
                                for k := 0; uint32(k) < c.seg.nsect; k++ {
                                        ks := &c.seg.sect[k]
                                        if ks.addr <= uint64(rel.value) && uint64(rel.value) < ks.addr+ks.size {
-                                               if ks.sym != nil {
+                                               if ks.sym != 0 {
                                                        rp.Sym = ks.sym
                                                        rp.Add += int64(uint64(rel.value) - ks.addr)
                                                } else if ks.segname == "__IMPORT" && ks.name == "__pointers" {
@@ -792,11 +795,12 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader,
                                return errorf("unsupported scattered relocation: invalid address %#x", rel.addr)
                        }
 
-                       rp.Siz = rel.length
+                       rp.Size = rel.length
                        rp.Type = objabi.MachoRelocOffset + (objabi.RelocType(rel.type_) << 1) + objabi.RelocType(rel.pcrel)
                        rp.Off = int32(rel.addr)
 
                        // Handle X86_64_RELOC_SIGNED referencing a section (rel->extrn == 0).
+                       p := l.Data(s)
                        if arch.Family == sys.AMD64 && rel.extrn == 0 && rel.type_ == MACHO_X86_64_RELOC_SIGNED {
                                // Calculate the addend as the offset into the section.
                                //
@@ -815,9 +819,9 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader,
                                // [For future reference, see Darwin's /usr/include/mach-o/x86_64/reloc.h]
                                secaddr := c.seg.sect[rel.symnum-1].addr
 
-                               rp.Add = int64(uint64(int64(int32(e.Uint32(s.P[rp.Off:])))+int64(rp.Off)+4) - secaddr)
+                               rp.Add = int64(uint64(int64(int32(e.Uint32(p[rp.Off:])))+int64(rp.Off)+4) - secaddr)
                        } else {
-                               rp.Add = int64(int32(e.Uint32(s.P[rp.Off:])))
+                               rp.Add = int64(int32(e.Uint32(p[rp.Off:])))
                        }
 
                        // An unsigned internal relocation has a value offset
@@ -831,7 +835,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader,
                        // it *is* the PC being subtracted. Use that to make
                        // it match our version of PC-relative.
                        if rel.pcrel != 0 && arch.Family == sys.I386 {
-                               rp.Add += int64(rp.Off) + int64(rp.Siz)
+                               rp.Add += int64(rp.Off) + int64(rp.Size)
                        }
                        if rel.extrn == 0 {
                                if rel.symnum < 1 || rel.symnum > c.seg.nsect {
@@ -839,7 +843,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader,
                                }
 
                                rp.Sym = c.seg.sect[rel.symnum-1].sym
-                               if rp.Sym == nil {
+                               if rp.Sym == 0 {
                                        return errorf("invalid relocation: %s", c.seg.sect[rel.symnum-1].name)
                                }
 
@@ -861,9 +865,9 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, f *bio.Reader,
                        rpi++
                }
 
-               sort.Sort(sym.RelocByOff(r[:rpi]))
-               s.R = r
-               s.R = s.R[:rpi]
+               sort.Sort(loader.RelocByOff(r[:rpi]))
+               sb, _ := l.MakeSymbolUpdater(sect.sym)
+               sb.SetRelocs(r[:rpi])
        }
 
        return textp, nil