This repository has been archived by the owner on Sep 7, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from dependabot/re-extract-20190731
Re-extract (2019-07-31)
- Loading branch information
Showing
66 changed files
with
4,082 additions
and
712 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
// Copyright 2018 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
// +build gc | ||
|
||
package goroot | ||
|
||
import ( | ||
"os" | ||
"os/exec" | ||
"path/filepath" | ||
"strings" | ||
"sync" | ||
) | ||
|
||
// IsStandardPackage reports whether path is a standard package, | ||
// given goroot and compiler. | ||
func IsStandardPackage(goroot, compiler, path string) bool { | ||
switch compiler { | ||
case "gc": | ||
dir := filepath.Join(goroot, "src", path) | ||
_, err := os.Stat(dir) | ||
return err == nil | ||
case "gccgo": | ||
return gccgoSearch.isStandard(path) | ||
default: | ||
panic("unknown compiler " + compiler) | ||
} | ||
} | ||
|
||
// gccgoSearch holds the gccgo search directories. | ||
type gccgoDirs struct { | ||
once sync.Once | ||
dirs []string | ||
} | ||
|
||
// gccgoSearch is used to check whether a gccgo package exists in the | ||
// standard library. | ||
var gccgoSearch gccgoDirs | ||
|
||
// init finds the gccgo search directories. If this fails it leaves dirs == nil. | ||
func (gd *gccgoDirs) init() { | ||
gccgo := os.Getenv("GCCGO") | ||
if gccgo == "" { | ||
gccgo = "gccgo" | ||
} | ||
bin, err := exec.LookPath(gccgo) | ||
if err != nil { | ||
return | ||
} | ||
|
||
allDirs, err := exec.Command(bin, "-print-search-dirs").Output() | ||
if err != nil { | ||
return | ||
} | ||
versionB, err := exec.Command(bin, "-dumpversion").Output() | ||
if err != nil { | ||
return | ||
} | ||
version := strings.TrimSpace(string(versionB)) | ||
machineB, err := exec.Command(bin, "-dumpmachine").Output() | ||
if err != nil { | ||
return | ||
} | ||
machine := strings.TrimSpace(string(machineB)) | ||
|
||
dirsEntries := strings.Split(string(allDirs), "\n") | ||
const prefix = "libraries: =" | ||
var dirs []string | ||
for _, dirEntry := range dirsEntries { | ||
if strings.HasPrefix(dirEntry, prefix) { | ||
dirs = filepath.SplitList(strings.TrimPrefix(dirEntry, prefix)) | ||
break | ||
} | ||
} | ||
if len(dirs) == 0 { | ||
return | ||
} | ||
|
||
var lastDirs []string | ||
for _, dir := range dirs { | ||
goDir := filepath.Join(dir, "go", version) | ||
if fi, err := os.Stat(goDir); err == nil && fi.IsDir() { | ||
gd.dirs = append(gd.dirs, goDir) | ||
goDir = filepath.Join(goDir, machine) | ||
if fi, err = os.Stat(goDir); err == nil && fi.IsDir() { | ||
gd.dirs = append(gd.dirs, goDir) | ||
} | ||
} | ||
if fi, err := os.Stat(dir); err == nil && fi.IsDir() { | ||
lastDirs = append(lastDirs, dir) | ||
} | ||
} | ||
gd.dirs = append(gd.dirs, lastDirs...) | ||
} | ||
|
||
// isStandard reports whether path is a standard library for gccgo. | ||
func (gd *gccgoDirs) isStandard(path string) bool { | ||
// Quick check: if the first path component has a '.', it's not | ||
// in the standard library. This skips most GOPATH directories. | ||
i := strings.Index(path, "/") | ||
if i < 0 { | ||
i = len(path) | ||
} | ||
if strings.Contains(path[:i], ".") { | ||
return false | ||
} | ||
|
||
if path == "unsafe" { | ||
// Special case. | ||
return true | ||
} | ||
|
||
gd.once.Do(gd.init) | ||
if gd.dirs == nil { | ||
// We couldn't find the gccgo search directories. | ||
// Best guess, since the first component did not contain | ||
// '.', is that this is a standard library package. | ||
return true | ||
} | ||
|
||
for _, dir := range gd.dirs { | ||
full := filepath.Join(dir, path) | ||
pkgdir, pkg := filepath.Split(full) | ||
for _, p := range [...]string{ | ||
full, | ||
full + ".gox", | ||
pkgdir + "lib" + pkg + ".so", | ||
pkgdir + "lib" + pkg + ".a", | ||
full + ".o", | ||
} { | ||
if fi, err := os.Stat(p); err == nil && !fi.IsDir() { | ||
return true | ||
} | ||
} | ||
} | ||
|
||
return false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,228 @@ | ||
// Copyright 2018 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package xcoff | ||
|
||
import ( | ||
"encoding/binary" | ||
"fmt" | ||
"io" | ||
"os" | ||
"strconv" | ||
"strings" | ||
) | ||
|
||
const ( | ||
SAIAMAG = 0x8 | ||
AIAFMAG = "`\n" | ||
AIAMAG = "<aiaff>\n" | ||
AIAMAGBIG = "<bigaf>\n" | ||
|
||
// Sizeof | ||
FL_HSZ_BIG = 0x80 | ||
AR_HSZ_BIG = 0x70 | ||
) | ||
|
||
type bigarFileHeader struct { | ||
Flmagic [SAIAMAG]byte // Archive magic string | ||
Flmemoff [20]byte // Member table offset | ||
Flgstoff [20]byte // 32-bits global symtab offset | ||
Flgst64off [20]byte // 64-bits global symtab offset | ||
Flfstmoff [20]byte // First member offset | ||
Fllstmoff [20]byte // Last member offset | ||
Flfreeoff [20]byte // First member on free list offset | ||
} | ||
|
||
type bigarMemberHeader struct { | ||
Arsize [20]byte // File member size | ||
Arnxtmem [20]byte // Next member pointer | ||
Arprvmem [20]byte // Previous member pointer | ||
Ardate [12]byte // File member date | ||
Aruid [12]byte // File member uid | ||
Argid [12]byte // File member gid | ||
Armode [12]byte // File member mode (octal) | ||
Arnamlen [4]byte // File member name length | ||
// _ar_nam is removed because it's easier to get name without it. | ||
} | ||
|
||
// Archive represents an open AIX big archive. | ||
type Archive struct { | ||
ArchiveHeader | ||
Members []*Member | ||
|
||
closer io.Closer | ||
} | ||
|
||
// MemberHeader holds information about a big archive file header | ||
type ArchiveHeader struct { | ||
magic string | ||
} | ||
|
||
// Member represents a member of an AIX big archive. | ||
type Member struct { | ||
MemberHeader | ||
sr *io.SectionReader | ||
} | ||
|
||
// MemberHeader holds information about a big archive member | ||
type MemberHeader struct { | ||
Name string | ||
Size uint64 | ||
} | ||
|
||
// OpenArchive opens the named archive using os.Open and prepares it for use | ||
// as an AIX big archive. | ||
func OpenArchive(name string) (*Archive, error) { | ||
f, err := os.Open(name) | ||
if err != nil { | ||
return nil, err | ||
} | ||
arch, err := NewArchive(f) | ||
if err != nil { | ||
f.Close() | ||
return nil, err | ||
} | ||
arch.closer = f | ||
return arch, nil | ||
} | ||
|
||
// Close closes the Archive. | ||
// If the Archive was created using NewArchive directly instead of OpenArchive, | ||
// Close has no effect. | ||
func (a *Archive) Close() error { | ||
var err error | ||
if a.closer != nil { | ||
err = a.closer.Close() | ||
a.closer = nil | ||
} | ||
return err | ||
} | ||
|
||
// NewArchive creates a new Archive for accessing an AIX big archive in an underlying reader. | ||
func NewArchive(r io.ReaderAt) (*Archive, error) { | ||
parseDecimalBytes := func(b []byte) (int64, error) { | ||
return strconv.ParseInt(strings.TrimSpace(string(b)), 10, 64) | ||
} | ||
sr := io.NewSectionReader(r, 0, 1<<63-1) | ||
|
||
// Read File Header | ||
var magic [SAIAMAG]byte | ||
if _, err := sr.ReadAt(magic[:], 0); err != nil { | ||
return nil, err | ||
} | ||
|
||
arch := new(Archive) | ||
switch string(magic[:]) { | ||
case AIAMAGBIG: | ||
arch.magic = string(magic[:]) | ||
case AIAMAG: | ||
return nil, fmt.Errorf("small AIX archive not supported") | ||
default: | ||
return nil, fmt.Errorf("unrecognised archive magic: 0x%x", magic) | ||
} | ||
|
||
var fhdr bigarFileHeader | ||
if _, err := sr.Seek(0, os.SEEK_SET); err != nil { | ||
return nil, err | ||
} | ||
if err := binary.Read(sr, binary.BigEndian, &fhdr); err != nil { | ||
return nil, err | ||
} | ||
|
||
off, err := parseDecimalBytes(fhdr.Flfstmoff[:]) | ||
if err != nil { | ||
return nil, fmt.Errorf("error parsing offset of first member in archive header(%q); %v", fhdr, err) | ||
} | ||
|
||
if off == 0 { | ||
// Occurs if the archive is empty. | ||
return arch, nil | ||
} | ||
|
||
lastoff, err := parseDecimalBytes(fhdr.Fllstmoff[:]) | ||
if err != nil { | ||
return nil, fmt.Errorf("error parsing offset of first member in archive header(%q); %v", fhdr, err) | ||
} | ||
|
||
// Read members | ||
for { | ||
// Read Member Header | ||
// The member header is normally 2 bytes larger. But it's easier | ||
// to read the name if the header is read without _ar_nam. | ||
// However, AIAFMAG must be read afterward. | ||
if _, err := sr.Seek(off, os.SEEK_SET); err != nil { | ||
return nil, err | ||
} | ||
|
||
var mhdr bigarMemberHeader | ||
if err := binary.Read(sr, binary.BigEndian, &mhdr); err != nil { | ||
return nil, err | ||
} | ||
|
||
member := new(Member) | ||
arch.Members = append(arch.Members, member) | ||
|
||
size, err := parseDecimalBytes(mhdr.Arsize[:]) | ||
if err != nil { | ||
return nil, fmt.Errorf("error parsing size in member header(%q); %v", mhdr, err) | ||
} | ||
member.Size = uint64(size) | ||
|
||
// Read name | ||
namlen, err := parseDecimalBytes(mhdr.Arnamlen[:]) | ||
if err != nil { | ||
return nil, fmt.Errorf("error parsing name length in member header(%q); %v", mhdr, err) | ||
} | ||
name := make([]byte, namlen) | ||
if err := binary.Read(sr, binary.BigEndian, name); err != nil { | ||
return nil, err | ||
} | ||
member.Name = string(name) | ||
|
||
fileoff := off + AR_HSZ_BIG + namlen | ||
if fileoff&1 != 0 { | ||
fileoff++ | ||
if _, err := sr.Seek(1, os.SEEK_CUR); err != nil { | ||
return nil, err | ||
} | ||
} | ||
|
||
// Read AIAFMAG string | ||
var fmag [2]byte | ||
if err := binary.Read(sr, binary.BigEndian, &fmag); err != nil { | ||
return nil, err | ||
} | ||
if string(fmag[:]) != AIAFMAG { | ||
return nil, fmt.Errorf("AIAFMAG not found after member header") | ||
} | ||
|
||
fileoff += 2 // Add the two bytes of AIAFMAG | ||
member.sr = io.NewSectionReader(sr, fileoff, size) | ||
|
||
if off == lastoff { | ||
break | ||
} | ||
off, err = parseDecimalBytes(mhdr.Arnxtmem[:]) | ||
if err != nil { | ||
return nil, fmt.Errorf("error parsing offset of first member in archive header(%q); %v", fhdr, err) | ||
} | ||
|
||
} | ||
|
||
return arch, nil | ||
|
||
} | ||
|
||
// GetFile returns the XCOFF file defined by member name. | ||
// FIXME: This doesn't work if an archive has two members with the same | ||
// name which can occur if a archive has both 32-bits and 64-bits files. | ||
func (arch *Archive) GetFile(name string) (*File, error) { | ||
for _, mem := range arch.Members { | ||
if mem.Name == name { | ||
return NewFile(mem.sr) | ||
} | ||
} | ||
return nil, fmt.Errorf("unknown member %s in archive", name) | ||
|
||
} |
Oops, something went wrong.