func Parse(objPath, pkgPath string, importMap ImportMap) (*Package, error) {
	p := new(Package)
	p.ImportPath = pkgPath
	if _, err := parse(objPath, p, importMap, false); err != nil {
		return nil, err
	}
	return p, nil
}
Parse parses an object file or archive from objPath, assuming that
its import path is pkgpath. A function that returns paths of object
files from import paths can optionally be passed in as importMap
to optimize looking up paths to dependencies' object files.
package goobj2
import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"strconv"
	"strings"
	"github.com/Binject/debug/goobj2/internal/goobj2"
	"github.com/Binject/debug/goobj2/internal/objabi"
)
const (
	CompilerObjName = "__.PKGDEF"
	archiveHeaderLen = 60
)
type Package struct {
	ArchiveMembers []ArchiveMember
	ImportPath     string
	os   string
	arch string
}
func (p Package) OS() string {
	return p.os
}
func (p Package) Arch() string {
	return p.arch
}
type ArchiveMember struct {
	ArchiveHeader ArchiveHeader
	ObjHeader     goobj2.Header
	Imports       []goobj2.ImportedPkg
	Packages      []string
	DWARFFileList []string
	SymDefs       []*Sym
	NonPkgSymDefs []*Sym
	NonPkgSymRefs []*Sym
	SymRefs       []SymRef
	IsDataObj bool
	textSyms []*Sym
	symMap map[int]*Sym
}
func (a ArchiveMember) IsCompilerObj() bool {
	return a.ArchiveHeader.Name == CompilerObjName
}
type ArchiveHeader struct {
	Name string
	Date string
	UID  string
	GID  string
	Mode string
	Size int64
	Data []byte
}
type Sym struct {
	Name  string
	ABI   uint16
	Kind  SymKind  
	Flag  uint8
	Size  uint32  
	Align uint32
	Type  *SymRef  
	Data  []byte   
	Reloc []Reloc  
	Func  *Func    
}
type SymRef struct {
	Name string
	goobj2.SymRef
}
type Reloc struct {
	Name string
	Offset int64
	Size   int64
	Sym    goobj2.SymRef
	Add    int64
	Type objabi.RelocType
}
type Func struct {
	Args     int64       
	Frame    int64       
	PCSP     []byte      
	PCFile   []byte      
	PCLine   []byte      
	PCInline []byte      
	PCData   [][]byte    
	FuncData []FuncData  
	File     []SymRef    
	InlTree  []*InlinedCall
	FuncInfo        *SymRef
	DwarfInfo       *SymRef
	DwarfLoc        *SymRef
	DwarfRanges     *SymRef
	DwarfDebugLines *SymRef
	dataSymIdx int
}
type FuncData struct {
	Sym    *SymRef  
	Offset uint32   
}
type InlinedCall struct {
	Parent   int32
	File     SymRef
	Line     int32
	Func     SymRef
	ParentPC int32
}
type SymKind uint8
const (
	Sxxx SymKind = iota
	STEXT
	SRODATA
	SNOPTRDATA
	SDATA
	SBSS
	SNOPTRBSS
	STLSBSS
	SDWARFINFO
	SDWARFRANGE
	SDWARFLOC
	SDWARFLINES
	SABIALIAS
	SLIBFUZZER_EXTRA_COUNTER
)
type ImportCfg struct {
	ImportMap map[string]string
	Packages  map[string]ExportInfo
}
type ExportInfo struct {
	Path        string
	IsSharedLib bool
}
func ParseImportCfg(path string) (importCfg ImportCfg, err error) {
	data, err := ioutil.ReadFile(path)
	if err != nil {
		return importCfg, fmt.Errorf("error reading importcfg: %v", err)
	}
	lines := bytes.Count(data, []byte("\n"))
	if lines == -1 {
		return importCfg, errors.New("error parsing importcfg: could not find any newlines")
	}
	importCfg.ImportMap = make(map[string]string)
	importCfg.Packages = make(map[string]ExportInfo, lines)
	for lineNum, line := range strings.Split(string(data), "\n") {
		lineNum++  
		line = strings.TrimSpace(line)
		if line == "" {
			continue
		}
		if line == "" || strings.HasPrefix(line, "#") {
			continue
		}
		var verb, args string
		if i := strings.Index(line, " "); i < 0 {
			verb = line
		} else {
			verb, args = line[:i], strings.TrimSpace(line[i+1:])
		}
		var before, after string
		if i := strings.Index(args, "="); i >= 0 {
			before, after = args[:i], args[i+1:]
		}
		switch verb {
		default:
			return importCfg, fmt.Errorf("error parsing importcfg: %s:%d: unknown directive %q", path, lineNum, verb)
		case "importmap":
			if before == "" || after == "" {
				return importCfg, fmt.Errorf(`error parsing importcfg: %s:%d: invalid importmap: syntax is "importmap path=path"`, path, lineNum)
			}
			importCfg.ImportMap[before] = after
		case "packagefile":
			if before == "" || after == "" {
				return importCfg, fmt.Errorf(`error parsing importcfg: %s:%d: invalid packagefile: syntax is "packagefile path=filename"`, path, lineNum)
			}
			importCfg.Packages[before] = ExportInfo{after, false}
		case "packageshlib":
			if before == "" || after == "" {
				return importCfg, fmt.Errorf(`error parsing importcfg: %s:%d: invalid packageshlib: syntax is "packageshlib path=filename"`, path, lineNum)
			}
			importCfg.Packages[before] = ExportInfo{after, true}
		}
	}
	return importCfg, nil
}
var (
	archiveHeader = []byte("!<arch>\n")
	archiveMagic  = []byte("`\n")
	goobjHeader   = []byte("go objec")  
	archivePathPrefix = filepath.Join("$GOROOT", "pkg")
	errCorruptArchive   = errors.New("corrupt archive")
	errTruncatedArchive = errors.New("truncated archive")
	errCorruptObject    = errors.New("corrupt object file")
	errNotObject        = errors.New("unrecognized object file format")
)
type objReader struct {
	p         *Package
	b         *bufio.Reader
	f         *os.File
	err       error
	offset    int64
	limit     int64
	tmp       [256]byte
	pkgprefix string
	objStart  int64
}
func (r *objReader) init(f *os.File, p *Package) {
	r.f = f
	r.p = p
	r.offset, _ = f.Seek(0, io.SeekCurrent)
	r.limit, _ = f.Seek(0, io.SeekEnd)
	f.Seek(r.offset, io.SeekStart)
	r.b = bufio.NewReader(f)
	if p != nil {
		r.pkgprefix = objabi.PathToPrefix(p.ImportPath) + "."
	}
}
func (r *objReader) error(err error) error {
	if r.err == nil {
		if err == io.EOF {
			err = io.ErrUnexpectedEOF
		}
		r.err = err
	}
	return r.err
}
func (r *objReader) peek(n int) ([]byte, error) {
	if r.err != nil {
		return nil, r.err
	}
	if r.offset >= r.limit {
		r.error(io.ErrUnexpectedEOF)
		return nil, r.err
	}
	b, err := r.b.Peek(n)
	if err != nil {
		if err != bufio.ErrBufferFull {
			r.error(err)
		}
	}
	return b, err
}
func (r *objReader) readByte() byte {
	if r.err != nil {
		return 0
	}
	if r.offset >= r.limit {
		r.error(io.ErrUnexpectedEOF)
		return 0
	}
	b, err := r.b.ReadByte()
	if err != nil {
		if err == io.EOF {
			err = io.ErrUnexpectedEOF
		}
		r.error(err)
		b = 0
	} else {
		r.offset++
	}
	return b
}
func (r *objReader) readFull(b []byte) error {
	if r.err != nil {
		return r.err
	}
	if r.offset+int64(len(b)) > r.limit {
		return r.error(io.ErrUnexpectedEOF)
	}
	n, err := io.ReadFull(r.b, b)
	r.offset += int64(n)
	if err != nil {
		return r.error(err)
	}
	return nil
}
func (r *objReader) readInt() int64 {
	var u uint64
	for shift := uint(0); ; shift += 7 {
		if shift >= 64 {
			r.error(errCorruptObject)
			return 0
		}
		c := r.readByte()
		u |= uint64(c&0x7F) << shift
		if c&0x80 == 0 {
			break
		}
	}
	return int64(u>>1) ^ (int64(u) << 63 >> 63)
}
func (r *objReader) skip(n int64) {
	if n < 0 {
		r.error(fmt.Errorf("debug/goobj: internal error: misuse of skip"))
	}
	if n < int64(len(r.tmp)) {
		r.readFull(r.tmp[:n])
	} else if n <= int64(r.b.Buffered()) {
		for n > int64(len(r.tmp)) {
			r.readFull(r.tmp[:])
			n -= int64(len(r.tmp))
		}
		r.readFull(r.tmp[:n])
	} else {
		_, err := r.f.Seek(r.offset+n, io.SeekStart)
		if err != nil {
			r.error(err)
		}
		r.offset += n
		r.b.Reset(r.f)
	}
}
type ImportMap = func(importPath string) (objectPath string)