diff options
| author | Jeremy Faller <jeremy@golang.org> | 2019-10-17 11:06:11 -0400 |
|---|---|---|
| committer | Jeremy Faller <jeremy@golang.org> | 2019-10-31 13:11:51 +0000 |
| commit | 0e76e2f4e5353fb935181fed353ed8667476c4ad (patch) | |
| tree | 3b41467981936a3b5dcef69af89934a4e6f50529 /src/cmd/link/internal/loadelf | |
| parent | 5a210b58588f9614c33e1b1e7231a9968879d9e4 (diff) | |
| download | go-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.go | 52 |
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 } |
