From e961b26c274498f9e9bf17a6609dbc0f542f2d40 Mon Sep 17 00:00:00 2001 From: Jeremy Faller Date: Tue, 29 Oct 2019 11:37:44 -0400 Subject: [PATCH] [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 --- src/cmd/link/internal/ld/config.go | 2 +- src/cmd/link/internal/ld/lib.go | 26 ++++++++++++----- src/cmd/link/internal/loadxcoff/ldxcoff.go | 34 ++++++++++++++++++---- 3 files changed, 48 insertions(+), 14 deletions(-) diff --git a/src/cmd/link/internal/ld/config.go b/src/cmd/link/internal/ld/config.go index 0c571c30e7..b4ee67825f 100644 --- a/src/cmd/link/internal/ld/config.go +++ b/src/cmd/link/internal/ld/config.go @@ -168,7 +168,7 @@ func canLinkHostObj(ctxt *Link) bool { if !*flagNewobj { 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 diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index a0f85b85c7..bf43ef36d0 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -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) { - ldxcoff := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { - textp, err := loadxcoff.Load(ctxt.Arch, ctxt.Syms, f, pkg, length, pn) - if err != nil { - Errorf(nil, "%v", err) - return + if *flagNewobj { + ldxcoff := func(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) { + textp, err := loadxcoff.Load(ctxt.loader, ctxt.Arch, ctxt.Syms, f, pkg, length, pn) + if err != nil { + 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 */ diff --git a/src/cmd/link/internal/loadxcoff/ldxcoff.go b/src/cmd/link/internal/loadxcoff/ldxcoff.go index f52b23ce6a..fc5d3cf2bf 100644 --- a/src/cmd/link/internal/loadxcoff/ldxcoff.go +++ b/src/cmd/link/internal/loadxcoff/ldxcoff.go @@ -9,6 +9,7 @@ import ( "cmd/internal/bio" "cmd/internal/objabi" "cmd/internal/sys" + "cmd/link/internal/loader" "cmd/link/internal/sym" "errors" "fmt" @@ -38,13 +39,34 @@ func (f *xcoffBiobuf) ReadAt(p []byte, off int64) (int, error) { 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. -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) { return nil, fmt.Errorf("loadxcoff: %v: %v", pn, fmt.Sprintf(str, args...)) } - localSymVersion := syms.IncVersion() 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.Section = *sect name := fmt.Sprintf("%s(%s)", pkg, lds.Name) - s := syms.Lookup(name, localSymVersion) + s := lookup(name, localSymVersion) switch lds.Type { default: @@ -100,7 +122,7 @@ func Load(arch *sys.Arch, syms *sym.Symbols, input *bio.Reader, pkg string, leng continue } - s := syms.Lookup(sx.Name, 0) + s := lookup(sx.Name, 0) // Text symbol 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 { 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 { return errorf("virtual address of a relocation is too big: 0x%x", rx.VirtualAddress) } -- 2.48.1