]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: add XCOFF format handler for go version
authorClément Chigot <clement.chigot@atos.net>
Mon, 29 Apr 2019 14:41:20 +0000 (16:41 +0200)
committerIan Lance Taylor <iant@golang.org>
Mon, 29 Apr 2019 22:17:05 +0000 (22:17 +0000)
Change-Id: Ib102ae95acfd89fc3c9942a4ec82c74362f62045
Reviewed-on: https://go-review.googlesource.com/c/go/+/174299
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/cmd/go/internal/version/exe.go

index 99d9ab9515927ffaf6f0652abe36f2721afa24a8..281a641964d20c0877561d24baff8e0f78d9733f 100644 (file)
@@ -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
+}