aboutsummaryrefslogtreecommitdiff
path: root/src/debug
diff options
context:
space:
mode:
authorCherry Mui <cherryyz@google.com>2025-08-04 10:30:26 -0400
committerCherry Mui <cherryyz@google.com>2025-08-06 12:28:05 -0700
commit2747f925dd1f08f9b9a1ef23170ee601519d70c2 (patch)
treeff86a3b5b243b0b27f0cd22d5a77770f52e2ea26 /src/debug
parent025d36917c8f56baede2f477131bbf08bf1382ca (diff)
downloadgo-2747f925dd1f08f9b9a1ef23170ee601519d70c2.tar.xz
debug/macho: support reading imported symbols without LC_DYSYMTAB
Currently, the ImportedSymbols method requires an LC_DYSYMTAB load command to exist. However, a Mach-O object file may not have an LC_DYSYMTAB load command, e.g. the one produced by "ld -r". Support this case by just reading the symbol table and gathers undefined symbols. Updates #61229. Change-Id: I8b4761ac7d99e1f1f378e883e9be75ee4049ffbb Reviewed-on: https://go-review.googlesource.com/c/go/+/692995 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: David Chase <drchase@google.com>
Diffstat (limited to 'src/debug')
-rw-r--r--src/debug/macho/file.go19
-rw-r--r--src/debug/macho/file_test.go38
-rw-r--r--src/debug/macho/testdata/clang-amd64-darwin-ld-r.obj.base641
3 files changed, 50 insertions, 8 deletions
diff --git a/src/debug/macho/file.go b/src/debug/macho/file.go
index fcf28c4b25..52ff81750c 100644
--- a/src/debug/macho/file.go
+++ b/src/debug/macho/file.go
@@ -719,15 +719,28 @@ func (f *File) DWARF() (*dwarf.Data, error) {
// 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
}
diff --git a/src/debug/macho/file_test.go b/src/debug/macho/file_test.go
index 313c376c54..fbcc7bdcb0 100644
--- a/src/debug/macho/file_test.go
+++ b/src/debug/macho/file_test.go
@@ -9,15 +9,17 @@ import (
"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{
@@ -46,6 +48,7 @@ var fileTests = []fileTest{
{"__jump_table", "__IMPORT", 0x3000, 0xa, 0x2000, 0x6, 0x0, 0x0, 0x4000008},
},
nil,
+ nil,
},
{
"testdata/gcc-amd64-darwin-exec.base64",
@@ -74,6 +77,7 @@ var fileTests = []fileTest{
{"__la_symbol_ptr", "__DATA", 0x100001058, 0x10, 0x1058, 0x2, 0x0, 0x0, 0x7},
},
nil,
+ nil,
},
{
"testdata/gcc-amd64-darwin-exec-debug.base64",
@@ -102,6 +106,7 @@ var fileTests = []fileTest{
{"__debug_str", "__DWARF", 0x10000215c, 0x60, 0x115c, 0x0, 0x0, 0x0, 0x0},
},
nil,
+ nil,
},
{
"testdata/clang-386-darwin-exec-with-rpath.base64",
@@ -126,6 +131,7 @@ var fileTests = []fileTest{
},
nil,
nil,
+ nil,
},
{
"testdata/clang-amd64-darwin-exec-with-rpath.base64",
@@ -150,6 +156,7 @@ var fileTests = []fileTest{
},
nil,
nil,
+ nil,
},
{
"testdata/clang-386-darwin.obj.base64",
@@ -185,6 +192,7 @@ var fileTests = []fileTest{
},
},
},
+ nil,
},
{
"testdata/clang-amd64-darwin.obj.base64",
@@ -221,6 +229,15 @@ var fileTests = []fileTest{
},
},
},
+ []string{"_printf"},
+ },
+ {
+ "testdata/clang-amd64-darwin-ld-r.obj.base64",
+ FileHeader{0xfeedfacf, CpuAmd64, 0x3, 0x1, 0x4, 0x1c0, 0x2000},
+ nil,
+ nil,
+ nil,
+ []string{"_printf"},
},
}
@@ -345,6 +362,17 @@ func TestOpen(t *testing.T) {
}
}
}
+
+ 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)
+ }
+ }
}
}
diff --git a/src/debug/macho/testdata/clang-amd64-darwin-ld-r.obj.base64 b/src/debug/macho/testdata/clang-amd64-darwin-ld-r.obj.base64
new file mode 100644
index 0000000000..036b5746ab
--- /dev/null
+++ b/src/debug/macho/testdata/clang-amd64-darwin-ld-r.obj.base64
@@ -0,0 +1 @@
+z/rt/gcAAAEDAAAAAQAAAAQAAADAAQAAACAAAAAAAAAZAAAAiAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJgAAAAAAAAAAAIAAAAAAACYAAAAAAAAAAcAAAAHAAAABAAAAAAAAABfX3RleHQAAAAAAAAAAAAAX19URVhUAAAAAAAAAAAAAAAAAAAAAAAAKgAAAAAAAAAAAgAABAAAAJgCAAACAAAAAAQAgAAAAAAAAAAAAAAAAF9fY3N0cmluZwAAAAAAAABfX1RFWFQAAAAAAAAAAAAAKgAAAAAAAAAOAAAAAAAAACoCAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAX19laF9mcmFtZQAAAAAAAF9fVEVYVAAAAAAAAAAAAAA4AAAAAAAAAEAAAAAAAAAAOAIAAAMAAACoAgAABAAAAAAAAAAAAAAAAAAAAAAAAABfX2NvbXBhY3RfdW53aW5kX19MRAAAAAAAAAAAAAAAAHgAAAAAAAAAIAAAAAAAAAB4AgAAAwAAAMgCAAABAAAAAAAAAgAAAAAAAAAAAAAAAAIAAAAYAAAA0AIAAAUAAAAgAwAAKAAAACQAAAAQAAAAAAwKAAAAAAApAAAAEAAAANACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABVSInlSIPsEEiNPQAAAADHRfwAAAAAsADoAAAAADHJiUX4ichIg8QQXcNoZWxsbywgd29ybGQKABQAAAAAAAAAAXpSAAF4EAEQDAcIkAEAACQAAAAEAAAA+P////////8qAAAAAAAAAABBDhCGAkMNBgAAAAAAAAAAAAAAAAAAACoAAAAAAAABAAAAAAAAAAAAAAAAAAAAABkAAAAEAAAtCwAAAAAAAB0cAAAAAQAAXBwAAAACAAAMIAAAAAIAAF4gAAAAAwAADgAAAAADAAAOEAAAAB4CAAAqAAAAAAAAABQAAAAOAwAAOAAAAAAAAAAeAAAADgMAAFAAAAAAAAAAAgAAAA8BAAAAAAAAAAAAAAgAAAABAAAAAAAAAAAAAAAgAF9tYWluAF9wcmludGYATEMxAEVIX0ZyYW1lMQBmdW5jLmVoAAAA