]> Cypherpunks repositories - gostls13.git/commitdiff
go/internal/gccgoimporter: add XCOFF support
authorClément Chigot <clement.chigot@atos.net>
Wed, 5 Dec 2018 16:27:24 +0000 (17:27 +0100)
committerIan Lance Taylor <iant@golang.org>
Tue, 11 Dec 2018 18:18:55 +0000 (18:18 +0000)
This commit adds support to read XCOFF files and AIX big archives in
go/internal/gccgoimporter.

Fixes: #29113
Change-Id: Id84d40358ff98fae5a576d1ebdd65980896365b9
Reviewed-on: https://go-review.googlesource.com/c/152720
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/go/build/deps_test.go
src/go/internal/gccgoimporter/ar.go
src/go/internal/gccgoimporter/importer.go

index dd38cc0a6a5821af382a23491c6bb213251cee75..3a70991639e399ae4d11d8287ffd88d922e767e2 100644 (file)
@@ -230,7 +230,7 @@ var pkgDeps = map[string][]string{
        "go/constant":               {"L4", "go/token", "math/big"},
        "go/importer":               {"L4", "go/build", "go/internal/gccgoimporter", "go/internal/gcimporter", "go/internal/srcimporter", "go/token", "go/types"},
        "go/internal/gcimporter":    {"L4", "OS", "go/build", "go/constant", "go/token", "go/types", "text/scanner"},
-       "go/internal/gccgoimporter": {"L4", "OS", "debug/elf", "go/constant", "go/token", "go/types", "text/scanner"},
+       "go/internal/gccgoimporter": {"L4", "OS", "debug/elf", "go/constant", "go/token", "go/types", "internal/xcoff", "text/scanner"},
        "go/internal/srcimporter":   {"L4", "OS", "fmt", "go/ast", "go/build", "go/parser", "go/token", "go/types", "path/filepath"},
        "go/types":                  {"L4", "GOPARSER", "container/heap", "go/constant"},
 
index ebd08b8f35957a04bd87b10b398edbb576d06ac9..443aa26a0cdf57982c8b9f57d1fae495e9643f58 100644 (file)
@@ -9,6 +9,7 @@ import (
        "debug/elf"
        "errors"
        "fmt"
+       "internal/xcoff"
        "io"
        "strconv"
        "strings"
@@ -65,13 +66,13 @@ func arExportData(archive io.ReadSeeker) (io.ReadSeeker, error) {
        case armagt:
                return nil, errors.New("unsupported thin archive")
        case armagb:
-               return nil, errors.New("unsupported AIX big archive")
+               return aixBigArExportData(archive)
        default:
                return nil, fmt.Errorf("unrecognized archive file format %q", buf[:])
        }
 }
 
-// standardArExportData returns export data form a standard archive.
+// standardArExportData returns export data from a standard archive.
 func standardArExportData(archive io.ReadSeeker) (io.ReadSeeker, error) {
        off := int64(len(armag))
        for {
@@ -126,6 +127,28 @@ func elfFromAr(member *io.SectionReader) (io.ReadSeeker, error) {
        return sec.Open(), nil
 }
 
+// aixBigArExportData returns export data from an AIX big archive.
+func aixBigArExportData(archive io.ReadSeeker) (io.ReadSeeker, error) {
+       archiveAt := readerAtFromSeeker(archive)
+       arch, err := xcoff.NewArchive(archiveAt)
+       if err != nil {
+               return nil, err
+       }
+
+       for _, mem := range arch.Members {
+               f, err := arch.GetFile(mem.Name)
+               if err != nil {
+                       return nil, err
+               }
+               sdat := f.CSect(".go_export")
+               if sdat != nil {
+                       return bytes.NewReader(sdat), nil
+               }
+       }
+
+       return nil, fmt.Errorf(".go_export not found in this archive")
+}
+
 // readerAtFromSeeker turns an io.ReadSeeker into an io.ReaderAt.
 // This is only safe because there won't be any concurrent seeks
 // while this code is executing.
index ea111136cdadb8f07e55580206d6f92348458f8b..6856611026f3244756d6a824056616231ae6e120 100644 (file)
@@ -6,9 +6,11 @@
 package gccgoimporter // import "go/internal/gccgoimporter"
 
 import (
+       "bytes"
        "debug/elf"
        "fmt"
        "go/types"
+       "internal/xcoff"
        "io"
        "os"
        "path/filepath"
@@ -65,6 +67,7 @@ const (
        gccgov3Magic    = "v3;\n"
        goimporterMagic = "\n$$ "
        archiveMagic    = "!<ar"
+       aixbigafMagic   = "<big"
 )
 
 // Opens the export data file at the given path. If this is an ELF file,
@@ -89,33 +92,44 @@ func openExportFile(fpath string) (reader io.ReadSeeker, closer io.Closer, err e
                return
        }
 
-       var elfreader io.ReaderAt
+       var objreader io.ReaderAt
        switch string(magic[:]) {
        case gccgov1Magic, gccgov2Magic, gccgov3Magic, goimporterMagic:
                // Raw export data.
                reader = f
                return
 
-       case archiveMagic:
+       case archiveMagic, aixbigafMagic:
                reader, err = arExportData(f)
                return
 
        default:
-               elfreader = f
+               objreader = f
        }
 
-       ef, err := elf.NewFile(elfreader)
-       if err != nil {
+       ef, err := elf.NewFile(objreader)
+       if err == nil {
+               sec := ef.Section(".go_export")
+               if sec == nil {
+                       err = fmt.Errorf("%s: .go_export section not found", fpath)
+                       return
+               }
+               reader = sec.Open()
                return
        }
 
-       sec := ef.Section(".go_export")
-       if sec == nil {
-               err = fmt.Errorf("%s: .go_export section not found", fpath)
+       xf, err := xcoff.NewFile(objreader)
+       if err == nil {
+               sdat := xf.CSect(".go_export")
+               if sdat == nil {
+                       err = fmt.Errorf("%s: .go_export section not found", fpath)
+                       return
+               }
+               reader = bytes.NewReader(sdat)
                return
        }
 
-       reader = sec.Open()
+       err = fmt.Errorf("%s: unrecognized file format", fpath)
        return
 }