// referred to by the binary f that are expected to be
// satisfied by other libraries at dynamic load time.
func (f *File) ImportedSymbols() ([]string, error) {
- if f.Dysymtab == nil || f.Symtab == nil {
+ if f.Symtab == nil {
return nil, &FormatError{0, "missing symbol table", nil}
}
st := f.Symtab
dt := f.Dysymtab
var all []string
- for _, s := range st.Syms[dt.Iundefsym : dt.Iundefsym+dt.Nundefsym] {
- all = append(all, s.Name)
+ if dt != nil {
+ for _, s := range st.Syms[dt.Iundefsym : dt.Iundefsym+dt.Nundefsym] {
+ all = append(all, s.Name)
+ }
+ } else {
+ // From Darwin's include/mach-o/nlist.h
+ const (
+ N_TYPE = 0x0e
+ N_UNDF = 0x0
+ )
+ for _, s := range st.Syms {
+ if s.Type&N_TYPE == N_UNDF && s.Sect == 0 {
+ all = append(all, s.Name)
+ }
+ }
}
return all, nil
}
"internal/obscuretestdata"
"io"
"reflect"
+ "slices"
"testing"
)
type fileTest struct {
- file string
- hdr FileHeader
- loads []any
- sections []*SectionHeader
- relocations map[string][]Reloc
+ file string
+ hdr FileHeader
+ loads []any
+ sections []*SectionHeader
+ relocations map[string][]Reloc
+ importedSyms []string
}
var fileTests = []fileTest{
{"__jump_table", "__IMPORT", 0x3000, 0xa, 0x2000, 0x6, 0x0, 0x0, 0x4000008},
},
nil,
+ nil,
},
{
"testdata/gcc-amd64-darwin-exec.base64",
{"__la_symbol_ptr", "__DATA", 0x100001058, 0x10, 0x1058, 0x2, 0x0, 0x0, 0x7},
},
nil,
+ nil,
},
{
"testdata/gcc-amd64-darwin-exec-debug.base64",
{"__debug_str", "__DWARF", 0x10000215c, 0x60, 0x115c, 0x0, 0x0, 0x0, 0x0},
},
nil,
+ nil,
},
{
"testdata/clang-386-darwin-exec-with-rpath.base64",
},
nil,
nil,
+ nil,
},
{
"testdata/clang-amd64-darwin-exec-with-rpath.base64",
},
nil,
nil,
+ nil,
},
{
"testdata/clang-386-darwin.obj.base64",
},
},
},
+ nil,
},
{
"testdata/clang-amd64-darwin.obj.base64",
},
},
},
+ []string{"_printf"},
+ },
+ {
+ "testdata/clang-amd64-darwin-ld-r.obj.base64",
+ FileHeader{0xfeedfacf, CpuAmd64, 0x3, 0x1, 0x4, 0x1c0, 0x2000},
+ nil,
+ nil,
+ nil,
+ []string{"_printf"},
},
}
}
}
}
+
+ if tt.importedSyms != nil {
+ ss, err := f.ImportedSymbols()
+ if err != nil {
+ t.Errorf("open %s: fail to read imported symbols: %v", tt.file, err)
+ }
+ want := tt.importedSyms
+ if !slices.Equal(ss, want) {
+ t.Errorf("open %s: imported symbols differ:\n\thave %v\n\twant %v", tt.file, ss, want)
+ }
+ }
}
}