mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.link] cmd/link: use new sym builders in macho loader
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>
This commit is contained in:
parent
2d2590e94a
commit
4ad94a5db9
4 changed files with 111 additions and 78 deletions
|
|
@ -457,7 +457,8 @@ func (ctxt *Link) loadlib() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process cgo directives (has to be done before host object loading).
|
// 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.
|
// Conditionally load host objects, or setup for external linking.
|
||||||
hostobjs(ctxt)
|
hostobjs(ctxt)
|
||||||
|
|
@ -1888,7 +1889,7 @@ func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string,
|
||||||
Errorf(nil, "%v", err)
|
Errorf(nil, "%v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctxt.Textp = append(ctxt.Textp, textp...)
|
ctxt.Textp2 = append(ctxt.Textp2, textp...)
|
||||||
}
|
}
|
||||||
return ldhostobj(ldmacho, ctxt.HeadType, f, pkg, length, pn, file)
|
return ldhostobj(ldmacho, ctxt.HeadType, f, pkg, length, pn, file)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -674,6 +674,9 @@ func (l *Loader) NDef() int {
|
||||||
|
|
||||||
// Returns the raw (unpatched) name of the i-th symbol.
|
// Returns the raw (unpatched) name of the i-th symbol.
|
||||||
func (l *Loader) RawSymName(i Sym) string {
|
func (l *Loader) RawSymName(i Sym) string {
|
||||||
|
if ov, ok := l.overwrite[i]; ok {
|
||||||
|
i = ov
|
||||||
|
}
|
||||||
if l.IsExternal(i) {
|
if l.IsExternal(i) {
|
||||||
if s := l.Syms[i]; s != nil {
|
if s := l.Syms[i]; s != nil {
|
||||||
return s.Name
|
return s.Name
|
||||||
|
|
@ -904,7 +907,7 @@ func (l *Loader) AttrExternal(i Sym) bool {
|
||||||
// symbol (see AttrExternal).
|
// symbol (see AttrExternal).
|
||||||
func (l *Loader) SetAttrExternal(i Sym, v bool) {
|
func (l *Loader) SetAttrExternal(i Sym, v bool) {
|
||||||
if i < l.extStart {
|
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 {
|
if v {
|
||||||
l.attrExternal.set(i - l.extStart)
|
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.SetAttrSpecial(dst, l.AttrSpecial(src))
|
||||||
l.SetAttrCgoExportDynamic(dst, l.AttrCgoExportDynamic(src))
|
l.SetAttrCgoExportDynamic(dst, l.AttrCgoExportDynamic(src))
|
||||||
l.SetAttrCgoExportStatic(dst, l.AttrCgoExportStatic(src))
|
l.SetAttrCgoExportStatic(dst, l.AttrCgoExportStatic(src))
|
||||||
|
l.SetAttrReadOnly(dst, l.AttrReadOnly(src))
|
||||||
}
|
}
|
||||||
|
|
||||||
// migrateAttributes copies over all of the attributes of symbol 'src' to
|
// 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.AttrSpecial, l.AttrSpecial(src))
|
||||||
dst.Attr.Set(sym.AttrCgoExportDynamic, l.AttrCgoExportDynamic(src))
|
dst.Attr.Set(sym.AttrCgoExportDynamic, l.AttrCgoExportDynamic(src))
|
||||||
dst.Attr.Set(sym.AttrCgoExportStatic, l.AttrCgoExportStatic(src))
|
dst.Attr.Set(sym.AttrCgoExportStatic, l.AttrCgoExportStatic(src))
|
||||||
|
dst.Attr.Set(sym.AttrReadOnly, l.AttrReadOnly(src))
|
||||||
|
|
||||||
// Convert outer/sub relationships
|
// Convert outer/sub relationships
|
||||||
if outer, ok := l.outer[src]; ok {
|
if outer, ok := l.outer[src]; ok {
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
"cmd/link/internal/sym"
|
"cmd/link/internal/sym"
|
||||||
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SymbolBuilder is a helper designed to help with the construction
|
// 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)
|
symIdx = l.cloneToExternal(symIdx)
|
||||||
}
|
}
|
||||||
if l.Syms[symIdx] != nil {
|
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.
|
// 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.
|
// Getters for properties of the symbol we're working on.
|
||||||
|
|
||||||
func (sb *SymbolBuilder) Sym() Sym { return sb.symIdx }
|
func (sb *SymbolBuilder) Sym() Sym { return sb.symIdx }
|
||||||
func (sb *SymbolBuilder) Name() string { return sb.name }
|
func (sb *SymbolBuilder) Name() string { return sb.name }
|
||||||
func (sb *SymbolBuilder) Version() int { return sb.ver }
|
func (sb *SymbolBuilder) Version() int { return sb.ver }
|
||||||
func (sb *SymbolBuilder) Type() sym.SymKind { return sb.kind }
|
func (sb *SymbolBuilder) Type() sym.SymKind { return sb.kind }
|
||||||
func (sb *SymbolBuilder) Size() int64 { return sb.size }
|
func (sb *SymbolBuilder) Size() int64 { return sb.size }
|
||||||
func (sb *SymbolBuilder) Data() []byte { return sb.data }
|
func (sb *SymbolBuilder) Data() []byte { return sb.data }
|
||||||
func (sb *SymbolBuilder) Value() int64 { return sb.l.SymValue(sb.symIdx) }
|
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) Align() int32 { return sb.l.SymAlign(sb.symIdx) }
|
||||||
func (sb *SymbolBuilder) Localentry() uint8 { return sb.l.SymLocalentry(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) OnList() bool { return sb.l.AttrOnList(sb.symIdx) }
|
||||||
func (sb *SymbolBuilder) Dynimplib() string { return sb.l.SymDynimplib(sb.symIdx) }
|
func (sb *SymbolBuilder) External() bool { return sb.l.AttrExternal(sb.symIdx) }
|
||||||
func (sb *SymbolBuilder) Dynimpvers() string { return sb.l.SymDynimpvers(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.
|
// Setters for symbol properties.
|
||||||
|
|
||||||
func (sb *SymbolBuilder) SetType(kind sym.SymKind) { sb.kind = kind }
|
func (sb *SymbolBuilder) SetType(kind sym.SymKind) { sb.kind = kind }
|
||||||
func (sb *SymbolBuilder) SetSize(size int64) { sb.size = size }
|
func (sb *SymbolBuilder) SetSize(size int64) { sb.size = size }
|
||||||
func (sb *SymbolBuilder) SetData(data []byte) { sb.data = data }
|
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) SetValue(v int64) { sb.l.SetSymValue(sb.symIdx, v) }
|
||||||
func (sb *SymbolBuilder) SetAlign(align int32) { sb.l.SetSymAlign(sb.symIdx, align) }
|
func (sb *SymbolBuilder) SetAlign(align int32) { sb.l.SetSymAlign(sb.symIdx, align) }
|
||||||
func (sb *SymbolBuilder) SetLocalentry(value uint8) { sb.l.SetSymLocalentry(sb.symIdx, value) }
|
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)
|
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 {
|
func (sb *SymbolBuilder) Outer() Sym {
|
||||||
return sb.l.OuterSym(sb.symIdx)
|
return sb.l.OuterSym(sb.symIdx)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ type ldMachoSect struct {
|
||||||
flags uint32
|
flags uint32
|
||||||
res1 uint32
|
res1 uint32
|
||||||
res2 uint32
|
res2 uint32
|
||||||
sym *sym.Symbol
|
sym loader.Sym
|
||||||
rel []ldMachoRel
|
rel []ldMachoRel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -131,7 +131,7 @@ type ldMachoSym struct {
|
||||||
desc uint16
|
desc uint16
|
||||||
kind int8
|
kind int8
|
||||||
value uint64
|
value uint64
|
||||||
sym *sym.Symbol
|
sym loader.Sym
|
||||||
}
|
}
|
||||||
|
|
||||||
type ldMachoDysymtab struct {
|
type ldMachoDysymtab struct {
|
||||||
|
|
@ -423,8 +423,8 @@ func macholoadsym(m *ldMachoObj, symtab *ldMachoSymtab) int {
|
||||||
|
|
||||||
// Load the Mach-O file pn from f.
|
// Load the Mach-O file pn from f.
|
||||||
// Symbols are written into syms, and a slice of the text symbols is returned.
|
// 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) {
|
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{}) ([]*sym.Symbol, error) {
|
errorf := func(str string, args ...interface{}) ([]loader.Sym, error) {
|
||||||
return nil, fmt.Errorf("loadmacho: %v: %v", pn, fmt.Sprintf(str, args...))
|
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
|
continue
|
||||||
}
|
}
|
||||||
name := fmt.Sprintf("%s(%s/%s)", pkg, sect.segname, sect.name)
|
name := fmt.Sprintf("%s(%s/%s)", pkg, sect.segname, sect.name)
|
||||||
s := l.LookupOrCreate(name, localSymVersion)
|
bld, s := l.MakeSymbolUpdater(l.LookupOrCreateSym(name, localSymVersion))
|
||||||
if s.Type != 0 {
|
if bld.Type() != 0 {
|
||||||
return errorf("duplicate %s/%s", sect.segname, sect.name)
|
return errorf("duplicate %s/%s", sect.segname, sect.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if sect.flags&0xff == 1 { // S_ZEROFILL
|
if sect.flags&0xff == 1 { // S_ZEROFILL
|
||||||
s.P = make([]byte, sect.size)
|
bld.SetData(make([]byte, sect.size))
|
||||||
} else {
|
} else {
|
||||||
s.Attr.Set(sym.AttrReadOnly, readOnly)
|
bld.SetReadOnly(readOnly)
|
||||||
s.P = dat[sect.addr-c.seg.vmaddr:][:sect.size]
|
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.segname == "__TEXT" {
|
||||||
if sect.name == "__text" {
|
if sect.name == "__text" {
|
||||||
s.Type = sym.STEXT
|
bld.SetType(sym.STEXT)
|
||||||
} else {
|
} else {
|
||||||
s.Type = sym.SRODATA
|
bld.SetType(sym.SRODATA)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if sect.name == "__bss" {
|
if sect.name == "__bss" {
|
||||||
s.Type = sym.SNOPTRBSS
|
bld.SetType(sym.SNOPTRBSS)
|
||||||
s.P = s.P[:0]
|
bld.SetData(nil)
|
||||||
} else {
|
} 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 {
|
if machsym.type_&N_EXT == 0 {
|
||||||
v = localSymVersion
|
v = localSymVersion
|
||||||
}
|
}
|
||||||
s := l.LookupOrCreate(name, v)
|
s := l.LookupOrCreateSym(name, v)
|
||||||
if machsym.type_&N_EXT == 0 {
|
if machsym.type_&N_EXT == 0 {
|
||||||
s.Attr |= sym.AttrDuplicateOK
|
l.SetAttrDuplicateOK(s, true)
|
||||||
}
|
}
|
||||||
if machsym.desc&(N_WEAK_REF|N_WEAK_DEF) != 0 {
|
if machsym.desc&(N_WEAK_REF|N_WEAK_DEF) != 0 {
|
||||||
s.Attr |= sym.AttrDuplicateOK
|
l.SetAttrDuplicateOK(s, true)
|
||||||
}
|
}
|
||||||
machsym.sym = s
|
machsym.sym = s
|
||||||
if machsym.sectnum == 0 { // undefined
|
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]
|
sect := &c.seg.sect[machsym.sectnum-1]
|
||||||
|
bld, bldSym := l.MakeSymbolUpdater(s)
|
||||||
outer := sect.sym
|
outer := sect.sym
|
||||||
if outer == nil {
|
if outer == 0 {
|
||||||
continue // ignore reference to invalid section
|
continue // ignore reference to invalid section
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.Outer != nil {
|
if osym := l.OuterSym(s); osym != 0 {
|
||||||
if s.Attr.DuplicateOK() {
|
if l.AttrDuplicateOK(s) {
|
||||||
continue
|
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
|
bld.SetType(l.SymType(outer))
|
||||||
s.Attr |= sym.AttrSubSymbol
|
l.PrependSub(outer, bldSym)
|
||||||
s.Sub = outer.Sub
|
|
||||||
outer.Sub = s
|
bld.SetValue(int64(machsym.value - sect.addr))
|
||||||
s.Outer = outer
|
if !l.AttrCgoExportDynamic(s) {
|
||||||
s.Value = int64(machsym.value - sect.addr)
|
bld.SetDynimplib("") // satisfy dynimport
|
||||||
if !s.Attr.CgoExportDynamic() {
|
|
||||||
s.SetDynimplib("") // satisfy dynimport
|
|
||||||
}
|
}
|
||||||
if outer.Type == sym.STEXT {
|
if l.SymType(outer) == sym.STEXT {
|
||||||
if s.Attr.External() && !s.Attr.DuplicateOK() {
|
if bld.External() && !bld.DuplicateOK() {
|
||||||
return errorf("%v: duplicate symbol definition", s)
|
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.
|
// Sort outer lists by address, adding to textp.
|
||||||
// This keeps textp in increasing address order.
|
// This keeps textp in increasing address order.
|
||||||
for i := 0; uint32(i) < c.seg.nsect; i++ {
|
for i := 0; uint32(i) < c.seg.nsect; i++ {
|
||||||
sect := &c.seg.sect[i]
|
sect := &c.seg.sect[i]
|
||||||
s := sect.sym
|
sectSym := sect.sym
|
||||||
if s == nil {
|
if sectSym == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if s.Sub != nil {
|
bld, s := l.MakeSymbolUpdater(sectSym)
|
||||||
s.Sub = sym.SortSub(s.Sub)
|
if bld.SubSym() != 0 {
|
||||||
|
|
||||||
|
bld.SortSub()
|
||||||
|
|
||||||
// assign sizes, now that we know symbols in sorted order.
|
// assign sizes, now that we know symbols in sorted order.
|
||||||
for s1 := s.Sub; s1 != nil; s1 = s1.Sub {
|
for s1 := bld.Sub(); s1 != 0; s1 = l.SubSym(s1) {
|
||||||
if s1.Sub != nil {
|
s1Bld, _ := l.MakeSymbolUpdater(s1)
|
||||||
s1.Size = s1.Sub.Value - s1.Value
|
if sub := l.SubSym(s1); sub != 0 {
|
||||||
|
s1Bld.SetSize(l.SymValue(sub) - l.SymValue(s1))
|
||||||
} else {
|
} 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 bld.Type() == sym.STEXT {
|
||||||
if s.Attr.OnList() {
|
if bld.OnList() {
|
||||||
return errorf("symbol %s listed multiple times", s.Name)
|
return errorf("symbol %s listed multiple times", bld.Name())
|
||||||
}
|
}
|
||||||
s.Attr |= sym.AttrOnList
|
bld.SetOnList(true)
|
||||||
textp = append(textp, s)
|
textp = append(textp, s)
|
||||||
for s1 := s.Sub; s1 != nil; s1 = s1.Sub {
|
for s1 := bld.Sub(); s1 != 0; s1 = l.SubSym(s1) {
|
||||||
if s1.Attr.OnList() {
|
if l.AttrOnList(s1) {
|
||||||
return errorf("symbol %s listed multiple times", s1.Name)
|
return errorf("symbol %s listed multiple times", l.RawSymName(s1))
|
||||||
}
|
}
|
||||||
s1.Attr |= sym.AttrOnList
|
l.SetAttrOnList(s1, true)
|
||||||
textp = append(textp, s1)
|
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++ {
|
for i := 0; uint32(i) < c.seg.nsect; i++ {
|
||||||
sect := &c.seg.sect[i]
|
sect := &c.seg.sect[i]
|
||||||
s := sect.sym
|
s := sect.sym
|
||||||
if s == nil {
|
if s == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
macholoadrel(m, sect)
|
macholoadrel(m, sect)
|
||||||
if sect.rel == nil {
|
if sect.rel == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
r := make([]sym.Reloc, sect.nreloc)
|
r := make([]loader.Reloc, sect.nreloc)
|
||||||
rpi := 0
|
rpi := 0
|
||||||
Reloc:
|
Reloc:
|
||||||
for j := uint32(0); j < sect.nreloc; j++ {
|
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_))
|
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)
|
rp.Off = int32(rel.addr)
|
||||||
|
|
||||||
// NOTE(rsc): I haven't worked out why (really when)
|
// 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++ {
|
for k := 0; uint32(k) < c.seg.nsect; k++ {
|
||||||
ks := &c.seg.sect[k]
|
ks := &c.seg.sect[k]
|
||||||
if ks.addr <= uint64(rel.value) && uint64(rel.value) < ks.addr+ks.size {
|
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.Sym = ks.sym
|
||||||
rp.Add += int64(uint64(rel.value) - ks.addr)
|
rp.Add += int64(uint64(rel.value) - ks.addr)
|
||||||
} else if ks.segname == "__IMPORT" && ks.name == "__pointers" {
|
} 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)
|
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.Type = objabi.MachoRelocOffset + (objabi.RelocType(rel.type_) << 1) + objabi.RelocType(rel.pcrel)
|
||||||
rp.Off = int32(rel.addr)
|
rp.Off = int32(rel.addr)
|
||||||
|
|
||||||
// Handle X86_64_RELOC_SIGNED referencing a section (rel->extrn == 0).
|
// 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 {
|
if arch.Family == sys.AMD64 && rel.extrn == 0 && rel.type_ == MACHO_X86_64_RELOC_SIGNED {
|
||||||
// Calculate the addend as the offset into the section.
|
// 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]
|
// [For future reference, see Darwin's /usr/include/mach-o/x86_64/reloc.h]
|
||||||
secaddr := c.seg.sect[rel.symnum-1].addr
|
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 {
|
} 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
|
// 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 *is* the PC being subtracted. Use that to make
|
||||||
// it match our version of PC-relative.
|
// it match our version of PC-relative.
|
||||||
if rel.pcrel != 0 && arch.Family == sys.I386 {
|
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.extrn == 0 {
|
||||||
if rel.symnum < 1 || rel.symnum > c.seg.nsect {
|
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
|
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)
|
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++
|
rpi++
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Sort(sym.RelocByOff(r[:rpi]))
|
sort.Sort(loader.RelocByOff(r[:rpi]))
|
||||||
s.R = r
|
sb, _ := l.MakeSymbolUpdater(sect.sym)
|
||||||
s.R = s.R[:rpi]
|
sb.SetRelocs(r[:rpi])
|
||||||
}
|
}
|
||||||
|
|
||||||
return textp, nil
|
return textp, nil
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue