aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/link/internal/loadelf
diff options
context:
space:
mode:
authorJeremy Faller <jeremy@golang.org>2019-10-17 11:06:11 -0400
committerJeremy Faller <jeremy@golang.org>2019-10-31 13:11:51 +0000
commit0e76e2f4e5353fb935181fed353ed8667476c4ad (patch)
tree3b41467981936a3b5dcef69af89934a4e6f50529 /src/cmd/link/internal/loadelf
parent5a210b58588f9614c33e1b1e7231a9968879d9e4 (diff)
downloadgo-0e76e2f4e5353fb935181fed353ed8667476c4ad.tar.xz
[dev.link] cmd/link: elf host obj support w/ new obj files
Add support for elf host objects with new object file format. Change-Id: Ic5be1953359b9b6b78d9a0b715af69763aefd227 Reviewed-on: https://go-review.googlesource.com/c/go/+/201728 Reviewed-by: Cherry Zhang <cherryyz@google.com> Reviewed-by: Than McIntosh <thanm@google.com>
Diffstat (limited to 'src/cmd/link/internal/loadelf')
-rw-r--r--src/cmd/link/internal/loadelf/ldelf.go52
1 files changed, 41 insertions, 11 deletions
diff --git a/src/cmd/link/internal/loadelf/ldelf.go b/src/cmd/link/internal/loadelf/ldelf.go
index e895056bb2..627f836835 100644
--- a/src/cmd/link/internal/loadelf/ldelf.go
+++ b/src/cmd/link/internal/loadelf/ldelf.go
@@ -10,6 +10,7 @@ import (
"cmd/internal/bio"
"cmd/internal/objabi"
"cmd/internal/sys"
+ "cmd/link/internal/loader"
"cmd/link/internal/sym"
"debug/elf"
"encoding/binary"
@@ -451,7 +452,37 @@ func parseArmAttributes(e binary.ByteOrder, data []byte) (found bool, ehdrFlags
return found, ehdrFlags, nil
}
-// Load loads the ELF file pn from f.
+func Load(l *loader.Loader, arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, pkg string, length int64, pn string, flags uint32) ([]*sym.Symbol, uint32, error) {
+ newSym := func(name string, version int) *sym.Symbol {
+ // If we've seen the symbol, we might need to load it.
+ i := l.Lookup(name, version)
+ if i != 0 {
+ // Already loaded.
+ if l.Syms[i] != nil {
+ return l.Syms[i]
+ }
+ if l.IsExternal(i) {
+ panic("Can't load an external symbol.")
+ }
+ 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, syms.IncVersion(), newSym, newSym, f, pkg, length, pn, flags)
+}
+
+func LoadOld(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, pkg string, length int64, pn string, flags uint32) ([]*sym.Symbol, uint32, error) {
+ return load(arch, syms.IncVersion(), syms.Newsym, syms.Lookup, f, pkg, length, pn, flags)
+}
+
+type lookupFunc func(string, int) *sym.Symbol
+
+// load loads the ELF file pn from f.
// Symbols are written into syms, and a slice of the text symbols is returned.
//
// On ARM systems, Load will attempt to determine what ELF header flags to
@@ -459,12 +490,11 @@ func parseArmAttributes(e binary.ByteOrder, data []byte) (found bool, ehdrFlags
// parameter initEhdrFlags contains the current header flags for the output
// object, and the returned ehdrFlags contains what this Load function computes.
// TODO: find a better place for this logic.
-func Load(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, pkg string, length int64, pn string, initEhdrFlags uint32) (textp []*sym.Symbol, ehdrFlags uint32, err error) {
+func load(arch *sys.Arch, localSymVersion int, newSym, lookup lookupFunc, f *bio.Reader, pkg string, length int64, pn string, initEhdrFlags uint32) (textp []*sym.Symbol, ehdrFlags uint32, err error) {
errorf := func(str string, args ...interface{}) ([]*sym.Symbol, uint32, error) {
return nil, 0, fmt.Errorf("loadelf: %s: %v", pn, fmt.Sprintf(str, args...))
}
- localSymVersion := syms.IncVersion()
base := f.Offset()
var hdrbuf [64]uint8
@@ -715,7 +745,7 @@ func Load(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, pkg string, length i
}
sectsymNames[name] = true
- s := syms.Lookup(name, localSymVersion)
+ s := lookup(name, localSymVersion)
switch int(sect.flags) & (ElfSectFlagAlloc | ElfSectFlagWrite | ElfSectFlagExec) {
default:
@@ -754,7 +784,7 @@ func Load(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, pkg string, length i
for i := 1; i < elfobj.nsymtab; i++ {
var elfsym ElfSym
- if err := readelfsym(arch, syms, elfobj, i, &elfsym, 1, localSymVersion); err != nil {
+ if err := readelfsym(newSym, lookup, arch, elfobj, i, &elfsym, 1, localSymVersion); err != nil {
return errorf("%s: malformed elf file: %v", pn, err)
}
symbols[i] = elfsym.sym
@@ -925,7 +955,7 @@ func Load(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, pkg string, length i
rp.Sym = nil
} else {
var elfsym ElfSym
- if err := readelfsym(arch, syms, elfobj, int(info>>32), &elfsym, 0, 0); err != nil {
+ if err := readelfsym(newSym, lookup, arch, elfobj, int(info>>32), &elfsym, 0, 0); err != nil {
return errorf("malformed elf file: %v", err)
}
elfsym.sym = symbols[info>>32]
@@ -1002,7 +1032,7 @@ func elfmap(elfobj *ElfObj, sect *ElfSect) (err error) {
return nil
}
-func readelfsym(arch *sys.Arch, syms *sym.Symbols, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int, localSymVersion int) (err error) {
+func readelfsym(newSym, lookup lookupFunc, arch *sys.Arch, elfobj *ElfObj, i int, elfsym *ElfSym, needSym int, localSymVersion int) (err error) {
if i >= elfobj.nsymtab || i < 0 {
err = fmt.Errorf("invalid elf symbol index")
return err
@@ -1052,7 +1082,7 @@ func readelfsym(arch *sys.Arch, syms *sym.Symbols, elfobj *ElfObj, i int, elfsym
switch elfsym.bind {
case ElfSymBindGlobal:
if needSym != 0 {
- s = syms.Lookup(elfsym.name, 0)
+ s = lookup(elfsym.name, 0)
// for global scoped hidden symbols we should insert it into
// symbol hash table, but mark them as hidden.
@@ -1077,7 +1107,7 @@ func readelfsym(arch *sys.Arch, syms *sym.Symbols, elfobj *ElfObj, i int, elfsym
// We need to be able to look this up,
// so put it in the hash table.
if needSym != 0 {
- s = syms.Lookup(elfsym.name, localSymVersion)
+ s = lookup(elfsym.name, localSymVersion)
s.Attr |= sym.AttrVisibilityHidden
}
@@ -1088,14 +1118,14 @@ func readelfsym(arch *sys.Arch, syms *sym.Symbols, elfobj *ElfObj, i int, elfsym
// local names and hidden global names are unique
// and should only be referenced by their index, not name, so we
// don't bother to add them into the hash table
- s = syms.Newsym(elfsym.name, localSymVersion)
+ s = newSym(elfsym.name, localSymVersion)
s.Attr |= sym.AttrVisibilityHidden
}
case ElfSymBindWeak:
if needSym != 0 {
- s = syms.Lookup(elfsym.name, 0)
+ s = lookup(elfsym.name, 0)
if elfsym.other == 2 {
s.Attr |= sym.AttrVisibilityHidden
}