golang/go · error
%s and %s symbols must be in the same section
Error message
%s and %s symbols must be in the same section
What it means
loadPETable extracts a byte table from a PE (Windows) binary by slicing the section data between a start symbol's Value and an end symbol's Value. Because the slice is computed against a single section's Data(), both symbols must live in the same PE section; if they do not, the offsets are meaningless and could even panic on a bad slice. The library therefore refuses the operation rather than return garbage. This fires during pclntab/funcdata extraction from a Go PE binary (used by go tool nm, objdump, pprof).
Source
Thrown at src/cmd/internal/objfile/pe.go:179
if len(f.Sections) < int(s.SectionNumber) {
return nil, fmt.Errorf("symbol %s: section number %d is larger than max %d", name, s.SectionNumber, len(f.Sections))
}
return s, nil
}
return nil, fmt.Errorf("no %s symbol found", name)
}
func loadPETable(f *pe.File, sname, ename string) ([]byte, error) {
ssym, err := findPESymbol(f, sname)
if err != nil {
return nil, err
}
esym, err := findPESymbol(f, ename)
if err != nil {
return nil, err
}
if ssym.SectionNumber != esym.SectionNumber {
return nil, fmt.Errorf("%s and %s symbols must be in the same section", sname, ename)
}
sect := f.Sections[ssym.SectionNumber-1]
data, err := sect.Data()
if err != nil {
return nil, err
}
return data[ssym.Value:esym.Value], nil
}
func (f *peFile) goarch() string {
switch f.pe.Machine {
case pe.IMAGE_FILE_MACHINE_I386:
return "386"
case pe.IMAGE_FILE_MACHINE_AMD64:
return "amd64"
case pe.IMAGE_FILE_MACHINE_ARM64:
return "arm64"
default:View on GitHub (pinned to b6b368adc5)
Solutions
- Rebuild the Windows binary with a stock 'go build' and avoid objcopy/manual section manipulation.
- Confirm the binary was produced by the Go toolchain for GOOS=windows and has not been stripped of pclntab.
- If you only need symbols, try 'go tool nm' on the original object file before linking instead of the final .exe.
Defensive patterns
Strategy: try-catch
Try / catch
// data, err := loadPETable(pe, "runtime.pclntab", "runtime.epclntab")
// if err != nil {
// if strings.Contains(err.Error(), "must be in the same section") {
// // binary is unsuitable for table extraction; fall back to symbol-only tooling
// }
// return err
// } Prevention
- Only feed stock 'go build' Windows binaries to objfile-based tools.
- Avoid objcopy/manual section manipulation on Go .exe files.
- Keep pclntab/epclntab symbols intact (do not strip aggressively).
When it happens
Trigger: Calling loadPETable (directly or via pclntab loading) where findPESymbol(sname).SectionNumber != findPESymbol(ename).SectionNumber — e.g. 'runtime.pclntab' and 'runtime.epclntab' resolved to different PE sections.
Common situations: Inspecting a Windows .exe that was post-processed by objcopy/stripping tools that re-laid-out sections, a corrupted PE binary, or a hand-crafted/merged object file. Also possible if the wrong start/end symbol pair is requested for the binary's Go version.
Related errors
- symbol %s: invalid section number %d
- no %s symbol found
- pe file format not recognized
- invalid section number in symbol table
- text section not found
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/9a61946f5ad2cb94.
Report an issue: GitHub.