// DO NOT EDIT. Generated by code.google.com/p/rsc/cmd/bundle
// bundle -p main -x goobj_ debug/goobj

/* read.go */

// Copyright 2013 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 goobj implements reading of Go object files and archives.
//
// TODO(rsc): Decide where this package should live. (golang.org/issue/6932)
// TODO(rsc): Decide the appropriate integer types for various fields.
// TODO(rsc): Write tests. (File format still up in the air a little.)

package main

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"io"
	"strconv"
	"strings"
)

// A SymKind describes the kind of memory represented by a symbol.
type goobj_SymKind int

// This list is taken from include/link.h.

// Defined SymKind values.
// TODO(rsc): Give idiomatic Go names.
// TODO(rsc): Reduce the number of symbol types in the object files.
const (
	_ goobj_SymKind = iota

	// readonly, executable
	goobj_STEXT
	goobj_SELFRXSECT

	// readonly, non-executable
	goobj_STYPE
	goobj_SSTRING
	goobj_SGOSTRING
	goobj_SGOFUNC
	goobj_SRODATA
	goobj_SFUNCTAB
	goobj_STYPELINK
	goobj_SSYMTAB // TODO: move to unmapped section
	goobj_SPCLNTAB
	goobj_SELFROSECT

	// writable, non-executable
	goobj_SMACHOPLT
	goobj_SELFSECT
	goobj_SMACHO // Mach-O __nl_symbol_ptr
	goobj_SMACHOGOT
	goobj_SNOPTRDATA
	goobj_SINITARR
	goobj_SDATA
	goobj_SWINDOWS
	goobj_SBSS
	goobj_SNOPTRBSS
	goobj_STLSBSS

	// not mapped
	goobj_SXREF
	goobj_SMACHOSYMSTR
	goobj_SMACHOSYMTAB
	goobj_SMACHOINDIRECTPLT
	goobj_SMACHOINDIRECTGOT
	goobj_SFILE
	goobj_SFILEPATH
	goobj_SCONST
	goobj_SDYNIMPORT
	goobj_SHOSTOBJ
)

var goobj_symKindStrings = []string{
	goobj_SBSS:              "SBSS",
	goobj_SCONST:            "SCONST",
	goobj_SDATA:             "SDATA",
	goobj_SDYNIMPORT:        "SDYNIMPORT",
	goobj_SELFROSECT:        "SELFROSECT",
	goobj_SELFRXSECT:        "SELFRXSECT",
	goobj_SELFSECT:          "SELFSECT",
	goobj_SFILE:             "SFILE",
	goobj_SFILEPATH:         "SFILEPATH",
	goobj_SFUNCTAB:          "SFUNCTAB",
	goobj_SGOFUNC:           "SGOFUNC",
	goobj_SGOSTRING:         "SGOSTRING",
	goobj_SHOSTOBJ:          "SHOSTOBJ",
	goobj_SINITARR:          "SINITARR",
	goobj_SMACHO:            "SMACHO",
	goobj_SMACHOGOT:         "SMACHOGOT",
	goobj_SMACHOINDIRECTGOT: "SMACHOINDIRECTGOT",
	goobj_SMACHOINDIRECTPLT: "SMACHOINDIRECTPLT",
	goobj_SMACHOPLT:         "SMACHOPLT",
	goobj_SMACHOSYMSTR:      "SMACHOSYMSTR",
	goobj_SMACHOSYMTAB:      "SMACHOSYMTAB",
	goobj_SNOPTRBSS:         "SNOPTRBSS",
	goobj_SNOPTRDATA:        "SNOPTRDATA",
	goobj_SPCLNTAB:          "SPCLNTAB",
	goobj_SRODATA:           "SRODATA",
	goobj_SSTRING:           "SSTRING",
	goobj_SSYMTAB:           "SSYMTAB",
	goobj_STEXT:             "STEXT",
	goobj_STLSBSS:           "STLSBSS",
	goobj_STYPE:             "STYPE",
	goobj_STYPELINK:         "STYPELINK",
	goobj_SWINDOWS:          "SWINDOWS",
	goobj_SXREF:             "SXREF",
}

