...

Source file src/debug/pe/section.go

Documentation: debug/pe

		 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  	"io"
		11  	"strconv"
		12  )
		13  
		14  // SectionHeader32 represents real PE COFF section header.
		15  type SectionHeader32 struct {
		16  	Name								 [8]uint8
		17  	VirtualSize					uint32
		18  	VirtualAddress			 uint32
		19  	SizeOfRawData				uint32
		20  	PointerToRawData		 uint32
		21  	PointerToRelocations uint32
		22  	PointerToLineNumbers uint32
		23  	NumberOfRelocations	uint16
		24  	NumberOfLineNumbers	uint16
		25  	Characteristics			uint32
		26  }
		27  
		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
		34  	}
		35  	i, err := strconv.Atoi(cstring(sh.Name[1:]))
		36  	if err != nil {
		37  		return "", err
		38  	}
		39  	return st.String(uint32(i))
		40  }
		41  
		42  // TODO(brainman): copy all IMAGE_REL_* consts from ldpe.go here
		43  
		44  // Reloc represents a PE COFF relocation.
		45  // Each section contains its own relocation list.
		46  type Reloc struct {
		47  	VirtualAddress	 uint32
		48  	SymbolTableIndex uint32
		49  	Type						 uint16
		50  }
		51  
		52  func readRelocs(sh *SectionHeader, r io.ReadSeeker) ([]Reloc, error) {
		53  	if sh.NumberOfRelocations <= 0 {
		54  		return nil, nil
		55  	}
		56  	_, err := r.Seek(int64(sh.PointerToRelocations), seekStart)
		57  	if err != nil {
		58  		return nil, fmt.Errorf("fail to seek to %q section relocations: %v", sh.Name, err)
		59  	}
		60  	relocs := make([]Reloc, sh.NumberOfRelocations)
		61  	err = binary.Read(r, binary.LittleEndian, relocs)
		62  	if err != nil {
		63  		return nil, fmt.Errorf("fail to read section relocations: %v", err)
		64  	}
		65  	return relocs, nil
		66  }
		67  
		68  // SectionHeader is similar to SectionHeader32 with Name
		69  // field replaced by Go string.
		70  type SectionHeader struct {
		71  	Name								 string
		72  	VirtualSize					uint32
		73  	VirtualAddress			 uint32
		74  	Size								 uint32
		75  	Offset							 uint32
		76  	PointerToRelocations uint32
		77  	PointerToLineNumbers uint32
		78  	NumberOfRelocations	uint16
		79  	NumberOfLineNumbers	uint16
		80  	Characteristics			uint32
		81  }
		82  
		83  // Section provides access to PE COFF section.
		84  type Section struct {
		85  	SectionHeader
		86  	Relocs []Reloc
		87  
		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.
		94  	io.ReaderAt
		95  	sr *io.SectionReader
		96  }
		97  
		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)
	 102  	if n == len(dat) {
	 103  		err = nil
	 104  	}
	 105  	return dat[0:n], err
	 106  }
	 107  
	 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)
	 111  }
	 112  

View as plain text