Info, Other byte
Section SectionIndex
Value, Size uint64
+
+ // Version and Library are present only for the dynamic symbol
+ // table.
+ Version string
+ Library string
}
/*
// DynamicSymbols returns the dynamic symbol table for f. The symbols
// will be listed in the order they appear in f.
//
+// If f has a symbol version table, the returned Symbols will have
+// initialized Version and Library fields.
+//
// For compatibility with Symbols, DynamicSymbols omits the null symbol at index 0.
// After retrieving the symbols as symtab, an externally supplied index x
// corresponds to symtab[x-1], not symtab[x].
func (f *File) DynamicSymbols() ([]Symbol, error) {
- sym, _, err := f.getSymbols(SHT_DYNSYM)
- return sym, err
+ sym, str, err := f.getSymbols(SHT_DYNSYM)
+ if err != nil {
+ return nil, err
+ }
+ if f.gnuVersionInit(str) {
+ for i := range sym {
+ sym[i].Library, sym[i].Version = f.gnuVersion(i)
+ }
+ }
+ return sym, nil
}
type ImportedSymbol struct {
for i, s := range sym {
if ST_BIND(s.Info) == STB_GLOBAL && s.Section == SHN_UNDEF {
all = append(all, ImportedSymbol{Name: s.Name})
- f.gnuVersion(i, &all[len(all)-1])
+ sym := &all[len(all)-1]
+ sym.Library, sym.Version = f.gnuVersion(i)
}
}
return all, nil
// gnuVersionInit parses the GNU version tables
// for use by calls to gnuVersion.
-func (f *File) gnuVersionInit(str []byte) {
+func (f *File) gnuVersionInit(str []byte) bool {
+ if f.gnuNeed != nil {
+ // Already initialized
+ return true
+ }
+
// Accumulate verneed information.
vn := f.SectionByType(SHT_GNU_VERNEED)
if vn == nil {
- return
+ return false
}
d, _ := vn.Data()
// Versym parallels symbol table, indexing into verneed.
vs := f.SectionByType(SHT_GNU_VERSYM)
if vs == nil {
- return
+ return false
}
d, _ = vs.Data()
f.gnuNeed = need
f.gnuVersym = d
+ return true
}
// gnuVersion adds Library and Version information to sym,
// which came from offset i of the symbol table.
-func (f *File) gnuVersion(i int, sym *ImportedSymbol) {
+func (f *File) gnuVersion(i int) (library string, version string) {
// Each entry is two bytes.
i = (i + 1) * 2
if i >= len(f.gnuVersym) {
return
}
n := &f.gnuNeed[j]
- sym.Library = n.File
- sym.Version = n.Name
+ return n.File, n.Name
}
// ImportedLibraries returns the names of all libraries