func (k goobj_SymKind) String() string {
	if k < 0 || int(k) >= len(goobj_symKindStrings) {
		return fmt.Sprintf("SymKind(%d)", k)
	}
	return goobj_symKindStrings[k]
}

// A Sym is a named symbol in an object file.
type goobj_Sym struct {
	goobj_SymID               // symbol identifier (name and version)
	Kind        goobj_SymKind // kind of symbol
	DupOK       bool          // are duplicate definitions okay?
	Size        int           // size of corresponding data
	Type        goobj_SymID   // symbol for Go type information
	Data        goobj_Data    // memory image of symbol
	Reloc       []goobj_Reloc // relocations to apply to Data
	Func        *goobj_Func   // additional data for functions
}

// A SymID - the combination of Name and Version - uniquely identifies
// a symbol within a package.
type goobj_SymID struct {
	// Name is the name of a symbol.
	Name string

	// Version is zero for symbols with global visibility.
	// Symbols with only file visibility (such as file-level static
	// declarations in C) have a non-zero version distinguishing
	// a symbol in one file from a symbol of the same name
	// in another file
	Version int
}

func (s goobj_SymID) String() string {
	if s.Version == 0 {
		return s.Name
	}
	return fmt.Sprintf("%s<%d>", s.Name, s.Version)
}

// A Data is a reference to data stored in an object file.
// It records the offset and size of the data, so that a client can
// read the data only if necessary.
type goobj_Data struct {
	Offset int64
	Size   int64
}

// A Reloc describes a relocation applied to a memory image to refer
// to an address within a particular symbol.
type goobj_Reloc struct {
	// The bytes at [Offset, Offset+Size) within the memory image
	// should be updated to refer to the address Add bytes after the start
	// of the symbol Sym.
	Offset int
	Size   int
	Sym    goobj_SymID
	Add    int

	// The Type records the form of address expected in the bytes
	// described by the previous fields: absolute, PC-relative, and so on.
	// TODO(rsc): The interpretation of Type is not exposed by this package.
	Type int
}

// A Var describes a variable in a function stack frame: a declared
// local variable, an input argument, or an output result.
type goobj_Var struct {
	// The combination of Name, Kind, and Offset uniquely
	// identifies a variable in a function stack frame.
	// Using fewer of these - in particular, using only Name - does not.
	Name   string // Name of variable.
	Kind   int    // TODO(rsc): Define meaning.
	Offset int    // Frame offset. TODO(rsc): Define meaning.

	Type goobj_SymID // Go type for variable.
}

// Func contains additional per-symbol information specific to functions.
type goobj_Func struct {
	Args     int              // size in bytes of argument frame: inputs and outputs
	Frame    int              // size in bytes of local variable frame
	Leaf     bool             // function omits save of link register (ARM)
	NoSplit  bool             // function omits stack split prologue
	Var      []goobj_Var      // detail about local variables
	PCSP     goobj_Data       // PC → SP offset map
	PCFile   goobj_Data       // PC → file number map (index into File)
	PCLine   goobj_Data       // PC → line number map
	PCData   []goobj_Data     // PC → runtime support data map
	FuncData []goobj_FuncData // non-PC-specific runtime support data
	File     []string         // paths indexed by PCFile
}

// TODO: Add PCData []byte and PCDataIter (similar to liblink).

// A FuncData is a single function-specific data value.
type goobj_FuncData struct {
	Sym    goobj_SymID // symbol holding data
	Offset int64       // offset into symbol for funcdata pointer
}

// A Package is a parsed Go object file or archive defining a Go package.
type goobj_Package struct {
	ImportPath string       // import path denoting this package
	Imports    []string     // packages imported by this package
	Syms       []*goobj_Sym // symbols defined by this package
	MaxVersion int          // maximum Version in any SymID in Syms
}

var (
	goobj_archiveHeader = []byte("!<arch>\n")
	goobj_archiveMagic  = []byte("`\n")
	goobj_goobjHeader   = []byte("go objec") // truncated to size of archiveHeader

	goobj_errCorruptArchive   = errors.New("corrupt archive")
	goobj_errTruncatedArchive = errors.New("truncated archive")
	goobj_errNotArchive       = errors.New("unrecognized archive format")

	goobj_errCorruptObject   = errors.New("corrupt object file")
	goobj_errTruncatedObject = errors.New("truncated object file")
	goobj_errNotObject       = errors.New("unrecognized object file format")
)

