diff options
Diffstat (limited to 'src/pkg/debug/macho/file.go')
-rw-r--r-- | src/pkg/debug/macho/file.go | 322 |
1 files changed, 161 insertions, 161 deletions
diff --git a/src/pkg/debug/macho/file.go b/src/pkg/debug/macho/file.go index 233490c83..7c492ef52 100644 --- a/src/pkg/debug/macho/file.go +++ b/src/pkg/debug/macho/file.go @@ -9,53 +9,53 @@ package macho // High level access to low level data structures. import ( - "bytes"; - "debug/dwarf"; - "encoding/binary"; - "fmt"; - "io"; - "os"; + "bytes" + "debug/dwarf" + "encoding/binary" + "fmt" + "io" + "os" ) // A File represents an open Mach-O file. type File struct { - FileHeader; - ByteOrder binary.ByteOrder; - Loads []Load; - Sections []*Section; + FileHeader + ByteOrder binary.ByteOrder + Loads []Load + Sections []*Section - closer io.Closer; + closer io.Closer } // A Load represents any Mach-O load command. type Load interface { - Raw() []byte; + Raw() []byte } // A LoadBytes is the uninterpreted bytes of a Mach-O load command. type LoadBytes []byte -func (b LoadBytes) Raw() []byte { return b } +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; + 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; + LoadBytes + SegmentHeader // Embed ReaderAt for ReadAt method. // Do not embed SectionReader directly @@ -63,34 +63,34 @@ type Segment struct { // 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; + io.ReaderAt + sr *io.SectionReader } // Data reads and returns the contents of the segment. func (s *Segment) Data() ([]byte, os.Error) { - dat := make([]byte, s.sr.Size()); - n, err := s.sr.ReadAt(dat, 0); - return dat[0:n], err; + 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) } +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; + Name string + Seg string + Addr uint64 + Size uint64 + Offset uint32 + Align uint32 + Reloff uint32 + Nreloc uint32 + Flags uint32 } type Section struct { - SectionHeader; + SectionHeader // Embed ReaderAt for ReadAt method. // Do not embed SectionReader directly @@ -98,19 +98,19 @@ type Section struct { // 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; + io.ReaderAt + sr *io.SectionReader } // Data reads and returns the contents of the Mach-O section. func (s *Section) Data() ([]byte, os.Error) { - dat := make([]byte, s.sr.Size()); - n, err := s.sr.ReadAt(dat, 0); - return dat[0:n], err; + 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) } +func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) } /* @@ -118,68 +118,68 @@ func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<< */ type FormatError struct { - off int64; - msg string; - val interface{}; + off int64 + msg string + val interface{} } func (e *FormatError) String() string { - msg := e.msg; + 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; + 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, os.Error) { - f, err := os.Open(name, os.O_RDONLY, 0); + f, err := os.Open(name, os.O_RDONLY, 0) if err != nil { return nil, err } - ff, err := NewFile(f); + ff, err := NewFile(f) if err != nil { - f.Close(); - return nil, err; + f.Close() + return nil, err } - ff.closer = f; - return ff, nil; + 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() os.Error { - var err os.Error; + var err os.Error if f.closer != nil { - err = f.closer.Close(); - f.closer = nil; + err = f.closer.Close() + f.closer = nil } - return err; + return err } // NewFile creates a new File for acecssing 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, os.Error) { - f := new(File); - sr := io.NewSectionReader(r, 0, 1<<63-1); + 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]uint8; + var ident [4]uint8 if _, err := r.ReadAt(&ident, 0); err != nil { return nil, err } - be := binary.BigEndian.Uint32(&ident); - le := binary.LittleEndian.Uint32(&ident); + be := binary.BigEndian.Uint32(&ident) + le := binary.LittleEndian.Uint32(&ident) switch Magic32 &^ 1 { case be &^ 1: - f.ByteOrder = binary.BigEndian; - f.Magic = be; + f.ByteOrder = binary.BigEndian + f.Magic = be case le &^ 1: - f.ByteOrder = binary.LittleEndian; - f.Magic = le; + f.ByteOrder = binary.LittleEndian + f.Magic = le } // Read entire file header. @@ -188,138 +188,138 @@ func NewFile(r io.ReaderAt) (*File, os.Error) { } // Then load commands. - offset := int64(fileHeaderSize32); + offset := int64(fileHeaderSize32) if f.Magic == Magic64 { offset = fileHeaderSize64 } - dat := make([]byte, f.Cmdsz); + 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; + 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]); + 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; + 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 LoadCmdSegment: - var seg32 Segment32; - b := bytes.NewBuffer(cmddat); + 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); - 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; + s = new(Segment) + s.LoadBytes = cmddat + s.Cmd = cmd + s.Len = siz + s.Name = cstring(&seg32.Name) + 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; + var sh32 Section32 if err := binary.Read(b, bo, &sh32); err != nil { return nil, err } - sh := new(Section); - sh.Name = cstring(&sh32.Name); - sh.Seg = cstring(&sh32.Seg); - 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); + sh := new(Section) + sh.Name = cstring(&sh32.Name) + sh.Seg = cstring(&sh32.Seg) + 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); + 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); - 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; + s = new(Segment) + s.LoadBytes = cmddat + s.Cmd = cmd + s.Len = siz + s.Name = cstring(&seg64.Name) + 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; + var sh64 Section64 if err := binary.Read(b, bo, &sh64); err != nil { return nil, err } - sh := new(Section); - sh.Name = cstring(&sh64.Name); - sh.Seg = cstring(&sh64.Seg); - 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); + sh := new(Section) + sh.Name = cstring(&sh64.Name) + sh.Seg = cstring(&sh64.Seg) + 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; + s.sr = io.NewSectionReader(r, int64(s.Offset), int64(s.Filesz)) + s.ReaderAt = s.sr } } - return f, nil; + return f, nil } func (f *File) pushSection(sh *Section, r io.ReaderAt) { - n := len(f.Sections); + n := len(f.Sections) if n >= cap(f.Sections) { - m := (n + 1) * 2; - new := make([]*Section, n, m); + m := (n + 1) * 2 + new := make([]*Section, n, m) for i, sh := range f.Sections { new[i] = sh } - f.Sections = new; + f.Sections = new } - f.Sections = f.Sections[0 : n+1]; - f.Sections[n] = sh; - sh.sr = io.NewSectionReader(r, int64(sh.Offset), int64(sh.Size)); - sh.ReaderAt = sh.sr; + f.Sections = f.Sections[0 : n+1] + f.Sections[n] = sh + sh.sr = io.NewSectionReader(r, int64(sh.Offset), int64(sh.Size)) + sh.ReaderAt = sh.sr } func cstring(b []byte) string { - var i int; + var i int for i = 0; i < len(b) && b[i] != 0; i++ { } - return string(b[0:i]); + return string(b[0:i]) } // Segment returns the first Segment with the given name, or nil if no such segment exists. @@ -329,7 +329,7 @@ func (f *File) Segment(name string) *Segment { return s } } - return nil; + return nil } // Section returns the first section with the given name, or nil if no such @@ -340,7 +340,7 @@ func (f *File) Section(name string) *Section { return s } } - return nil; + return nil } // DWARF returns the DWARF debug information for the Mach-O file. @@ -348,21 +348,21 @@ func (f *File) DWARF() (*dwarf.Data, os.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", "str"}; - var dat [len(names)][]byte; + var names = [...]string{"abbrev", "info", "str"} + var dat [len(names)][]byte for i, name := range names { - name = "__debug_" + name; - s := f.Section(name); + name = "__debug_" + name + s := f.Section(name) if s == nil { return nil, os.NewError("missing Mach-O section " + name) } - b, err := s.Data(); + b, err := s.Data() if err != nil && uint64(len(b)) < s.Size { return nil, err } - dat[i] = b; + dat[i] = b } - abbrev, info, str := dat[0], dat[1], dat[2]; - return dwarf.New(abbrev, nil, nil, info, nil, nil, nil, str); + abbrev, info, str := dat[0], dat[1], dat[2] + return dwarf.New(abbrev, nil, nil, info, nil, nil, nil, str) } |