github.com/bir3/gocompiler@v0.9.2202/src/debug/pe/section.go (about) 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. 4 5 package pe 6 7 import ( 8 "encoding/binary" 9 "fmt" 10 "github.com/bir3/gocompiler/src/internal/saferio" 11 "io" 12 "strconv" 13 ) 14 15 // SectionHeader32 represents real PE COFF section header. 16 type SectionHeader32 struct { 17 Name [8]uint8 18 VirtualSize uint32 19 VirtualAddress uint32 20 SizeOfRawData uint32 21 PointerToRawData uint32 22 PointerToRelocations uint32 23 PointerToLineNumbers uint32 24 NumberOfRelocations uint16 25 NumberOfLineNumbers uint16 26 Characteristics uint32 27 } 28 29 // fullName finds real name of section sh. Normally name is stored 30 // in sh.Name, but if it is longer then 8 characters, it is stored 31 // in COFF string table st instead. 32 func (sh *SectionHeader32) fullName(st StringTable) (string, error) { 33 if sh.Name[0] != '/' { 34 return cstring(sh.Name[:]), nil 35 } 36 i, err := strconv.Atoi(cstring(sh.Name[1:])) 37 if err != nil { 38 return "", err 39 } 40 return st.String(uint32(i)) 41 } 42 43 // TODO(brainman): copy all IMAGE_REL_* consts from ldpe.go here 44 45 // Reloc represents a PE COFF relocation. 46 // Each section contains its own relocation list. 47 type Reloc struct { 48 VirtualAddress uint32 49 SymbolTableIndex uint32 50 Type uint16 51 } 52 53 func readRelocs(sh *SectionHeader, r io.ReadSeeker) ([]Reloc, error) { 54 if sh.NumberOfRelocations <= 0 { 55 return nil, nil 56 } 57 _, err := r.Seek(int64(sh.PointerToRelocations), io.SeekStart) 58 if err != nil { 59 return nil, fmt.Errorf("fail to seek to %q section relocations: %v", sh.Name, err) 60 } 61 relocs := make([]Reloc, sh.NumberOfRelocations) 62 err = binary.Read(r, binary.LittleEndian, relocs) 63 if err != nil { 64 return nil, fmt.Errorf("fail to read section relocations: %v", err) 65 } 66 return relocs, nil 67 } 68 69 // SectionHeader is similar to [SectionHeader32] with Name 70 // field replaced by Go string. 71 type SectionHeader struct { 72 Name string 73 VirtualSize uint32 74 VirtualAddress uint32 75 Size uint32 76 Offset uint32 77 PointerToRelocations uint32 78 PointerToLineNumbers uint32 79 NumberOfRelocations uint16 80 NumberOfLineNumbers uint16 81 Characteristics uint32 82 } 83 84 // Section provides access to PE COFF section. 85 type Section struct { 86 SectionHeader 87 Relocs []Reloc 88 89 // Embed ReaderAt for ReadAt method. 90 // Do not embed SectionReader directly 91 // to avoid having Read and Seek. 92 // If a client wants Read and Seek it must use 93 // Open() to avoid fighting over the seek offset 94 // with other clients. 95 io.ReaderAt 96 sr *io.SectionReader 97 } 98 99 // Data reads and returns the contents of the PE section s. 100 // 101 // If s.Offset is 0, the section has no contents, 102 // and Data will always return a non-nil error. 103 func (s *Section) Data() ([]byte, error) { 104 return saferio.ReadDataAt(s.sr, uint64(s.Size), 0) 105 } 106 107 // Open returns a new ReadSeeker reading the PE section s. 108 // 109 // If s.Offset is 0, the section has no contents, and all calls 110 // to the returned reader will return a non-nil error. 111 func (s *Section) Open() io.ReadSeeker { 112 return io.NewSectionReader(s.sr, 0, 1<<63-1) 113 } 114 115 // Section characteristics flags. 116 const ( 117 IMAGE_SCN_CNT_CODE = 0x00000020 118 IMAGE_SCN_CNT_INITIALIZED_DATA = 0x00000040 119 IMAGE_SCN_CNT_UNINITIALIZED_DATA = 0x00000080 120 IMAGE_SCN_LNK_COMDAT = 0x00001000 121 IMAGE_SCN_MEM_DISCARDABLE = 0x02000000 122 IMAGE_SCN_MEM_EXECUTE = 0x20000000 123 IMAGE_SCN_MEM_READ = 0x40000000 124 IMAGE_SCN_MEM_WRITE = 0x80000000 125 )