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  )