{"record":{"id":"e4c9a54f7ba2dc29","repo":"golang/go","slug":"corrupt-arm-attributes-section-name-not-nul-term","errorCode":null,"errorMessage":"corrupt .ARM.attributes (section name not NUL-terminated)\n","messagePattern":"corrupt \\.ARM\\.attributes \\(section name not NUL-terminated\\)\n","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/link/internal/loadelf/ldelf.go","lineNumber":203,"sourceCode":"// file-level attribute with tag Tag_VFP_arch and value 1). Unfortunately the\n// format used means that we have to parse all of the file-level attributes to\n// find the one we are looking for. This format is slightly documented in \"ELF\n// for the ARM Architecture\" but mostly this is derived from reading the source\n// to gold and readelf.\nfunc parseArmAttributes(e binary.ByteOrder, data []byte) (found bool, ehdrFlags uint32, err error) {\n\tfound = false\n\tif data[0] != 'A' {\n\t\treturn false, 0, fmt.Errorf(\".ARM.attributes has unexpected format %c\\n\", data[0])\n\t}\n\tdata = data[1:]\n\tfor len(data) != 0 {\n\t\tsectionlength := e.Uint32(data)\n\t\tsectiondata := data[4:sectionlength]\n\t\tdata = data[sectionlength:]\n\n\t\tnulIndex := bytes.IndexByte(sectiondata, 0)\n\t\tif nulIndex < 0 {\n\t\t\treturn false, 0, fmt.Errorf(\"corrupt .ARM.attributes (section name not NUL-terminated)\\n\")\n\t\t}\n\t\tname := string(sectiondata[:nulIndex])\n\t\tsectiondata = sectiondata[nulIndex+1:]\n\n\t\tif name != \"aeabi\" {\n\t\t\tcontinue\n\t\t}\n\t\tfor len(sectiondata) != 0 {\n\t\t\tsubsectiontag, sz := binary.Uvarint(sectiondata)\n\t\t\tsubsectionsize := e.Uint32(sectiondata[sz:])\n\t\t\tsubsectiondata := sectiondata[sz+4 : subsectionsize]\n\t\t\tsectiondata = sectiondata[subsectionsize:]\n\n\t\t\tif subsectiontag != TagFile {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tattrList := elfAttributeList{data: subsectiondata}\n\t\t\tfor !attrList.done() {","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/link/internal/loadelf/ldelf.go#L185-L221","documentation":"Within `.ARM.attributes`, after the `'A'` byte, the section is a sequence of subsections each beginning with a 4-byte length and a NUL-terminated subsection name (e.g. `aeabi`). If no NUL byte terminates the name within the subsection's declared bounds, the name is unparseable and the linker aborts rather than read past the subsection boundary.","triggerScenarios":"An object whose `.ARM.attributes` subsection length is wrong (too short, cutting off the name) or whose name field is not NUL-terminated; a truncated or corrupted attributes section from a faulty assembler; bit-flip corruption in a cached object.","commonSituations":"Object from a broken nightly toolchain; cache corruption after a crash; object transferred with a tool that altered bytes (encoding conversion).","solutions":["Rebuild the ARM object from source with a stable GCC/Clang.","`go clean -cache && go build -a`.","Validate with `readelf -A <obj>`; discard objects it cannot parse.","Reinstall the ARM cross-toolchain if objects are consistently malformed."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"for obj in $(find build -name '*.o'); do\n  readelf -A \"$obj\" >/dev/null 2>&1 || echo \"corrupt ARM attributes (name) in $obj\"\ndone","typeGuard":null,"tryCatchPattern":"set +e\ngo build ./...\nrc=$?\nset -e\nif [ $rc -ne 0 ]; then\n  go clean -cache && go build -a ./...\nfi","preventionTips":["Rebuild ARM objects with a stable assembler/compiler.","Do not transfer objects through encoding-converting channels.","Validate attributes with `readelf -A` in CI."],"tags":["linker","go-toolchain","arm","elf","abi"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}