debug/buildinfo: implement for Plan 9 a.out

Plan 9 a.out was not implemented for debug/buildinfo, which
was causing test failures on Plan 9. This adds an implementation,
and causes the tests to pass.

Fixes #53949

Change-Id: I90a307ef9babf8cf381f8746d731cac2206b234a
Reviewed-on: https://go-review.googlesource.com/c/go/+/418014
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Benny Siegert <bsiegert@gmail.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
This commit is contained in:
Ori Bernstein 2022-07-17 12:02:30 -04:00 committed by Ian Lance Taylor
parent 5b1658d691
commit 0816d38713

View file

@ -15,6 +15,7 @@ import (
"debug/elf"
"debug/macho"
"debug/pe"
"debug/plan9obj"
"encoding/binary"
"errors"
"fmt"
@ -130,6 +131,12 @@ func readRawBuildInfo(r io.ReaderAt) (vers, mod string, err error) {
return "", "", errUnrecognizedFormat
}
x = &xcoffExe{f}
case hasPlan9Magic(ident):
f, err := plan9obj.NewFile(r)
if err != nil {
return "", "", errUnrecognizedFormat
}
x = &plan9objExe{f}
default:
return "", "", errUnrecognizedFormat
}
@ -205,6 +212,17 @@ func readRawBuildInfo(r io.ReaderAt) (vers, mod string, err error) {
return vers, mod, nil
}
func hasPlan9Magic(magic []byte) bool {
if len(magic) >= 4 {
m := binary.BigEndian.Uint32(magic)
switch m {
case plan9obj.Magic386, plan9obj.MagicAMD64, plan9obj.MagicARM:
return true
}
}
return false
}
func decodeString(data []byte) (s string, rest []byte) {
u, n := binary.Uvarint(data)
if n <= 0 || u >= uint64(len(data)-n) {
@ -389,7 +407,7 @@ func (x *xcoffExe) ReadData(addr, size uint64) ([]byte, error) {
return data, nil
}
}
return nil, fmt.Errorf("address not mapped")
return nil, errors.New("address not mapped")
}
func (x *xcoffExe) DataStart() uint64 {
@ -398,3 +416,34 @@ func (x *xcoffExe) DataStart() uint64 {
}
return 0
}
// plan9objExe is the Plan 9 a.out implementation of the exe interface.
type plan9objExe struct {
f *plan9obj.File
}
func (x *plan9objExe) DataStart() uint64 {
if s := x.f.Section("data"); s != nil {
return uint64(s.Offset)
}
return 0
}
func (x *plan9objExe) ReadData(addr, size uint64) ([]byte, error) {
for _, sect := range x.f.Sections {
if uint64(sect.Offset) <= addr && addr <= uint64(sect.Offset+sect.Size-1) {
n := uint64(sect.Offset+sect.Size) - addr
if n > size {
n = size
}
data := make([]byte, n)
_, err := sect.ReadAt(data, int64(addr-uint64(sect.Offset)))
if err != nil {
return nil, err
}
return data, nil
}
}
return nil, errors.New("address not mapped")
}