mirror of
https://github.com/golang/go
synced 2024-09-06 00:19:45 +00:00
cmd/link/internal/loadelf: fix logic for computing ELF flags on ARM
The linker contains complicated logic for figuring out which float ABI to indicate it is using on (32 bit) ARM systems: it parses a special section in host object files to look for a flag indicating use of the hard float ABI. When loadelf got split into its own package a bug was introduced: if the last host object file does not contain a float ABI related tag, the ELF header's flag was set to 0, rather than using the value from the last object file which contained an ABI tag. Fix the code to only change the value used for the ELF header if a tag was found. This fixes an extremely confusing build failure on Ubuntu's armhf builders. Change-Id: I0845d68d082d1383e4cae84ea85164cdc6bcdddb Reviewed-on: https://go-review.googlesource.com/92515 Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
c07095cd28
commit
b2d3d6e676
|
@ -405,13 +405,10 @@ func (a *elfAttributeList) done() bool {
|
||||||
// find the one we are looking for. This format is slightly documented in "ELF
|
// 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
|
// for the ARM Architecture" but mostly this is derived from reading the source
|
||||||
// to gold and readelf.
|
// to gold and readelf.
|
||||||
func parseArmAttributes(e binary.ByteOrder, initEhdrFlags uint32, data []byte) (ehdrFlags uint32, err error) {
|
func parseArmAttributes(e binary.ByteOrder, data []byte) (found bool, ehdrFlags uint32, err error) {
|
||||||
// We assume the soft-float ABI unless we see a tag indicating otherwise.
|
found = false
|
||||||
if initEhdrFlags == 0x5000002 {
|
|
||||||
ehdrFlags = 0x5000202
|
|
||||||
}
|
|
||||||
if data[0] != 'A' {
|
if data[0] != 'A' {
|
||||||
return 0, fmt.Errorf(".ARM.attributes has unexpected format %c\n", data[0])
|
return false, 0, fmt.Errorf(".ARM.attributes has unexpected format %c\n", data[0])
|
||||||
}
|
}
|
||||||
data = data[1:]
|
data = data[1:]
|
||||||
for len(data) != 0 {
|
for len(data) != 0 {
|
||||||
|
@ -421,7 +418,7 @@ func parseArmAttributes(e binary.ByteOrder, initEhdrFlags uint32, data []byte) (
|
||||||
|
|
||||||
nulIndex := bytes.IndexByte(sectiondata, 0)
|
nulIndex := bytes.IndexByte(sectiondata, 0)
|
||||||
if nulIndex < 0 {
|
if nulIndex < 0 {
|
||||||
return 0, fmt.Errorf("corrupt .ARM.attributes (section name not NUL-terminated)\n")
|
return false, 0, fmt.Errorf("corrupt .ARM.attributes (section name not NUL-terminated)\n")
|
||||||
}
|
}
|
||||||
name := string(sectiondata[:nulIndex])
|
name := string(sectiondata[:nulIndex])
|
||||||
sectiondata = sectiondata[nulIndex+1:]
|
sectiondata = sectiondata[nulIndex+1:]
|
||||||
|
@ -442,15 +439,16 @@ func parseArmAttributes(e binary.ByteOrder, initEhdrFlags uint32, data []byte) (
|
||||||
for !attrList.done() {
|
for !attrList.done() {
|
||||||
attr := attrList.armAttr()
|
attr := attrList.armAttr()
|
||||||
if attr.tag == TagABIVFPArgs && attr.ival == 1 {
|
if attr.tag == TagABIVFPArgs && attr.ival == 1 {
|
||||||
|
found = true
|
||||||
ehdrFlags = 0x5000402 // has entry point, Version5 EABI, hard-float ABI
|
ehdrFlags = 0x5000402 // has entry point, Version5 EABI, hard-float ABI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if attrList.err != nil {
|
if attrList.err != nil {
|
||||||
return 0, fmt.Errorf("could not parse .ARM.attributes\n")
|
return false, 0, fmt.Errorf("could not parse .ARM.attributes\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ehdrFlags, nil
|
return found, ehdrFlags, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load loads the ELF file pn from f.
|
// Load loads the ELF file pn from f.
|
||||||
|
@ -686,11 +684,20 @@ func Load(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, pkg string, length i
|
||||||
if err := elfmap(elfobj, sect); err != nil {
|
if err := elfmap(elfobj, sect); err != nil {
|
||||||
return errorf("%s: malformed elf file: %v", pn, err)
|
return errorf("%s: malformed elf file: %v", pn, err)
|
||||||
}
|
}
|
||||||
ehdrFlags, err = parseArmAttributes(e, initEhdrFlags, sect.base[:sect.size])
|
// We assume the soft-float ABI unless we see a tag indicating otherwise.
|
||||||
|
if initEhdrFlags == 0x5000002 {
|
||||||
|
ehdrFlags = 0x5000202
|
||||||
|
} else {
|
||||||
|
ehdrFlags = initEhdrFlags
|
||||||
|
}
|
||||||
|
found, newEhdrFlags, err := parseArmAttributes(e, sect.base[:sect.size])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO(dfc) should this return an error?
|
// TODO(dfc) should this return an error?
|
||||||
log.Printf("%s: %v", pn, err)
|
log.Printf("%s: %v", pn, err)
|
||||||
}
|
}
|
||||||
|
if found {
|
||||||
|
ehdrFlags = newEhdrFlags
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (sect.type_ != ElfSectProgbits && sect.type_ != ElfSectNobits) || sect.flags&ElfSectFlagAlloc == 0 {
|
if (sect.type_ != ElfSectProgbits && sect.type_ != ElfSectNobits) || sect.flags&ElfSectFlagAlloc == 0 {
|
||||||
continue
|
continue
|
||||||
|
|
Loading…
Reference in a new issue