diff --git a/debug/gosym/pclntab.go b/debug/gosym/pclntab.go index ffa1bf5..1ca6c88 100644 --- a/debug/gosym/pclntab.go +++ b/debug/gosym/pclntab.go @@ -14,7 +14,6 @@ import ( "bytes" "encoding/binary" "fmt" - "math" "sort" "strings" "sync" @@ -352,8 +351,9 @@ func (t *LineTable) go12Funcs() []Func { } // avoid OOM error on corrupt binaries + // empirically gathered. Most binaries are <= UINT16_MAX, but some truly huge have >= 100000 functions ft := t.funcTab() - if ft.Count() >= math.MaxUint16 { + if ft.Count() >= 350000 { return make([]Func, 1) } diff --git a/main.go b/main.go index f98b360..b357a02 100644 --- a/main.go +++ b/main.go @@ -167,9 +167,10 @@ func main_impl(fileName string, printStdPkgs bool, printFilePaths bool, printTyp } } + var knownPclntabVA = uint64(0) var knownGoTextBase = uint64(0) restartParseWithRealTextBase: - tabs, err := file.PCLineTable(versionOverride, knownGoTextBase) + tabs, err := file.PCLineTable(versionOverride, knownPclntabVA, knownGoTextBase) if err != nil { return ExtractMetadata{}, fmt.Errorf("failed to read pclntab: %w", err) } @@ -223,10 +224,10 @@ restartParseWithRealTextBase: stomppedMagicMetaConstraintsValid = tab.StompMagicCandidateMeta.SuspectedModuleDataVa == tmpModData.VA } - if knownGoTextBase == 0 && stomppedMagicMetaConstraintsValid { + if knownGoTextBase == 0 && knownPclntabVA == 0 && stomppedMagicMetaConstraintsValid { // assign real base and restart pclntab parsing with correct VAs! - // TODO: optimize, we should only restart pclntab parsing of the candidates we know find a moduledata knownGoTextBase = tmpModData.TextVA + knownPclntabVA = tab.PclntabVA goto restartParseWithRealTextBase } diff --git a/main_test.go b/main_test.go index 23e67e1..3343edd 100644 --- a/main_test.go +++ b/main_test.go @@ -144,7 +144,7 @@ func TestWeirdBins(t *testing.T) { }) t.Run("fmtisfun_macho", func(t *testing.T) { - testSymbolRecovery(t, "fmtisfun_macho", 0x10be128, 0x1109260, 0x10879b0) + testSymbolRecovery(t, "fmtisfun_macho", 0x10be140, 0x1109260, 0x10879b0) }) t.Run("fmtisfun_win", func(t *testing.T) {