diff options
author | Michael Stapelberg <stapelberg@debian.org> | 2014-06-19 09:22:53 +0200 |
---|---|---|
committer | Michael Stapelberg <stapelberg@debian.org> | 2014-06-19 09:22:53 +0200 |
commit | 8a39ee361feb9bf46d728ff1ba4f07ca1d9610b1 (patch) | |
tree | 4449f2036cccf162e8417cc5841a35815b3e7ac5 /src/pkg/debug/pe/file.go | |
parent | c8bf49ef8a92e2337b69c14b9b88396efe498600 (diff) | |
download | golang-8a39ee361feb9bf46d728ff1ba4f07ca1d9610b1.tar.gz |
Imported Upstream version 1.3upstream/1.3
Diffstat (limited to 'src/pkg/debug/pe/file.go')
-rw-r--r-- | src/pkg/debug/pe/file.go | 56 |
1 files changed, 42 insertions, 14 deletions
diff --git a/src/pkg/debug/pe/file.go b/src/pkg/debug/pe/file.go index f521566ef..ce6f1408f 100644 --- a/src/pkg/debug/pe/file.go +++ b/src/pkg/debug/pe/file.go @@ -13,13 +13,15 @@ import ( "io" "os" "strconv" + "unsafe" ) // A File represents an open PE file. type File struct { FileHeader - Sections []*Section - Symbols []*Symbol + OptionalHeader interface{} // of type *OptionalHeader32 or *OptionalHeader64 + Sections []*Section + Symbols []*Symbol closer io.Closer } @@ -72,6 +74,9 @@ type ImportDirectory struct { func (s *Section) Data() ([]byte, error) { dat := make([]byte, s.sr.Size()) n, err := s.sr.ReadAt(dat, 0) + if n == len(dat) { + err = nil + } return dat[0:n], err } @@ -193,10 +198,33 @@ func NewFile(r io.ReaderAt) (*File, error) { } } - // Process sections. + // Read optional header. sr.Seek(base, os.SEEK_SET) - binary.Read(sr, binary.LittleEndian, &f.FileHeader) - sr.Seek(int64(f.FileHeader.SizeOfOptionalHeader), os.SEEK_CUR) //Skip OptionalHeader + if err := binary.Read(sr, binary.LittleEndian, &f.FileHeader); err != nil { + return nil, err + } + var oh32 OptionalHeader32 + var oh64 OptionalHeader64 + switch uintptr(f.FileHeader.SizeOfOptionalHeader) { + case unsafe.Sizeof(oh32): + if err := binary.Read(sr, binary.LittleEndian, &oh32); err != nil { + return nil, err + } + if oh32.Magic != 0x10b { // PE32 + return nil, fmt.Errorf("pe32 optional header has unexpected Magic of 0x%x", oh32.Magic) + } + f.OptionalHeader = &oh32 + case unsafe.Sizeof(oh64): + if err := binary.Read(sr, binary.LittleEndian, &oh64); err != nil { + return nil, err + } + if oh64.Magic != 0x20b { // PE32+ + return nil, fmt.Errorf("pe32+ optional header has unexpected Magic of 0x%x", oh64.Magic) + } + f.OptionalHeader = &oh64 + } + + // Process sections. f.Sections = make([]*Section, f.FileHeader.NumberOfSections) for i := 0; i < int(f.FileHeader.NumberOfSections); i++ { sh := new(SectionHeader32) @@ -213,15 +241,15 @@ func NewFile(r io.ReaderAt) (*File, error) { s := new(Section) s.SectionHeader = SectionHeader{ Name: name, - VirtualSize: uint32(sh.VirtualSize), - VirtualAddress: uint32(sh.VirtualAddress), - Size: uint32(sh.SizeOfRawData), - Offset: uint32(sh.PointerToRawData), - PointerToRelocations: uint32(sh.PointerToRelocations), - PointerToLineNumbers: uint32(sh.PointerToLineNumbers), - NumberOfRelocations: uint16(sh.NumberOfRelocations), - NumberOfLineNumbers: uint16(sh.NumberOfLineNumbers), - Characteristics: uint32(sh.Characteristics), + VirtualSize: sh.VirtualSize, + VirtualAddress: sh.VirtualAddress, + Size: sh.SizeOfRawData, + Offset: sh.PointerToRawData, + PointerToRelocations: sh.PointerToRelocations, + PointerToLineNumbers: sh.PointerToLineNumbers, + NumberOfRelocations: sh.NumberOfRelocations, + NumberOfLineNumbers: sh.NumberOfLineNumbers, + Characteristics: sh.Characteristics, } s.sr = io.NewSectionReader(r, int64(s.SectionHeader.Offset), int64(s.SectionHeader.Size)) s.ReaderAt = s.sr |