aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.8.1/libgo/go/debug/macho/file.go
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.8.1/libgo/go/debug/macho/file.go')
-rw-r--r--gcc-4.8.1/libgo/go/debug/macho/file.go517
1 files changed, 0 insertions, 517 deletions
diff --git a/gcc-4.8.1/libgo/go/debug/macho/file.go b/gcc-4.8.1/libgo/go/debug/macho/file.go
deleted file mode 100644
index 6577803a0..000000000
--- a/gcc-4.8.1/libgo/go/debug/macho/file.go
+++ /dev/null
@@ -1,517 +0,0 @@
-// Copyright 2009 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 macho implements access to Mach-O object files.
-package macho
-
-// High level access to low level data structures.
-
-import (
- "bytes"
- "debug/dwarf"
- "encoding/binary"
- "errors"
- "fmt"
- "io"
- "os"
-)
-
-// A File represents an open Mach-O file.
-type File struct {
- FileHeader
- ByteOrder binary.ByteOrder
- Loads []Load
- Sections []*Section
-
- Symtab *Symtab
- Dysymtab *Dysymtab
-
- closer io.Closer
-}
-
-// A Load represents any Mach-O load command.
-type Load interface {
- Raw() []byte
-}
-
-// A LoadBytes is the uninterpreted bytes of a Mach-O load command.
-type LoadBytes []byte
-
-func (b LoadBytes) Raw() []byte { return b }
-
-// A SegmentHeader is the header for a Mach-O 32-bit or 64-bit load segment command.
-type SegmentHeader struct {
- Cmd LoadCmd
- Len uint32
- Name string
- Addr uint64
- Memsz uint64
- Offset uint64
- Filesz uint64
- Maxprot uint32
- Prot uint32
- Nsect uint32
- Flag uint32
-}
-
-// A Segment represents a Mach-O 32-bit or 64-bit load segment command.
-type Segment struct {
- LoadBytes
- SegmentHeader
-
- // Embed ReaderAt for ReadAt method.
- // Do not embed SectionReader directly
- // to avoid having Read and Seek.
- // If a client wants Read and Seek it must use
- // Open() to avoid fighting over the seek offset
- // with other clients.
- io.ReaderAt
- sr *io.SectionReader
-}
-
-// Data reads and returns the contents of the segment.
-func (s *Segment) Data() ([]byte, error) {
- dat := make([]byte, s.sr.Size())
- n, err := s.sr.ReadAt(dat, 0)
- return dat[0:n], err
-}
-
-// Open returns a new ReadSeeker reading the segment.
-func (s *Segment) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) }
-
-type SectionHeader struct {
- Name string
- Seg string
- Addr uint64
- Size uint64
- Offset uint32
- Align uint32
- Reloff uint32
- Nreloc uint32
- Flags uint32
-}
-
-type Section struct {
- SectionHeader
-
- // Embed ReaderAt for ReadAt method.
- // Do not embed SectionReader directly
- // to avoid having Read and Seek.
- // If a client wants Read and Seek it must use
- // Open() to avoid fighting over the seek offset
- // with other clients.
- io.ReaderAt
- sr *io.SectionReader
-}
-
-// Data reads and returns the contents of the Mach-O section.
-func (s *Section) Data() ([]byte, error) {
- dat := make([]byte, s.sr.Size())
- n, err := s.sr.ReadAt(dat, 0)
- return dat[0:n], err
-}
-
-// Open returns a new ReadSeeker reading the Mach-O section.
-func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) }
-
-// A Dylib represents a Mach-O load dynamic library command.
-type Dylib struct {
- LoadBytes
- Name string
- Time uint32
- CurrentVersion uint32
- CompatVersion uint32
-}
-
-// A Symtab represents a Mach-O symbol table command.
-type Symtab struct {
- LoadBytes
- SymtabCmd
- Syms []Symbol
-}
-
-// A Dysymtab represents a Mach-O dynamic symbol table command.
-type Dysymtab struct {
- LoadBytes
- DysymtabCmd
- IndirectSyms []uint32 // indices into Symtab.Syms
-}
-
-/*
- * Mach-O reader
- */
-
-type FormatError struct {
- off int64
- msg string
- val interface{}
-}
-
-func (e *FormatError) Error() string {
- msg := e.msg
- if e.val != nil {
- msg += fmt.Sprintf(" '%v'", e.val)
- }
- msg += fmt.Sprintf(" in record at byte %#x", e.off)
- return msg
-}
-
-// Open opens the named file using os.Open and prepares it for use as a Mach-O binary.
-func Open(name string) (*File, error) {
- f, err := os.Open(name)
- if err != nil {
- return nil, err
- }
- ff, err := NewFile(f)
- if err != nil {
- f.Close()
- return nil, err
- }
- ff.closer = f
- return ff, nil
-}
-
-// Close closes the File.
-// If the File was created using NewFile directly instead of Open,
-// Close has no effect.
-func (f *File) Close() error {
- var err error
- if f.closer != nil {
- err = f.closer.Close()
- f.closer = nil
- }
- return err
-}
-
-// NewFile creates a new File for accessing a Mach-O binary in an underlying reader.
-// The Mach-O binary is expected to start at position 0 in the ReaderAt.
-func NewFile(r io.ReaderAt) (*File, error) {
- f := new(File)
- sr := io.NewSectionReader(r, 0, 1<<63-1)
-
- // Read and decode Mach magic to determine byte order, size.
- // Magic32 and Magic64 differ only in the bottom bit.
- var ident [4]byte
- if _, err := r.ReadAt(ident[0:], 0); err != nil {
- return nil, err
- }
- be := binary.BigEndian.Uint32(ident[0:])
- le := binary.LittleEndian.Uint32(ident[0:])
- switch Magic32 &^ 1 {
- case be &^ 1:
- f.ByteOrder = binary.BigEndian
- f.Magic = be
- case le &^ 1:
- f.ByteOrder = binary.LittleEndian
- f.Magic = le
- default:
- return nil, &FormatError{0, "invalid magic number", nil}
- }
-
- // Read entire file header.
- if err := binary.Read(sr, f.ByteOrder, &f.FileHeader); err != nil {
- return nil, err
- }
-
- // Then load commands.
- offset := int64(fileHeaderSize32)
- if f.Magic == Magic64 {
- offset = fileHeaderSize64
- }
- dat := make([]byte, f.Cmdsz)
- if _, err := r.ReadAt(dat, offset); err != nil {
- return nil, err
- }
- f.Loads = make([]Load, f.Ncmd)
- bo := f.ByteOrder
- for i := range f.Loads {
- // Each load command begins with uint32 command and length.
- if len(dat) < 8 {
- return nil, &FormatError{offset, "command block too small", nil}
- }
- cmd, siz := LoadCmd(bo.Uint32(dat[0:4])), bo.Uint32(dat[4:8])
- if siz < 8 || siz > uint32(len(dat)) {
- return nil, &FormatError{offset, "invalid command block size", nil}
- }
- var cmddat []byte
- cmddat, dat = dat[0:siz], dat[siz:]
- offset += int64(siz)
- var s *Segment
- switch cmd {
- default:
- f.Loads[i] = LoadBytes(cmddat)
-
- case LoadCmdDylib:
- var hdr DylibCmd
- b := bytes.NewBuffer(cmddat)
- if err := binary.Read(b, bo, &hdr); err != nil {
- return nil, err
- }
- l := new(Dylib)
- if hdr.Name >= uint32(len(cmddat)) {
- return nil, &FormatError{offset, "invalid name in dynamic library command", hdr.Name}
- }
- l.Name = cstring(cmddat[hdr.Name:])
- l.Time = hdr.Time
- l.CurrentVersion = hdr.CurrentVersion
- l.CompatVersion = hdr.CompatVersion
- l.LoadBytes = LoadBytes(cmddat)
- f.Loads[i] = l
-
- case LoadCmdSymtab:
- var hdr SymtabCmd
- b := bytes.NewBuffer(cmddat)
- if err := binary.Read(b, bo, &hdr); err != nil {
- return nil, err
- }
- strtab := make([]byte, hdr.Strsize)
- if _, err := r.ReadAt(strtab, int64(hdr.Stroff)); err != nil {
- return nil, err
- }
- var symsz int
- if f.Magic == Magic64 {
- symsz = 16
- } else {
- symsz = 12
- }
- symdat := make([]byte, int(hdr.Nsyms)*symsz)
- if _, err := r.ReadAt(symdat, int64(hdr.Symoff)); err != nil {
- return nil, err
- }
- st, err := f.parseSymtab(symdat, strtab, cmddat, &hdr, offset)
- if err != nil {
- return nil, err
- }
- f.Loads[i] = st
- f.Symtab = st
-
- case LoadCmdDysymtab:
- var hdr DysymtabCmd
- b := bytes.NewBuffer(cmddat)
- if err := binary.Read(b, bo, &hdr); err != nil {
- return nil, err
- }
- dat := make([]byte, hdr.Nindirectsyms*4)
- if _, err := r.ReadAt(dat, int64(hdr.Indirectsymoff)); err != nil {
- return nil, err
- }
- x := make([]uint32, hdr.Nindirectsyms)
- if err := binary.Read(bytes.NewBuffer(dat), bo, x); err != nil {
- return nil, err
- }
- st := new(Dysymtab)
- st.LoadBytes = LoadBytes(cmddat)
- st.DysymtabCmd = hdr
- st.IndirectSyms = x
- f.Loads[i] = st
- f.Dysymtab = st
-
- case LoadCmdSegment:
- var seg32 Segment32
- b := bytes.NewBuffer(cmddat)
- if err := binary.Read(b, bo, &seg32); err != nil {
- return nil, err
- }
- s = new(Segment)
- s.LoadBytes = cmddat
- s.Cmd = cmd
- s.Len = siz
- s.Name = cstring(seg32.Name[0:])
- s.Addr = uint64(seg32.Addr)
- s.Memsz = uint64(seg32.Memsz)
- s.Offset = uint64(seg32.Offset)
- s.Filesz = uint64(seg32.Filesz)
- s.Maxprot = seg32.Maxprot
- s.Prot = seg32.Prot
- s.Nsect = seg32.Nsect
- s.Flag = seg32.Flag
- f.Loads[i] = s
- for i := 0; i < int(s.Nsect); i++ {
- var sh32 Section32
- if err := binary.Read(b, bo, &sh32); err != nil {
- return nil, err
- }
- sh := new(Section)
- sh.Name = cstring(sh32.Name[0:])
- sh.Seg = cstring(sh32.Seg[0:])
- sh.Addr = uint64(sh32.Addr)
- sh.Size = uint64(sh32.Size)
- sh.Offset = sh32.Offset
- sh.Align = sh32.Align
- sh.Reloff = sh32.Reloff
- sh.Nreloc = sh32.Nreloc
- sh.Flags = sh32.Flags
- f.pushSection(sh, r)
- }
-
- case LoadCmdSegment64:
- var seg64 Segment64
- b := bytes.NewBuffer(cmddat)
- if err := binary.Read(b, bo, &seg64); err != nil {
- return nil, err
- }
- s = new(Segment)
- s.LoadBytes = cmddat
- s.Cmd = cmd
- s.Len = siz
- s.Name = cstring(seg64.Name[0:])
- s.Addr = seg64.Addr
- s.Memsz = seg64.Memsz
- s.Offset = seg64.Offset
- s.Filesz = seg64.Filesz
- s.Maxprot = seg64.Maxprot
- s.Prot = seg64.Prot
- s.Nsect = seg64.Nsect
- s.Flag = seg64.Flag
- f.Loads[i] = s
- for i := 0; i < int(s.Nsect); i++ {
- var sh64 Section64
- if err := binary.Read(b, bo, &sh64); err != nil {
- return nil, err
- }
- sh := new(Section)
- sh.Name = cstring(sh64.Name[0:])
- sh.Seg = cstring(sh64.Seg[0:])
- sh.Addr = sh64.Addr
- sh.Size = sh64.Size
- sh.Offset = sh64.Offset
- sh.Align = sh64.Align
- sh.Reloff = sh64.Reloff
- sh.Nreloc = sh64.Nreloc
- sh.Flags = sh64.Flags
- f.pushSection(sh, r)
- }
- }
- if s != nil {
- s.sr = io.NewSectionReader(r, int64(s.Offset), int64(s.Filesz))
- s.ReaderAt = s.sr
- }
- }
- return f, nil
-}
-
-func (f *File) parseSymtab(symdat, strtab, cmddat []byte, hdr *SymtabCmd, offset int64) (*Symtab, error) {
- bo := f.ByteOrder
- symtab := make([]Symbol, hdr.Nsyms)
- b := bytes.NewBuffer(symdat)
- for i := range symtab {
- var n Nlist64
- if f.Magic == Magic64 {
- if err := binary.Read(b, bo, &n); err != nil {
- return nil, err
- }
- } else {
- var n32 Nlist32
- if err := binary.Read(b, bo, &n32); err != nil {
- return nil, err
- }
- n.Name = n32.Name
- n.Type = n32.Type
- n.Sect = n32.Sect
- n.Desc = n32.Desc
- n.Value = uint64(n32.Value)
- }
- sym := &symtab[i]
- if n.Name >= uint32(len(strtab)) {
- return nil, &FormatError{offset, "invalid name in symbol table", n.Name}
- }
- sym.Name = cstring(strtab[n.Name:])
- sym.Type = n.Type
- sym.Sect = n.Sect
- sym.Desc = n.Desc
- sym.Value = n.Value
- }
- st := new(Symtab)
- st.LoadBytes = LoadBytes(cmddat)
- st.Syms = symtab
- return st, nil
-}
-
-func (f *File) pushSection(sh *Section, r io.ReaderAt) {
- f.Sections = append(f.Sections, sh)
- sh.sr = io.NewSectionReader(r, int64(sh.Offset), int64(sh.Size))
- sh.ReaderAt = sh.sr
-}
-
-func cstring(b []byte) string {
- var i int
- for i = 0; i < len(b) && b[i] != 0; i++ {
- }
- return string(b[0:i])
-}
-
-// Segment returns the first Segment with the given name, or nil if no such segment exists.
-func (f *File) Segment(name string) *Segment {
- for _, l := range f.Loads {
- if s, ok := l.(*Segment); ok && s.Name == name {
- return s
- }
- }
- return nil
-}
-
-// Section returns the first section with the given name, or nil if no such
-// section exists.
-func (f *File) Section(name string) *Section {
- for _, s := range f.Sections {
- if s.Name == name {
- return s
- }
- }
- return nil
-}
-
-// DWARF returns the DWARF debug information for the Mach-O file.
-func (f *File) DWARF() (*dwarf.Data, error) {
- // There are many other DWARF sections, but these
- // are the required ones, and the debug/dwarf package
- // does not use the others, so don't bother loading them.
- var names = [...]string{"abbrev", "info", "line", "str"}
- var dat [len(names)][]byte
- for i, name := range names {
- name = "__debug_" + name
- s := f.Section(name)
- if s == nil {
- return nil, errors.New("missing Mach-O section " + name)
- }
- b, err := s.Data()
- if err != nil && uint64(len(b)) < s.Size {
- return nil, err
- }
- dat[i] = b
- }
-
- abbrev, info, line, str := dat[0], dat[1], dat[2], dat[3]
- return dwarf.New(abbrev, nil, nil, info, line, nil, nil, str)
-}
-
-// ImportedSymbols returns the names of all symbols
-// referred to by the binary f that are expected to be
-// satisfied by other libraries at dynamic load time.
-func (f *File) ImportedSymbols() ([]string, error) {
- if f.Dysymtab == nil || f.Symtab == nil {
- return nil, &FormatError{0, "missing symbol table", nil}
- }
-
- st := f.Symtab
- dt := f.Dysymtab
- var all []string
- for _, s := range st.Syms[dt.Iundefsym : dt.Iundefsym+dt.Nundefsym] {
- all = append(all, s.Name)
- }
- return all, nil
-}
-
-// ImportedLibraries returns the paths of all libraries
-// referred to by the binary f that are expected to be
-// linked with the binary at dynamic link time.
-func (f *File) ImportedLibraries() ([]string, error) {
- var all []string
- for _, l := range f.Loads {
- if lib, ok := l.(*Dylib); ok {
- all = append(all, lib.Name)
- }
- }
- return all, nil
-}