// An objReader is an object file reader.
type goobj_objReader struct {
	p         *goobj_Package
	b         *bufio.Reader
	f         io.ReadSeeker
	err       error
	offset    int64
	limit     int64
	tmp       [256]byte
	pkg       string
	pkgprefix string
}

// importPathToPrefix returns the prefix that will be used in the
// final symbol table for the given import path.
// We escape '%', '"', all control characters and non-ASCII bytes,
// and any '.' after the final slash.
//
// See ../../../cmd/ld/lib.c:/^pathtoprefix and
// ../../../cmd/gc/subr.c:/^pathtoprefix.
func goobj_importPathToPrefix(s string) string {
	// find index of last slash, if any, or else -1.
	// used for determining whether an index is after the last slash.
	slash := strings.LastIndex(s, "/")

	// check for chars that need escaping
	n := 0
	for r := 0; r < len(s); r++ {
		if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F {
			n++
		}
	}

	// quick exit
	if n == 0 {
		return s
	}

	// escape
	const hex = "0123456789abcdef"
	p := make([]byte, 0, len(s)+2*n)
	for r := 0; r < len(s); r++ {
		if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F {
			p = append(p, '%', hex[c>>4], hex[c&0xF])
		} else {
			p = append(p, c)
		}
	}

	return string(p)
}

// init initializes r to read package p from f.
func (r *goobj_objReader) init(f io.ReadSeeker, p *goobj_Package) {
	r.f = f
	r.p = p
	r.offset, _ = f.Seek(0, 1)
	r.limit, _ = f.Seek(0, 2)
	f.Seek(r.offset, 0)
	r.b = bufio.NewReader(f)
	r.pkgprefix = goobj_importPathToPrefix(p.ImportPath) + "."
}

// error records that an error occurred.
// It returns only the first error, so that an error
// caused by an earlier error does not discard information
// about the earlier error.
func (r *goobj_objReader) error(err error) error {
	if r.err == nil {
		if err == io.EOF {
			err = io.ErrUnexpectedEOF
		}
		r.err = err
	}
	// panic("corrupt") // useful for debugging
	return r.err
}

// readByte reads and returns a byte from the input file.
// On I/O error or EOF, it records the error but returns byte 0.
// A sequence of 0 bytes will eventually terminate any
// parsing state in the object file. In particular, it ends the
// reading of a varint.
func (r *goobj_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
}

// read reads exactly len(b) bytes from the input file.
// If an error occurs, read returns the error but also
// records it, so it is safe for callers to ignore the result
// as long as delaying the report is not a problem.
func (r *goobj_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
}

// readInt reads a zigzag varint from the input file.
func (r *goobj_objReader) readInt() int {
	var u uint64

	for shift := uint(0); ; shift += 7 {
		if shift >= 64 {
			r.error(goobj_errCorruptObject)
			return 0
		}
		c := r.readByte()
		u |= uint64(c&0x7F) << shift
		if c&0x80 == 0 {
			break
		}
	}

	v := int64(u>>1) ^ (int64(u) << 63 >> 63)
	if int64(int(v)) != v {
		r.error(goobj_errCorruptObject) // TODO
		return 0
	}
	return int(v)
}

// readString reads a length-delimited string from the input file.
func (r *goobj_objReader) readString() string {
	n := r.readInt()
	buf := make([]byte, n)
	r.readFull(buf)
	return string(buf)
}

// readSymID reads a SymID from the input file.
func (r *goobj_objReader) readSymID() goobj_SymID {
	name, vers := r.readString(), r.readInt()

	// In a symbol name in an object file, "". denotes the
	// prefix for the package in which the object file has been found.
	// Expand it.
	name = strings.Replace(name, `"".`, r.pkgprefix, -1)

	// An individual object file only records version 0 (extern) or 1 (static).
	// To make static symbols unique across all files being read, we
	// replace version 1 with the version corresponding to the current
	// file number. The number is incremented on each call to parseObject.
	if vers != 0 {
		vers = r.p.MaxVersion
	}

	return goobj_SymID{name, vers}
}

