{"record":{"id":"a0d6f9e683213034","repo":"golang/go","slug":"pdata-symbol-q-has-invalid-relocation-count","errorCode":null,"errorMessage":".pdata symbol %q has invalid relocation count","messagePattern":"\\.pdata symbol %q has invalid relocation count","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/link/internal/loadpe/seh.go","lineNumber":46,"sourceCode":"\tcase sys.AMD64:\n\t\treturn processSEHAMD64(ldr, pdata)\n\tdefault:\n\t\t// TODO: support SEH on other architectures.\n\t\treturn nil, fmt.Errorf(\"unsupported architecture for SEH: %v\", arch.Family)\n\t}\n}\n\nfunc processSEHAMD64(ldr *loader.Loader, pdata sym.LoaderSym) ([]loader.Sym, error) {\n\t// The following loop traverses a list of pdata entries,\n\t// each entry being 3 relocations long. The first relocation\n\t// is a pointer to the function symbol to which the pdata entry\n\t// corresponds. The third relocation is a pointer to the\n\t// corresponding .xdata entry.\n\t// Reference:\n\t// https://learn.microsoft.com/en-us/cpp/build/exception-handling-x64#struct-runtime_function\n\trels := ldr.Relocs(pdata)\n\tif rels.Count()%3 != 0 {\n\t\treturn nil, fmt.Errorf(\".pdata symbol %q has invalid relocation count\", ldr.SymName(pdata))\n\t}\n\tdata := ldr.Data(pdata)\n\tentries := make([]loader.Sym, 0, rels.Count()/3)\n\n\tfor i := 0; i < rels.Count(); i += 3 {\n\t\t// Create a new symbol for the pdata entry.\n\t\tentry := ldr.MakeSymbolBuilder(\"\")\n\t\tentry.SetType(sym.SSEHSECT)\n\t\tentry.SetAlign(4)\n\t\tentry.SetSize(12)\n\t\tentryOff := int(rels.At(i).Off())\n\t\tentryEnd := entryOff + 4*3\n\t\tentry.SetData(data[entryOff:entryEnd:entryEnd])\n\n\t\t// Add a relocation from the target function to the pdata entry\n\t\t// and to the exception handler, if present, to ensure they are\n\t\t// retained by dead code elimination.\n\t\tif targetFunc := rels.At(i).Sym(); targetFunc != 0 {","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/link/internal/loadpe/seh.go#L28-L64","documentation":"The Go linker's SEH processor found a `.pdata` section whose relocation count is not a multiple of 3. On AMD64 Windows, each `RUNTIME_FUNCTION` entry in `.pdata` consists of exactly 3 relocations (function start, function end, and unwind info pointer). A relocation count not divisible by 3 means the pdata section is malformed or was produced by a non-standard toolchain.","triggerScenarios":"Fires in `processSEHAMD64` at seh.go:44-46 when `rels.Count()%3 != 0` for the `.pdata` symbol being processed. This check validates that pdata entries follow the standard 3-relocation-per-entry layout documented in the Microsoft PE specification (referenced via URL at seh.go:43).","commonSituations":"Linking a corrupt or manually-constructed PE object file with a malformed .pdata section. Using a very old or experimental C compiler that emits non-standard pdata relocation layouts. File truncation or corruption of the object file. Mixing object files from different architectures or ABI conventions. A linker bug that miscounts relocations when merging sections from multiple object files.","solutions":["Clean and rebuild all object files from source to eliminate corruption: `go clean -cache && go build`.","Inspect the offending object file's .pdata section with `dumpbin /headers file.obj` or `objdump -x file.obj` to verify the relocation count.","Recompile the C/C++ code with a standard, up-to-date compiler (MSVC or MinGW-w64) that emits compliant pdata sections.","Use external linker mode (`-ldflags=-linkmode=external`) to bypass Go's internal pdata processing.","Isolate which object file triggers the error by building incrementally, then inspect or rebuild that specific file."],"exampleFix":"# Bypass internal SEH processing with external linker\ngo build -ldflags='-linkmode=external' ./...\n\n# Or clean and rebuild to fix corruption\ngo clean -cache\ngo build ./...","handlingStrategy":"validation","validationCode":"// Validate .pdata relocation count before relying on SEH processing\n// External check: dumpbin /relocations file.obj | grep pdata\n// Ensure the count is divisible by 3.\n// Not callable from Go user code — this is linker-internal.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Rebuild object files from source after any compiler update to ensure consistent relocation formats.","Use -ldflags=-linkmode=external if the internal linker rejects pdata.","Verify object files with dumpbin or objdump before linking if they come from non-standard sources."],"tags":["linker","pe","seh","pdata","relocation","windows","object-file"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}