ctxt.Logf("%5.2f ldelf %s\n", obj.Cputime(), pn)
}
- ctxt.Syms.IncVersion()
+ localSymVersion := ctxt.Syms.IncVersion()
base := f.Offset()
var add uint64
}
name = fmt.Sprintf("%s(%s)", pkg, sect.name)
- s = ctxt.Syms.Lookup(name, ctxt.Syms.Version)
+ s = ctxt.Syms.Lookup(name, localSymVersion)
switch int(sect.flags) & (ElfSectFlagAlloc | ElfSectFlagWrite | ElfSectFlagExec) {
default:
symbols = make([]*Symbol, elfobj.nsymtab)
for i := 1; i < elfobj.nsymtab; i++ {
- if err = readelfsym(ctxt, elfobj, i, &sym, 1); err != nil {
+ if err = readelfsym(ctxt, elfobj, i, &sym, 1, localSymVersion); err != nil {
goto bad
}
symbols[i] = sym.sym
if info>>32 == 0 { // absolute relocation, don't bother reading the null symbol
rp.Sym = nil
} else {
- if err = readelfsym(ctxt, elfobj, int(info>>32), &sym, 0); err != nil {
+ if err = readelfsym(ctxt, elfobj, int(info>>32), &sym, 0, 0); err != nil {
goto bad
}
sym.sym = symbols[info>>32]
return nil
}
-func readelfsym(ctxt *Link, elfobj *ElfObj, i int, sym *ElfSym, needSym int) (err error) {
+func readelfsym(ctxt *Link, elfobj *ElfObj, i int, sym *ElfSym, needSym int, localSymVersion int) (err error) {
if i >= elfobj.nsymtab || i < 0 {
err = fmt.Errorf("invalid elf symbol index")
return err
// We need to be able to look this up,
// so put it in the hash table.
if needSym != 0 {
- s = ctxt.Syms.Lookup(sym.name, ctxt.Syms.Version)
+ s = ctxt.Syms.Lookup(sym.name, localSymVersion)
s.Type |= obj.SHIDDEN
}
// 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 = ctxt.Syms.newsym(sym.name, ctxt.Syms.Version)
+ s = ctxt.Syms.newsym(sym.name, localSymVersion)
s.Type |= obj.SHIDDEN
}
var rp *Reloc
var name string
- ctxt.Syms.IncVersion()
+ localSymVersion := ctxt.Syms.IncVersion()
base := f.Offset()
if _, err := io.ReadFull(f, hdr[:]); err != nil {
goto bad
continue
}
name = fmt.Sprintf("%s(%s/%s)", pkg, sect.segname, sect.name)
- s = ctxt.Syms.Lookup(name, ctxt.Syms.Version)
+ s = ctxt.Syms.Lookup(name, localSymVersion)
if s.Type != 0 {
err = fmt.Errorf("duplicate %s/%s", sect.segname, sect.name)
goto bad
}
v := 0
if sym.type_&N_EXT == 0 {
- v = ctxt.Syms.Version
+ v = localSymVersion
}
s = ctxt.Syms.Lookup(name, v)
if sym.type_&N_EXT == 0 {
}
var sect *PeSect
- ctxt.Syms.IncVersion()
+ localSymVersion := ctxt.Syms.IncVersion()
base := f.Offset()
peobj := new(PeObj)
}
name = fmt.Sprintf("%s(%s)", pkg, sect.name)
- s = ctxt.Syms.Lookup(name, ctxt.Syms.Version)
+ s = ctxt.Syms.Lookup(name, localSymVersion)
switch sect.sh.Characteristics & (IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE) {
case IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ: //.rdata
rva := Le32(symbuf[0:])
symindex := Le32(symbuf[4:])
type_ := Le16(symbuf[8:])
- if err = readpesym(ctxt, peobj, int(symindex), &sym); err != nil {
+ if err = readpesym(ctxt, peobj, int(symindex), &sym, localSymVersion); err != nil {
goto bad
}
if sym.sym == nil {
}
}
- if err = readpesym(ctxt, peobj, i, &sym); err != nil {
+ if err = readpesym(ctxt, peobj, i, &sym, localSymVersion); err != nil {
goto bad
}
return s.sclass == IMAGE_SYM_CLASS_STATIC && s.type_ == 0 && s.name[0] == '.'
}
-func readpesym(ctxt *Link, peobj *PeObj, i int, y **PeSym) (err error) {
+func readpesym(ctxt *Link, peobj *PeObj, i int, y **PeSym, localSymVersion int) (err error) {
if uint(i) >= peobj.npesym || i < 0 {
err = fmt.Errorf("invalid pe symbol index")
return err
s = ctxt.Syms.Lookup(name, 0)
case IMAGE_SYM_CLASS_NULL, IMAGE_SYM_CLASS_STATIC, IMAGE_SYM_CLASS_LABEL:
- s = ctxt.Syms.Lookup(name, ctxt.Syms.Version)
+ s = ctxt.Syms.Lookup(name, localSymVersion)
s.Attr |= AttrDuplicateOK
default:
// objReader reads Go object files.
type objReader struct {
- rd *bufio.Reader
- ctxt *Link
- pkg string
- pn string
- // List of symbol references for the file being read.
- dupSym *Symbol
+ rd *bufio.Reader
+ ctxt *Link
+ pkg string
+ pn string
+ dupSym *Symbol
+ localSymVersion int
// rdBuf is used by readString and readSymName as scratch for reading strings.
rdBuf []byte
+ // List of symbol references for the file being read.
refs []*Symbol
data []byte
reloc []Reloc
func LoadObjFile(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
start := f.Offset()
r := &objReader{
- rd: f.Reader,
- pkg: pkg,
- ctxt: ctxt,
- pn: pn,
- dupSym: &Symbol{Name: ".dup"},
+ rd: f.Reader,
+ pkg: pkg,
+ ctxt: ctxt,
+ pn: pn,
+ dupSym: &Symbol{Name: ".dup"},
+ localSymVersion: ctxt.Syms.IncVersion(),
}
r.loadObjFile()
if f.Offset() != start+length {
}
func (r *objReader) loadObjFile() {
- // Increment context version, versions are used to differentiate static files in different packages
- r.ctxt.Syms.IncVersion()
// Magic header
var buf [8]uint8
log.Fatalf("invalid symbol version %d", v)
}
if v == 1 {
- v = r.ctxt.Syms.Version
+ v = r.localSymVersion
}
s := r.ctxt.Syms.Lookup(name, v)
r.refs = append(r.refs, s)
hash []map[string]*Symbol
Allsym []*Symbol
-
- Version int
}
func (syms *Symbols) newsym(name string, v int) *Symbol {
}
// Allocate a new version (i.e. symbol namespace).
-//
-// TODO(mwhudson): This would feel more natural if it returned the new
-// version (or if we dropped Symbols.Version entirely and just
-// returned len(syms.hash))
-func (syms *Symbols) IncVersion() {
- syms.Version++
+func (syms *Symbols) IncVersion() int {
syms.hash = append(syms.hash, make(map[string]*Symbol))
+ return len(syms.hash) - 1
}