mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.link] cmd/link: fix xcoff loader for new obj format
config.go needs to be removed from this CL. Change-Id: I04a267feeae1551bb18f6a03a725adc9db593fdb Reviewed-on: https://go-review.googlesource.com/c/go/+/204099 Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
c0555a2a7a
commit
e961b26c27
3 changed files with 48 additions and 14 deletions
|
|
@ -168,7 +168,7 @@ func canLinkHostObj(ctxt *Link) bool {
|
||||||
if !*flagNewobj {
|
if !*flagNewobj {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return ctxt.IsELF || objabi.GOOS == "darwin"
|
return ctxt.IsELF || objabi.GOOS == "darwin" || objabi.GOOS == "aix"
|
||||||
}
|
}
|
||||||
|
|
||||||
// mustLinkExternal reports whether the program being linked requires
|
// mustLinkExternal reports whether the program being linked requires
|
||||||
|
|
|
||||||
|
|
@ -1707,15 +1707,27 @@ func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string,
|
||||||
}
|
}
|
||||||
|
|
||||||
if c1 == 0x01 && (c2 == 0xD7 || c2 == 0xF7) {
|
if c1 == 0x01 && (c2 == 0xD7 || c2 == 0xF7) {
|
||||||
ldxcoff := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
|
if *flagNewobj {
|
||||||
textp, err := loadxcoff.Load(ctxt.Arch, ctxt.Syms, f, pkg, length, pn)
|
ldxcoff := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
|
||||||
if err != nil {
|
textp, err := loadxcoff.Load(ctxt.loader, ctxt.Arch, ctxt.Syms, f, pkg, length, pn)
|
||||||
Errorf(nil, "%v", err)
|
if err != nil {
|
||||||
return
|
Errorf(nil, "%v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctxt.Textp = append(ctxt.Textp, textp...)
|
||||||
}
|
}
|
||||||
ctxt.Textp = append(ctxt.Textp, textp...)
|
return ldhostobj(ldxcoff, ctxt.HeadType, f, pkg, length, pn, file)
|
||||||
|
} else {
|
||||||
|
ldxcoff := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
|
||||||
|
textp, err := loadxcoff.LoadOld(ctxt.Arch, ctxt.Syms, f, pkg, length, pn)
|
||||||
|
if err != nil {
|
||||||
|
Errorf(nil, "%v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctxt.Textp = append(ctxt.Textp, textp...)
|
||||||
|
}
|
||||||
|
return ldhostobj(ldxcoff, ctxt.HeadType, f, pkg, length, pn, file)
|
||||||
}
|
}
|
||||||
return ldhostobj(ldxcoff, ctxt.HeadType, f, pkg, length, pn, file)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check the header */
|
/* check the header */
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"cmd/internal/bio"
|
"cmd/internal/bio"
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
|
"cmd/link/internal/loader"
|
||||||
"cmd/link/internal/sym"
|
"cmd/link/internal/sym"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -38,13 +39,34 @@ func (f *xcoffBiobuf) ReadAt(p []byte, off int64) (int, error) {
|
||||||
return n, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load loads the Xcoff file pn from f.
|
// Load loads xcoff files with the indexed object files.
|
||||||
|
func Load(l *loader.Loader, arch *sys.Arch, syms *sym.Symbols, input *bio.Reader, pkg string, length int64, pn string) (textp []*sym.Symbol, err error) {
|
||||||
|
lookup := func(name string, version int) *sym.Symbol {
|
||||||
|
i := l.Lookup(name, version)
|
||||||
|
if i != 0 {
|
||||||
|
return l.LoadSymbol(name, version, syms)
|
||||||
|
}
|
||||||
|
if i = l.AddExtSym(name, version); i == 0 {
|
||||||
|
panic("AddExtSym returned bad index")
|
||||||
|
}
|
||||||
|
newSym := syms.Newsym(name, version)
|
||||||
|
l.Syms[i] = newSym
|
||||||
|
return newSym
|
||||||
|
}
|
||||||
|
return load(arch, lookup, syms.IncVersion(), input, pkg, length, pn)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadOld uses the old version of object loading.
|
||||||
|
func LoadOld(arch *sys.Arch, syms *sym.Symbols, input *bio.Reader, pkg string, length int64, pn string) (textp []*sym.Symbol, err error) {
|
||||||
|
return load(arch, syms.Lookup, syms.IncVersion(), input, pkg, length, pn)
|
||||||
|
}
|
||||||
|
|
||||||
|
// loads the Xcoff 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(arch *sys.Arch, syms *sym.Symbols, input *bio.Reader, pkg string, length int64, pn string) (textp []*sym.Symbol, err error) {
|
func load(arch *sys.Arch, lookup func(string, int) *sym.Symbol, localSymVersion int, input *bio.Reader, pkg string, length int64, pn string) (textp []*sym.Symbol, err error) {
|
||||||
errorf := func(str string, args ...interface{}) ([]*sym.Symbol, error) {
|
errorf := func(str string, args ...interface{}) ([]*sym.Symbol, error) {
|
||||||
return nil, fmt.Errorf("loadxcoff: %v: %v", pn, fmt.Sprintf(str, args...))
|
return nil, fmt.Errorf("loadxcoff: %v: %v", pn, fmt.Sprintf(str, args...))
|
||||||
}
|
}
|
||||||
localSymVersion := syms.IncVersion()
|
|
||||||
|
|
||||||
var ldSections []*ldSection
|
var ldSections []*ldSection
|
||||||
|
|
||||||
|
|
@ -62,7 +84,7 @@ func Load(arch *sys.Arch, syms *sym.Symbols, input *bio.Reader, pkg string, leng
|
||||||
lds := new(ldSection)
|
lds := new(ldSection)
|
||||||
lds.Section = *sect
|
lds.Section = *sect
|
||||||
name := fmt.Sprintf("%s(%s)", pkg, lds.Name)
|
name := fmt.Sprintf("%s(%s)", pkg, lds.Name)
|
||||||
s := syms.Lookup(name, localSymVersion)
|
s := lookup(name, localSymVersion)
|
||||||
|
|
||||||
switch lds.Type {
|
switch lds.Type {
|
||||||
default:
|
default:
|
||||||
|
|
@ -100,7 +122,7 @@ func Load(arch *sys.Arch, syms *sym.Symbols, input *bio.Reader, pkg string, leng
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
s := syms.Lookup(sx.Name, 0)
|
s := lookup(sx.Name, 0)
|
||||||
|
|
||||||
// Text symbol
|
// Text symbol
|
||||||
if s.Type == sym.STEXT {
|
if s.Type == sym.STEXT {
|
||||||
|
|
@ -122,7 +144,7 @@ func Load(arch *sys.Arch, syms *sym.Symbols, input *bio.Reader, pkg string, leng
|
||||||
for i, rx := range sect.Relocs {
|
for i, rx := range sect.Relocs {
|
||||||
r := &rs[i]
|
r := &rs[i]
|
||||||
|
|
||||||
r.Sym = syms.Lookup(rx.Symbol.Name, 0)
|
r.Sym = lookup(rx.Symbol.Name, 0)
|
||||||
if uint64(int32(rx.VirtualAddress)) != rx.VirtualAddress {
|
if uint64(int32(rx.VirtualAddress)) != rx.VirtualAddress {
|
||||||
return errorf("virtual address of a relocation is too big: 0x%x", rx.VirtualAddress)
|
return errorf("virtual address of a relocation is too big: 0x%x", rx.VirtualAddress)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue