From: Clément Chigot Date: Mon, 29 Apr 2019 14:41:20 +0000 (+0200) Subject: cmd/go: add XCOFF format handler for go version X-Git-Tag: go1.13beta1~499 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=ccbc9a3f9f6479070f5a45a8583d14d158b8bcb0;p=gostls13.git cmd/go: add XCOFF format handler for go version Change-Id: Ib102ae95acfd89fc3c9942a4ec82c74362f62045 Reviewed-on: https://go-review.googlesource.com/c/go/+/174299 Run-TryBot: Ian Lance Taylor Reviewed-by: Ian Lance Taylor --- diff --git a/src/cmd/go/internal/version/exe.go b/src/cmd/go/internal/version/exe.go index 99d9ab9515..281a641964 100644 --- a/src/cmd/go/internal/version/exe.go +++ b/src/cmd/go/internal/version/exe.go @@ -10,11 +10,12 @@ import ( "debug/macho" "debug/pe" "fmt" + "internal/xcoff" "io" "os" ) -// An exe is a generic interface to an OS executable (ELF, Mach-O, PE). +// An exe is a generic interface to an OS executable (ELF, Mach-O, PE, XCOFF). type exe interface { // Close closes the underlying file. Close() error @@ -61,6 +62,15 @@ func openExe(file string) (exe, error) { } return &machoExe{f, e}, nil } + if bytes.HasPrefix(data, []byte{0x01, 0xDF}) || bytes.HasPrefix(data, []byte{0x01, 0xF7}) { + e, err := xcoff.NewFile(f) + if err != nil { + f.Close() + return nil, err + } + return &xcoffExe{f, e}, nil + + } return nil, fmt.Errorf("unrecognized executable format") } @@ -209,3 +219,35 @@ func (x *machoExe) DataStart() uint64 { } return 0 } + +// xcoffExe is the XCOFF (AIX eXtended COFF) implementation of the exe interface. +type xcoffExe struct { + os *os.File + f *xcoff.File +} + +func (x *xcoffExe) Close() error { + return x.os.Close() +} + +func (x *xcoffExe) ReadData(addr, size uint64) ([]byte, error) { + for _, sect := range x.f.Sections { + if uint64(sect.VirtualAddress) <= addr && addr <= uint64(sect.VirtualAddress+sect.Size-1) { + n := uint64(sect.VirtualAddress+sect.Size) - addr + if n > size { + n = size + } + data := make([]byte, n) + _, err := sect.ReadAt(data, int64(addr-uint64(sect.VirtualAddress))) + if err != nil { + return nil, err + } + return data, nil + } + } + return nil, fmt.Errorf("address not mapped") +} + +func (x *xcoffExe) DataStart() uint64 { + return x.f.SectionByType(xcoff.STYP_DATA).VirtualAddress +}