Source file src/debug/pe/section.go

     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  	"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  )
   126  

View as plain text