1 // Copyright 2016 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
14 // SectionHeader32 represents real PE COFF section header.
15 type SectionHeader32
struct {
20 PointerToRawData
uint32
21 PointerToRelocations
uint32
22 PointerToLineNumbers
uint32
23 NumberOfRelocations
uint16
24 NumberOfLineNumbers
uint16
25 Characteristics
uint32
28 // fullName finds real name of section sh. Normally name is stored
29 // in sh.Name, but if it is longer then 8 characters, it is stored
30 // in COFF string table st instead.
31 func (sh
*SectionHeader32
) fullName(st StringTable
) (string, error
) {
32 if sh
.Name
[0] != '/' {
33 return cstring(sh
.Name
[:]), nil
35 i
, err
:= strconv
.Atoi(cstring(sh
.Name
[1:]))
39 return st
.String(uint32(i
))
42 // TODO(brainman): copy all IMAGE_REL_* consts from ldpe.go here
44 // Reloc represents a PE COFF relocation.
45 // Each section contains its own relocation list.
48 SymbolTableIndex
uint32
52 func readRelocs(sh
*SectionHeader
, r io
.ReadSeeker
) ([]Reloc
, error
) {
53 if sh
.NumberOfRelocations
<= 0 {
56 _
, err
:= r
.Seek(int64(sh
.PointerToRelocations
), seekStart
)
58 return nil, fmt
.Errorf("fail to seek to %q section relocations: %v", sh
.Name
, err
)
60 relocs
:= make([]Reloc
, sh
.NumberOfRelocations
)
61 err
= binary
.Read(r
, binary
.LittleEndian
, relocs
)
63 return nil, fmt
.Errorf("fail to read section relocations: %v", err
)
68 // SectionHeader is similar to SectionHeader32 with Name
69 // field replaced by Go string.
70 type SectionHeader
struct {
76 PointerToRelocations
uint32
77 PointerToLineNumbers
uint32
78 NumberOfRelocations
uint16
79 NumberOfLineNumbers
uint16
80 Characteristics
uint32
83 // Section provides access to PE COFF section.
88 // Embed ReaderAt for ReadAt method.
89 // Do not embed SectionReader directly
90 // to avoid having Read and Seek.
91 // If a client wants Read and Seek it must use
92 // Open() to avoid fighting over the seek offset
93 // with other clients.
98 // Data reads and returns the contents of the PE section s.
99 func (s
*Section
) Data() ([]byte, error
) {
100 dat
:= make([]byte, s
.sr
.Size())
101 n
, err
:= s
.sr
.ReadAt(dat
, 0)
108 // Open returns a new ReadSeeker reading the PE section s.
109 func (s
*Section
) Open() io
.ReadSeeker
{
110 return io
.NewSectionReader(s
.sr
, 0, 1<<63-1)