// readData reads a data reference from the input file.
func (r *goobj_objReader) readData() goobj_Data {
	n := r.readInt()
	d := goobj_Data{Offset: r.offset, Size: int64(n)}
	r.skip(int64(n))
	return d
}

// skip skips n bytes in the input.
func (r *goobj_objReader) skip(n int64) {
	if n < 0 {
		r.error(fmt.Errorf("debug/goobj: internal error: misuse of skip"))
	}
	if n < int64(len(r.tmp)) {
		// Since the data is so small, a just reading from the buffered
		// reader is better than flushing the buffer and seeking.
		r.readFull(r.tmp[:n])
	} else if n <= int64(r.b.Buffered()) {
		// Even though the data is not small, it has already been read.
		// Advance the buffer instead of seeking.
		for n > int64(len(r.tmp)) {
			r.readFull(r.tmp[:])
			n -= int64(len(r.tmp))
		}
		r.readFull(r.tmp[:n])
	} else {
		// Seek, giving up buffered data.
		_, err := r.f.Seek(r.offset+n, 0)
		if err != nil {
			r.error(err)
		}
		r.offset += n
		r.b.Reset(r.f)
	}
}

// Parse parses an object file or archive from r,
// assuming that its import path is pkgpath.
func goobj_Parse(r io.ReadSeeker, pkgpath string) (*goobj_Package, error) {
	if pkgpath == "" {
		pkgpath = `""`
	}
	p := new(goobj_Package)
	p.ImportPath = pkgpath

	var rd goobj_objReader
	rd.init(r, p)
	err := rd.readFull(rd.tmp[:8])
	if err != nil {
		if err == io.EOF {
			err = io.ErrUnexpectedEOF
		}
		return nil, err
	}

	switch {
	default:
		return nil, goobj_errNotObject

	case bytes.Equal(rd.tmp[:8], goobj_archiveHeader):
		if err := rd.parseArchive(); err != nil {
			return nil, err
		}
	case bytes.Equal(rd.tmp[:8], goobj_goobjHeader):
		if err := rd.parseObject(goobj_goobjHeader); err != nil {
			return nil, err
		}
	}

	return p, nil
}

// trimSpace removes trailing spaces from b and returns the corresponding string.
// This effectively parses the form used in archive headers.
func goobj_trimSpace(b []byte) string {
	return string(bytes.TrimRight(b, " "))
}

// parseArchive parses a Unix archive of Go object files.
// TODO(rsc): Need to skip non-Go object files.
// TODO(rsc): Maybe record table of contents in r.p so that
// linker can avoid having code to parse archives too.
func (r *goobj_objReader) parseArchive() error {
	for r.offset < r.limit {
		if err := r.readFull(r.tmp[:60]); err != nil {
			return err
		}
		data := r.tmp[:60]

		// Each file is preceded by this text header (slice indices in first column):
		//	 0:16	name
		//	16:28 date
		//	28:34 uid
		//	34:40 gid
		//	40:48 mode
		//	48:58 size
		//	58:60 magic - `\n
		// We only care about name, size, and magic.
		// The fields are space-padded on the right.
		// The size is in decimal.
		// The file data - size bytes - follows the header.
		// Headers are 2-byte aligned, so if size is odd, an extra padding
		// byte sits between the file data and the next header.
		// The file data that follows is padded to an even number of bytes:
		// if size is odd, an extra padding byte is inserted betw the next header.
		if len(data) < 60 {
			return goobj_errTruncatedArchive
		}
		if !bytes.Equal(data[58:60], goobj_archiveMagic) {
			return goobj_errCorruptArchive
		}
		name := goobj_trimSpace(data[0:16])
		size, err := strconv.ParseInt(goobj_trimSpace(data[48:58]), 10, 64)
		if err != nil {
			return goobj_errCorruptArchive
		}
		data = data[60:]
		fsize := size + size&1
		if fsize < 0 || fsize < size {
			return goobj_errCorruptArchive
		}
		switch name {
		case "__.SYMDEF", "__.GOSYMDEF", "__.PKGDEF":
			r.skip(size)
		default:
			oldLimit := r.limit
			r.limit = r.offset + size
			if err := r.parseObject(nil); err != nil {
				return fmt.Errorf("parsing archive member %q: %v", name, err)
			}
			r.skip(r.limit - r.offset)
			r.limit = oldLimit
		}
		if size&1 != 0 {
			r.skip(1)
		}
	}
	return nil
}

