golang/go · error

corrupt .ARM.attributes (section name not NUL-terminated)

Error message

corrupt .ARM.attributes (section name not NUL-terminated)

What it means

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.

Source

Thrown at src/cmd/link/internal/loadelf/ldelf.go:203

// file-level attribute with tag Tag_VFP_arch and value 1). Unfortunately the
// format used means that we have to parse all of the file-level attributes to
// find the one we are looking for. This format is slightly documented in "ELF
// for the ARM Architecture" but mostly this is derived from reading the source
// to gold and readelf.
func parseArmAttributes(e binary.ByteOrder, data []byte) (found bool, ehdrFlags uint32, err error) {
	found = false
	if data[0] != 'A' {
		return false, 0, fmt.Errorf(".ARM.attributes has unexpected format %c\n", data[0])
	}
	data = data[1:]
	for len(data) != 0 {
		sectionlength := e.Uint32(data)
		sectiondata := data[4:sectionlength]
		data = data[sectionlength:]

		nulIndex := bytes.IndexByte(sectiondata, 0)
		if nulIndex < 0 {
			return false, 0, fmt.Errorf("corrupt .ARM.attributes (section name not NUL-terminated)\n")
		}
		name := string(sectiondata[:nulIndex])
		sectiondata = sectiondata[nulIndex+1:]

		if name != "aeabi" {
			continue
		}
		for len(sectiondata) != 0 {
			subsectiontag, sz := binary.Uvarint(sectiondata)
			subsectionsize := e.Uint32(sectiondata[sz:])
			subsectiondata := sectiondata[sz+4 : subsectionsize]
			sectiondata = sectiondata[subsectionsize:]

			if subsectiontag != TagFile {
				continue
			}
			attrList := elfAttributeList{data: subsectiondata}
			for !attrList.done() {

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Rebuild the ARM object from source with a stable GCC/Clang.
  2. `go clean -cache && go build -a`.
  3. Validate with `readelf -A <obj>`; discard objects it cannot parse.
  4. Reinstall the ARM cross-toolchain if objects are consistently malformed.
Defensive patterns

Strategy: validation

Validate before calling

for obj in $(find build -name '*.o'); do
  readelf -A "$obj" >/dev/null 2>&1 || echo "corrupt ARM attributes (name) in $obj"
done

Try / catch

set +e
go build ./...
rc=$?
set -e
if [ $rc -ne 0 ]; then
  go clean -cache && go build -a ./...
fi

Prevention

When it happens

Trigger: 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.

Common situations: Object from a broken nightly toolchain; cache corruption after a crash; object transferred with a tool that altered bytes (encoding conversion).

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/e4c9a54f7ba2dc29. Report an issue: GitHub.