// parseObject parses a single Go object file.
// The prefix is the bytes already read from the file,
// typically in order to detect that this is an object file.
// The object file consists of a textual header ending in "\n!\n"
// and then the part we want to parse begins.
// The format of that part is defined in a comment at the top
// of src/liblink/objfile.c.
func (r *goobj_objReader) parseObject(prefix []byte) error {
	// TODO(rsc): Maybe use prefix and the initial input to
	// record the header line from the file, which would
	// give the architecture and other version information.

	r.p.MaxVersion++
	var c1, c2, c3 byte
	for {
		c1, c2, c3 = c2, c3, r.readByte()
		if c3 == 0 { // NUL or EOF, either is bad
			return goobj_errCorruptObject
		}
		if c1 == '\n' && c2 == '!' && c3 == '\n' {
			break
		}
	}

	r.readFull(r.tmp[:8])
	if !bytes.Equal(r.tmp[:8], []byte("\x00\x00go13ld")) {
		return r.error(goobj_errCorruptObject)
	}

	b := r.readByte()
	if b != 1 {
		return r.error(goobj_errCorruptObject)
	}

	// Direct package dependencies.
	for {
		s := r.readString()
		if s == "" {
			break
		}
		r.p.Imports = append(r.p.Imports, s)
	}

	// Symbols.
	for {
		if b := r.readByte(); b != 0xfe {
			if b != 0xff {
				return r.error(goobj_errCorruptObject)
			}
			break
		}

		typ := r.readInt()
		s := &goobj_Sym{goobj_SymID: r.readSymID()}
		r.p.Syms = append(r.p.Syms, s)
		s.Kind = goobj_SymKind(typ)
		s.DupOK = r.readInt() != 0
		s.Size = r.readInt()
		s.Type = r.readSymID()
		s.Data = r.readData()
		s.Reloc = make([]goobj_Reloc, r.readInt())
		for i := range s.Reloc {
			rel := &s.Reloc[i]
			rel.Offset = r.readInt()
			rel.Size = r.readInt()
			rel.Type = r.readInt()
			rel.Add = r.readInt()
			r.readInt() // Xadd - ignored
			rel.Sym = r.readSymID()
			r.readSymID() // Xsym - ignored
		}

		if s.Kind == goobj_STEXT {
			f := new(goobj_Func)
			s.Func = f
			f.Args = r.readInt()
			f.Frame = r.readInt()
			f.Leaf = r.readInt() != 0
			f.NoSplit = r.readInt() != 0
			f.Var = make([]goobj_Var, r.readInt())
			for i := range f.Var {
				v := &f.Var[i]
				v.Name = r.readSymID().Name
				v.Offset = r.readInt()
				v.Kind = r.readInt()
				v.Type = r.readSymID()
			}

			f.PCSP = r.readData()
			f.PCFile = r.readData()
			f.PCLine = r.readData()
			f.PCData = make([]goobj_Data, r.readInt())
			for i := range f.PCData {
				f.PCData[i] = r.readData()
			}
			f.FuncData = make([]goobj_FuncData, r.readInt())
			for i := range f.FuncData {
				f.FuncData[i].Sym = r.readSymID()
			}
			for i := range f.FuncData {
				f.FuncData[i].Offset = int64(r.readInt()) // TODO
			}
			f.File = make([]string, r.readInt())
			for i := range f.File {
				f.File[i] = r.readSymID().Name
			}
		}
	}

	r.readFull(r.tmp[:7])
	if !bytes.Equal(r.tmp[:7], []byte("\xffgo13ld")) {
		return r.error(goobj_errCorruptObject)
	}

	return nil
}
