
This allows us to update this dependency on our schedule which is important because the module relies on manually updating the known list of Go versions to function correctly. Forking allows us to keep this up to date ourselves and possibly create a new system to prevent having to perform this manual step in the future.
915 lines
26 KiB
Go
915 lines
26 KiB
Go
// This file is part of GoRE.
|
|
//
|
|
// Copyright (C) 2019-2022 GoRE Authors
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
package gore
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"reflect"
|
|
)
|
|
|
|
// Moduledata extracts the file's moduledata.
|
|
func (f *GoFile) Moduledata() (Moduledata, error) {
|
|
// We need the Go version to be defined to find the module data.
|
|
ver, err := f.GetCompilerVersion()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not get the Go version for the moduledata extraction: %w", err)
|
|
}
|
|
f.FileInfo.goversion = ver
|
|
|
|
md, err := parseModuledata(f.FileInfo, f.fh)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error when parsing the moduledata: %w", err)
|
|
}
|
|
|
|
return md, nil
|
|
}
|
|
|
|
// Moduledata holds information about the layout of the executable image in memory.
|
|
type Moduledata interface {
|
|
// Text returns the text secion.
|
|
Text() ModuleDataSection
|
|
// NoPtrData returns the noptrdata section.
|
|
NoPtrData() ModuleDataSection
|
|
// Data returns the data section.
|
|
Data() ModuleDataSection
|
|
// Bss returns the bss section.
|
|
Bss() ModuleDataSection
|
|
// NoPtrBss returns the noptrbss section.
|
|
NoPtrBss() ModuleDataSection
|
|
// Types returns the types section.
|
|
Types() ModuleDataSection
|
|
// PCLNTab returns the pclntab section.
|
|
PCLNTab() ModuleDataSection
|
|
// FuncTab returns the functab section.
|
|
FuncTab() ModuleDataSection
|
|
// ITabLinks returns the itablinks section.
|
|
ITabLinks() ModuleDataSection
|
|
// TypeLink returns the typelink section.
|
|
TypeLink() ([]int32, error)
|
|
// GoFuncValue returns the value of the 'go:func.*' symbol.
|
|
GoFuncValue() uint64
|
|
}
|
|
|
|
type moduledata struct {
|
|
TextAddr, TextLen uint64
|
|
NoPtrDataAddr, NoPtrDataLen uint64
|
|
DataAddr, DataLen uint64
|
|
BssAddr, BssLen uint64
|
|
NoPtrBssAddr, NoPtrBssLen uint64
|
|
|
|
TypesAddr, TypesLen uint64
|
|
TypelinkAddr, TypelinkLen uint64
|
|
ITabLinkAddr, ITabLinkLen uint64
|
|
FuncTabAddr, FuncTabLen uint64
|
|
PCLNTabAddr, PCLNTabLen uint64
|
|
|
|
GoFuncVal uint64
|
|
|
|
fh fileHandler
|
|
}
|
|
|
|
// Text returns the text secion.
|
|
func (m moduledata) Text() ModuleDataSection {
|
|
return ModuleDataSection{
|
|
Address: m.TextAddr,
|
|
Length: m.TextLen,
|
|
fh: m.fh,
|
|
}
|
|
}
|
|
|
|
// NoPtrData returns the noptrdata section.
|
|
func (m moduledata) NoPtrData() ModuleDataSection {
|
|
return ModuleDataSection{
|
|
Address: m.NoPtrDataAddr,
|
|
Length: m.NoPtrDataLen,
|
|
fh: m.fh,
|
|
}
|
|
}
|
|
|
|
// Data returns the data section.
|
|
func (m moduledata) Data() ModuleDataSection {
|
|
return ModuleDataSection{
|
|
Address: m.DataAddr,
|
|
Length: m.DataLen,
|
|
fh: m.fh,
|
|
}
|
|
}
|
|
|
|
// Bss returns the bss section.
|
|
func (m moduledata) Bss() ModuleDataSection {
|
|
return ModuleDataSection{
|
|
Address: m.BssAddr,
|
|
Length: m.BssLen,
|
|
fh: m.fh,
|
|
}
|
|
}
|
|
|
|
// NoPtrBss returns the noptrbss section.
|
|
func (m moduledata) NoPtrBss() ModuleDataSection {
|
|
return ModuleDataSection{
|
|
Address: m.NoPtrBssAddr,
|
|
Length: m.NoPtrBssLen,
|
|
fh: m.fh,
|
|
}
|
|
}
|
|
|
|
// Types returns the types section.
|
|
func (m moduledata) Types() ModuleDataSection {
|
|
return ModuleDataSection{
|
|
Address: m.TypesAddr,
|
|
Length: m.TypesLen,
|
|
fh: m.fh,
|
|
}
|
|
}
|
|
|
|
// PCLNTab returns the pclntab section.
|
|
func (m moduledata) PCLNTab() ModuleDataSection {
|
|
return ModuleDataSection{
|
|
Address: m.PCLNTabAddr,
|
|
Length: m.PCLNTabLen,
|
|
fh: m.fh,
|
|
}
|
|
}
|
|
|
|
// FuncTab returns the functab section.
|
|
func (m moduledata) FuncTab() ModuleDataSection {
|
|
return ModuleDataSection{
|
|
Address: m.FuncTabAddr,
|
|
Length: m.FuncTabLen,
|
|
fh: m.fh,
|
|
}
|
|
}
|
|
|
|
// ITabLinks returns the itablinks section.
|
|
func (m moduledata) ITabLinks() ModuleDataSection {
|
|
return ModuleDataSection{
|
|
Address: m.ITabLinkAddr,
|
|
Length: m.ITabLinkLen,
|
|
fh: m.fh,
|
|
}
|
|
}
|
|
|
|
// TypeLink returns the typelink section.
|
|
func (m moduledata) TypeLink() ([]int32, error) {
|
|
base, data, err := m.fh.getSectionDataFromOffset(m.TypelinkAddr)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get the typelink data section: %w", err)
|
|
}
|
|
|
|
r := bytes.NewReader(data[m.TypelinkAddr-base:])
|
|
a := make([]int32, 0, m.TypelinkLen)
|
|
bo := m.fh.getFileInfo().ByteOrder
|
|
for i := uint64(0); i < m.TypelinkLen; i++ {
|
|
// Type offsets are always int32
|
|
var off int32
|
|
err = binary.Read(r, bo, &off)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to read typelink item %d: %w", i, err)
|
|
}
|
|
a = append(a, off)
|
|
}
|
|
|
|
return a, nil
|
|
}
|
|
|
|
// GoFuncValue returns the value of the "go:func.*" symbol.
|
|
func (m moduledata) GoFuncValue() uint64 {
|
|
return m.GoFuncVal
|
|
}
|
|
|
|
// ModuleDataSection is a section defined in the Moduledata structure.
|
|
type ModuleDataSection struct {
|
|
// Address is the virtual address where the section start.
|
|
Address uint64
|
|
// Length is the byte length for the data in this section.
|
|
Length uint64
|
|
fh fileHandler
|
|
}
|
|
|
|
// Data returns the data in the section.
|
|
func (m ModuleDataSection) Data() ([]byte, error) {
|
|
// If we don't have any data, return an empty slice.
|
|
if m.Length == 0 {
|
|
return []byte{}, nil
|
|
}
|
|
base, data, err := m.fh.getSectionDataFromOffset(m.Address)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("getting module data section failed: %w", err)
|
|
}
|
|
start := m.Address - base
|
|
if uint64(len(data)) < start+m.Length {
|
|
return nil, fmt.Errorf("the length of module data section is to big: address 0x%x, base 0x%x, length 0x%x", m.Address, base, m.Length)
|
|
}
|
|
buf := make([]byte, m.Length)
|
|
copy(buf, data[start:start+m.Length])
|
|
return buf, nil
|
|
}
|
|
|
|
func findModuledata(f fileHandler) ([]byte, error) {
|
|
_, secData, err := f.getSectionData(f.moduledataSection())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
tabAddr, _, err := f.getPCLNTABData()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Search for moduledata
|
|
buf := new(bytes.Buffer)
|
|
err = binary.Write(buf, binary.LittleEndian, &tabAddr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
off := bytes.Index(secData, buf.Bytes()[:intSize32])
|
|
if off == -1 {
|
|
return nil, errors.New("could not find moduledata")
|
|
}
|
|
// TODO: Verify that hit is correct.
|
|
|
|
return secData[off : off+0x300], nil
|
|
}
|
|
|
|
func parseModuledata(fileInfo *FileInfo, f fileHandler) (moduledata, error) {
|
|
data, err := findModuledata(f)
|
|
if err != nil {
|
|
return moduledata{}, err
|
|
}
|
|
|
|
// buf will hold the struct type that represents the data in the file we are processing.
|
|
var buf interface{}
|
|
is32bit := fileInfo.WordSize == intSize32
|
|
|
|
// Determine what kind of struct we need to extract the module data from the file.
|
|
|
|
if GoVersionCompare("go1.20rc1", fileInfo.goversion.Name) <= 0 {
|
|
if is32bit {
|
|
buf = &moduledata2032{}
|
|
} else {
|
|
buf = &moduledata2064{}
|
|
}
|
|
} else if GoVersionCompare("go1.18beta1", fileInfo.goversion.Name) <= 0 {
|
|
if is32bit {
|
|
buf = &moduledata1832{}
|
|
} else {
|
|
buf = &moduledata1864{}
|
|
}
|
|
} else if GoVersionCompare("go1.16beta1", fileInfo.goversion.Name) <= 0 {
|
|
if is32bit {
|
|
buf = &moduledata1632{}
|
|
} else {
|
|
buf = &moduledata1664{}
|
|
}
|
|
} else if GoVersionCompare("go1.8beta1", fileInfo.goversion.Name) <= 0 {
|
|
if is32bit {
|
|
buf = &moduledata832{}
|
|
} else {
|
|
buf = &moduledata864{}
|
|
}
|
|
} else if GoVersionCompare("go1.7beta1", fileInfo.goversion.Name) <= 0 {
|
|
if is32bit {
|
|
buf = &moduledata732{}
|
|
} else {
|
|
buf = &moduledata764{}
|
|
}
|
|
} else {
|
|
if is32bit {
|
|
buf = &moduledata532{}
|
|
} else {
|
|
buf = &moduledata564{}
|
|
}
|
|
}
|
|
|
|
// Read the module struct from the file.
|
|
r := bytes.NewReader(data)
|
|
err = readStruct(r, fileInfo.ByteOrder, buf)
|
|
if err != nil {
|
|
return moduledata{}, fmt.Errorf("error when reading module data from file: %w", err)
|
|
}
|
|
|
|
// Convert the read struct to the type we return to the caller.
|
|
md, err := processModuledata(buf)
|
|
if err != nil {
|
|
return md, fmt.Errorf("error when processing module data: %w", err)
|
|
}
|
|
|
|
// Add the file handler.
|
|
md.fh = f
|
|
|
|
return md, nil
|
|
}
|
|
|
|
func readUIntTo64(r io.Reader, byteOrder binary.ByteOrder, is32bit bool) (uint64, error) {
|
|
if is32bit {
|
|
var addr uint32
|
|
err := binary.Read(r, byteOrder, &addr)
|
|
return uint64(addr), err
|
|
}
|
|
var addr uint64
|
|
err := binary.Read(r, byteOrder, &addr)
|
|
return addr, err
|
|
}
|
|
|
|
// readStruct performs a binary read from the reader to the data object. Data object must
|
|
// be a pointer to the struct.
|
|
func readStruct(r io.Reader, byteOrder binary.ByteOrder, data interface{}) error {
|
|
return binary.Read(r, byteOrder, data)
|
|
}
|
|
|
|
func processModuledata(data interface{}) (moduledata, error) {
|
|
md := moduledata{}
|
|
// This will panic if the data passed in is not a pointer to
|
|
// a struct. But this function should not be called outside
|
|
// of this file, we can ensure this is always the case.
|
|
val := reflect.ValueOf(data).Elem()
|
|
|
|
extractModFieldValue(&md, "TextAddr", val, "Text")
|
|
extractModFieldValue(&md, "TextLen", val, "Etext")
|
|
if md.TextLen > md.TextAddr {
|
|
md.TextLen = md.TextLen - md.TextAddr
|
|
}
|
|
|
|
extractModFieldValue(&md, "NoPtrDataAddr", val, "Noptrdata")
|
|
extractModFieldValue(&md, "NoPtrDataLen", val, "Enoptrdata")
|
|
if md.NoPtrDataLen > md.NoPtrDataAddr {
|
|
md.NoPtrDataLen = md.NoPtrDataLen - md.NoPtrDataAddr
|
|
}
|
|
|
|
extractModFieldValue(&md, "DataAddr", val, "Data")
|
|
extractModFieldValue(&md, "DataLen", val, "Edata")
|
|
if md.DataLen > md.DataAddr {
|
|
md.DataLen = md.DataLen - md.DataAddr
|
|
}
|
|
|
|
extractModFieldValue(&md, "BssAddr", val, "Bss")
|
|
extractModFieldValue(&md, "BssLen", val, "Ebss")
|
|
if md.BssLen > md.BssAddr {
|
|
md.BssLen = md.BssLen - md.BssAddr
|
|
}
|
|
|
|
extractModFieldValue(&md, "NoPtrBssAddr", val, "Noptrbss")
|
|
extractModFieldValue(&md, "NoPtrBssLen", val, "Enoptrbss")
|
|
if md.NoPtrBssLen > md.NoPtrBssAddr {
|
|
md.NoPtrBssLen = md.NoPtrBssLen - md.NoPtrBssAddr
|
|
}
|
|
|
|
extractModFieldValue(&md, "TypelinkAddr", val, "Typelinks")
|
|
extractModFieldValue(&md, "TypelinkLen", val, "Typelinkslen")
|
|
extractModFieldValue(&md, "ITabLinkAddr", val, "Itablinks")
|
|
extractModFieldValue(&md, "ITabLinkLen", val, "Itablinkslen")
|
|
extractModFieldValue(&md, "FuncTabAddr", val, "Ftab")
|
|
extractModFieldValue(&md, "FuncTabLen", val, "Ftablen")
|
|
extractModFieldValue(&md, "PCLNTabAddr", val, "Pclntable")
|
|
extractModFieldValue(&md, "PCLNTabLen", val, "Pclntablelen")
|
|
|
|
extractModFieldValue(&md, "TypesAddr", val, "Types")
|
|
extractModFieldValue(&md, "TypesLen", val, "Etypes")
|
|
if md.TypesLen > md.TypesAddr {
|
|
md.TypesLen = md.TypesLen - md.TypesAddr
|
|
}
|
|
|
|
extractModFieldValue(&md, "GoFuncVal", val, "GoFunc")
|
|
|
|
return md, nil
|
|
}
|
|
|
|
func extractModFieldValue(md *moduledata, dst string, val reflect.Value, src string) {
|
|
field := val.FieldByName(src)
|
|
// Not all versions of the module struct has all the fields. If we don't have the
|
|
// field, we skip it.
|
|
if !field.IsValid() {
|
|
return
|
|
}
|
|
|
|
// Save 32 to 64 uint casting if needed.
|
|
var num uint64
|
|
switch field.Interface().(type) {
|
|
case uint64:
|
|
num = field.Uint()
|
|
case uint32:
|
|
t := field.Interface().(uint32)
|
|
num = uint64(t)
|
|
}
|
|
|
|
// Set the value.
|
|
mdField := reflect.ValueOf(md).Elem().FieldByName(dst)
|
|
mdField.SetUint(num)
|
|
}
|
|
|
|
/*
|
|
Internal module structures from Go's runtime.
|
|
*/
|
|
|
|
// Moduledata structure for Go 1.20 and newer
|
|
|
|
type moduledata2064 struct {
|
|
PcHeader uint64
|
|
Funcnametab, Funcnametablen, Funcnametabcap uint64
|
|
Cutab, Cutablen, Cutabcap uint64
|
|
Filetab, Filetablen, Filetabcap uint64
|
|
Pctab, Pctablen, Pctabcap uint64
|
|
Pclntable, Pclntablelen, Pclntablecap uint64
|
|
Ftab, Ftablen, Ftabcap uint64
|
|
Findfunctab uint64
|
|
Minpc, Maxpc uint64
|
|
|
|
Text, Etext uint64
|
|
Noptrdata, Enoptrdata uint64
|
|
Data, Edata uint64
|
|
Bss, Ebss uint64
|
|
Noptrbss, Enoptrbss uint64
|
|
Covctrs, Ecovctrs uint64
|
|
End, Gcdata, Gcbss uint64
|
|
Types, Etypes uint64
|
|
RData uint64
|
|
GoFunc uint64
|
|
|
|
Textsectmap, Textsectmaplen, Textsectmapcap uint64
|
|
Typelinks, Typelinkslen, Typelinkscap uint64 // offsets from types
|
|
Itablinks, Itablinkslen, Itablinkscap uint64
|
|
|
|
Ptab, Ptablen, Ptabcap uint64
|
|
|
|
Pluginpath, Pluginpathlen uint64
|
|
Pkghashes, Pkghasheslen, Pkghashescap uint64
|
|
|
|
Modulename, Modulenamelen uint64
|
|
Modulehashes, Modulehasheslen, Modulehashescap uint64
|
|
|
|
/* These fields we are not planning to use so skipping the parsing of them.
|
|
|
|
hasmain uint8 // 1 if module contains the main function, 0 otherwise
|
|
|
|
gcdatamask, gcbssmask bitvector
|
|
|
|
typemap map[typeOff]*_type // offset to *_rtype in previous module
|
|
|
|
bad bool // module failed to load and should be ignored
|
|
|
|
next *moduledata
|
|
*/
|
|
}
|
|
|
|
type moduledata2032 struct {
|
|
PcHeader uint32
|
|
Funcnametab, Funcnametablen, Funcnametabcap uint32
|
|
Cutab, Cutablen, Cutabcap uint32
|
|
Filetab, Filetablen, Filetabcap uint32
|
|
Pctab, Pctablen, Pctabcap uint32
|
|
Pclntable, Pclntablelen, Pclntablecap uint32
|
|
Ftab, Ftablen, Ftabcap uint32
|
|
Findfunctab uint32
|
|
Minpc, Maxpc uint32
|
|
|
|
Text, Etext uint32
|
|
Noptrdata, Enoptrdata uint32
|
|
Data, Edata uint32
|
|
Bss, Ebss uint32
|
|
Noptrbss, Enoptrbss uint32
|
|
Covctrs, Ecovctrs uint32
|
|
End, Gcdata, Gcbss uint32
|
|
Types, Etypes uint32
|
|
RData uint32
|
|
GoFunc uint32
|
|
|
|
Textsectmap, Textsectmaplen, Textsectmapcap uint32
|
|
Typelinks, Typelinkslen, Typelinkscap uint32 // offsets from types
|
|
Itablinks, Itablinkslen, Itablinkscap uint32
|
|
|
|
Ptab, Ptablen, Ptabcap uint32
|
|
|
|
Pluginpath, Pluginpathlen uint32
|
|
Pkghashes, Pkghasheslen, Pkghashescap uint32
|
|
|
|
Modulename, Modulenamelen uint32
|
|
Modulehashes, Modulehasheslen, Modulehashescap uint32
|
|
|
|
/* These fields we are not planning to use so skipping the parsing of them.
|
|
|
|
hasmain uint8 // 1 if module contains the main function, 0 otherwise
|
|
|
|
gcdatamask, gcbssmask bitvector
|
|
|
|
typemap map[typeOff]*_type // offset to *_rtype in previous module
|
|
|
|
bad bool // module failed to load and should be ignored
|
|
|
|
next *moduledata
|
|
*/
|
|
}
|
|
|
|
// Moduledata structure for Go 1.18 and Go 1.19
|
|
|
|
type moduledata1864 struct {
|
|
PcHeader uint64
|
|
Funcnametab, Funcnametablen, Funcnametabcap uint64
|
|
Cutab, Cutablen, Cutabcap uint64
|
|
Filetab, Filetablen, Filetabcap uint64
|
|
Pctab, Pctablen, Pctabcap uint64
|
|
Pclntable, Pclntablelen, Pclntablecap uint64
|
|
Ftab, Ftablen, Ftabcap uint64
|
|
Findfunctab uint64
|
|
Minpc, Maxpc uint64
|
|
|
|
Text, Etext uint64
|
|
Noptrdata, Enoptrdata uint64
|
|
Data, Edata uint64
|
|
Bss, Ebss uint64
|
|
Noptrbss, Enoptrbss uint64
|
|
End, Gcdata, Gcbss uint64
|
|
Types, Etypes uint64
|
|
RData uint64
|
|
GoFunc uint64
|
|
|
|
Textsectmap, Textsectmaplen, Textsectmapcap uint64
|
|
Typelinks, Typelinkslen, Typelinkscap uint64 // offsets from types
|
|
Itablinks, Itablinkslen, Itablinkscap uint64
|
|
|
|
Ptab, Ptablen, Ptabcap uint64
|
|
|
|
Pluginpath, Pluginpathlen uint64
|
|
Pkghashes, Pkghasheslen, Pkghashescap uint64
|
|
|
|
Modulename, Modulenamelen uint64
|
|
Modulehashes, Modulehasheslen, Modulehashescap uint64
|
|
|
|
/* These fields we are not planning to use so skipping the parsing of them.
|
|
|
|
hasmain uint8 // 1 if module contains the main function, 0 otherwise
|
|
|
|
gcdatamask, gcbssmask bitvector
|
|
|
|
typemap map[typeOff]*_type // offset to *_rtype in previous module
|
|
|
|
bad bool // module failed to load and should be ignored
|
|
|
|
next *moduledata
|
|
*/
|
|
}
|
|
|
|
type moduledata1832 struct {
|
|
PcHeader uint32
|
|
Funcnametab, Funcnametablen, Funcnametabcap uint32
|
|
Cutab, Cutablen, Cutabcap uint32
|
|
Filetab, Filetablen, Filetabcap uint32
|
|
Pctab, Pctablen, Pctabcap uint32
|
|
Pclntable, Pclntablelen, Pclntablecap uint32
|
|
Ftab, Ftablen, Ftabcap uint32
|
|
Findfunctab uint32
|
|
Minpc, Maxpc uint32
|
|
|
|
Text, Etext uint32
|
|
Noptrdata, Enoptrdata uint32
|
|
Data, Edata uint32
|
|
Bss, Ebss uint32
|
|
Noptrbss, Enoptrbss uint32
|
|
End, Gcdata, Gcbss uint32
|
|
Types, Etypes uint32
|
|
RData uint32
|
|
GoFunc uint32
|
|
|
|
Textsectmap, Textsectmaplen, Textsectmapcap uint32
|
|
Typelinks, Typelinkslen, Typelinkscap uint32 // offsets from types
|
|
Itablinks, Itablinkslen, Itablinkscap uint32
|
|
|
|
Ptab, Ptablen, Ptabcap uint32
|
|
|
|
Pluginpath, Pluginpathlen uint32
|
|
Pkghashes, Pkghasheslen, Pkghashescap uint32
|
|
|
|
Modulename, Modulenamelen uint32
|
|
Modulehashes, Modulehasheslen, Modulehashescap uint32
|
|
|
|
/* These fields we are not planning to use so skipping the parsing of them.
|
|
|
|
hasmain uint8 // 1 if module contains the main function, 0 otherwise
|
|
|
|
gcdatamask, gcbssmask bitvector
|
|
|
|
typemap map[typeOff]*_type // offset to *_rtype in previous module
|
|
|
|
bad bool // module failed to load and should be ignored
|
|
|
|
next *moduledata
|
|
*/
|
|
}
|
|
|
|
// Moduledata structure for Go 1.16 to 1.17
|
|
|
|
type moduledata1664 struct {
|
|
PcHeader uint64
|
|
Funcnametab, Funcnametablen, Funcnametabcap uint64
|
|
Cutab, Cutablen, Cutabcap uint64
|
|
Filetab, Filetablen, Filetabcap uint64
|
|
Pctab, Pctablen, Pctabcap uint64
|
|
Pclntable, Pclntablelen, Pclntablecap uint64
|
|
Ftab, Ftablen, Ftabcap uint64
|
|
Findfunctab uint64
|
|
Minpc, Maxpc uint64
|
|
|
|
Text, Etext uint64
|
|
Noptrdata, Enoptrdata uint64
|
|
Data, Edata uint64
|
|
Bss, Ebss uint64
|
|
Noptrbss, Enoptrbss uint64
|
|
End, Gcdata, Gcbss uint64
|
|
Types, Etypes uint64
|
|
|
|
Textsectmap, Textsectmaplen, Textsectmapcap uint64
|
|
Typelinks, Typelinkslen, Typelinkscap uint64 // offsets from types
|
|
Itablinks, Itablinkslen, Itablinkscap uint64
|
|
|
|
Ptab, Ptablen, Ptabcap uint64
|
|
|
|
Pluginpath, Pluginpathlen uint64
|
|
Pkghashes, Pkghasheslen, Pkghashescap uint64
|
|
|
|
Modulename, Modulenamelen uint64
|
|
Modulehashes, Modulehasheslen, Modulehashescap uint64
|
|
|
|
/* These fields we are not planning to use so skipping the parsing of them.
|
|
|
|
hasmain uint8 // 1 if module contains the main function, 0 otherwise
|
|
|
|
gcdatamask, gcbssmask bitvector
|
|
|
|
typemap map[typeOff]*_type // offset to *_rtype in previous module
|
|
|
|
bad bool // module failed to load and should be ignored
|
|
|
|
next *moduledata
|
|
*/
|
|
}
|
|
|
|
type moduledata1632 struct {
|
|
PcHeader uint32
|
|
Funcnametab, Funcnametablen, Funcnametabcap uint32
|
|
Cutab, Cutablen, Cutabcap uint32
|
|
Filetab, Filetablen, Filetabcap uint32
|
|
Pctab, Pctablen, Pctabcap uint32
|
|
Pclntable, Pclntablelen, Pclntablecap uint32
|
|
Ftab, Ftablen, Ftabcap uint32
|
|
Findfunctab uint32
|
|
Minpc, Maxpc uint32
|
|
|
|
Text, Etext uint32
|
|
Noptrdata, Enoptrdata uint32
|
|
Data, Edata uint32
|
|
Bss, Ebss uint32
|
|
Noptrbss, Enoptrbss uint32
|
|
End, Gcdata, Gcbss uint32
|
|
Types, Etypes uint32
|
|
|
|
Textsectmap, Textsectmaplen, Textsectmapcap uint32
|
|
Typelinks, Typelinkslen, Typelinkscap uint32 // offsets from types
|
|
Itablinks, Itablinkslen, Itablinkscap uint32
|
|
|
|
Ptab, Ptablen, Ptabcap uint32
|
|
|
|
Pluginpath, Pluginpathlen uint32
|
|
Pkghashes, Pkghasheslen, Pkghashescap uint32
|
|
|
|
Modulename, Modulenamelen uint32
|
|
Modulehashes, Modulehasheslen, Modulehashescap uint32
|
|
|
|
/* These fields we are not planning to use so skipping the parsing of them.
|
|
|
|
hasmain uint8 // 1 if module contains the main function, 0 otherwise
|
|
|
|
gcdatamask, gcbssmask bitvector
|
|
|
|
typemap map[typeOff]*_type // offset to *_rtype in previous module
|
|
|
|
bad bool // module failed to load and should be ignored
|
|
|
|
next *moduledata
|
|
*/
|
|
}
|
|
|
|
// Moduledata structure for Go 1.8 to 1.15
|
|
|
|
type moduledata864 struct {
|
|
Pclntable, Pclntablelen, Pclntablecap uint64
|
|
Ftab, Ftablen, Ftabcap uint64
|
|
Filetab, Filetablen, Filetabcap uint64
|
|
Findfunctab uint64
|
|
Minpc, Maxpc uint64
|
|
|
|
Text, Etext uint64
|
|
Noptrdata, Enoptrdata uint64
|
|
Data, Edata uint64
|
|
Bss, Ebss uint64
|
|
Noptrbss, Enoptrbss uint64
|
|
End, Gcdata, Gcbss uint64
|
|
Types, Etypes uint64
|
|
|
|
Textsectmap, Textsectmaplen, Textsectmapcap uint64
|
|
Typelinks, Typelinkslen, Typelinkscap uint64 // offsets from types
|
|
Itablinks, Itablinkslen, Itablinkscap uint64
|
|
|
|
Ptab, Ptablen, Ptabcap uint64
|
|
|
|
Pluginpath, Pluginpathlen uint64
|
|
Pkghashes, Pkghasheslen, Pkghashescap uint64
|
|
|
|
Modulename, Modulenamelen uint64
|
|
Modulehashes, Modulehasheslen, Modulehashescap uint64
|
|
|
|
/* These fields we are not planning to use so skipping the parsing of them.
|
|
|
|
hasmain uint8 // 1 if module contains the main function, 0 otherwise
|
|
|
|
gcdatamask, gcbssmask bitvector
|
|
|
|
typemap map[typeOff]*_type // offset to *_rtype in previous module
|
|
|
|
bad bool // module failed to load and should be ignored
|
|
|
|
next *moduledata
|
|
*/
|
|
}
|
|
|
|
type moduledata832 struct {
|
|
Pclntable, Pclntablelen, Pclntablecap uint32
|
|
Ftab, Ftablen, Ftabcap uint32
|
|
Filetab, Filetablen, Filetabcap uint32
|
|
Findfunctab uint32
|
|
Minpc, Maxpc uint32
|
|
|
|
Text, Etext uint32
|
|
Noptrdata, Enoptrdata uint32
|
|
Data, Edata uint32
|
|
Bss, Ebss uint32
|
|
Noptrbss, Enoptrbss uint32
|
|
End, Gcdata, Gcbss uint32
|
|
Types, Etypes uint32
|
|
|
|
Textsectmap, Textsectmaplen, Textsectmapcap uint32
|
|
Typelinks, Typelinkslen, Typelinkscap uint32 // offsets from types
|
|
Itablinks, Itablinkslen, Itablinkscap uint32
|
|
|
|
Ptab, Ptablen, Ptabcap uint32
|
|
|
|
Pluginpath, Pluginpathlen uint32
|
|
Pkghashes, Pkghasheslen, Pkghashescap uint32
|
|
|
|
Modulename, Modulenamelen uint32
|
|
Modulehashes, Modulehasheslen, Modulehashescap uint32
|
|
|
|
/* These fields we are not planning to use so skipping the parsing of them.
|
|
|
|
hasmain uint8 // 1 if module contains the main function, 0 otherwise
|
|
|
|
gcdatamask, gcbssmask bitvector
|
|
|
|
typemap map[typeOff]*_type // offset to *_rtype in previous module
|
|
|
|
bad bool // module failed to load and should be ignored
|
|
|
|
next *moduledata
|
|
*/
|
|
}
|
|
|
|
// Moduledata structure for Go 1.7
|
|
|
|
type moduledata764 struct {
|
|
Pclntable, Pclntablelen, Pclntablecap uint64
|
|
Ftab, Ftablen, Ftabcap uint64
|
|
Filetab, Filetablen, Filetabcap uint64
|
|
Findfunctab uint64
|
|
Minpc, Maxpc uint64
|
|
|
|
Text, Etext uint64
|
|
Noptrdata, Enoptrdata uint64
|
|
Data, Edata uint64
|
|
Bss, Ebss uint64
|
|
Noptrbss, Enoptrbss uint64
|
|
End, Gcdata, Gcbss uint64
|
|
Types, Etypes uint64
|
|
|
|
Typelinks, Typelinkslen, Typelinkscap uint64 // offsets from types
|
|
Itablinks, Itablinkslen, Itablinkscap uint64
|
|
|
|
Modulename, Modulenamelen uint64
|
|
Modulehashes, Modulehasheslen, Modulehashescap uint64
|
|
|
|
/* These fields we are not planning to use so skipping the parsing of them.
|
|
|
|
gcdatamask, gcbssmask bitvector
|
|
|
|
typemap map[typeOff]*_type // offset to *_rtype in previous module
|
|
|
|
next *moduledata
|
|
*/
|
|
}
|
|
|
|
type moduledata732 struct {
|
|
Pclntable, Pclntablelen, Pclntablecap uint32
|
|
Ftab, Ftablen, Ftabcap uint32
|
|
Filetab, Filetablen, Filetabcap uint32
|
|
Findfunctab uint32
|
|
Minpc, Maxpc uint32
|
|
|
|
Text, Etext uint32
|
|
Noptrdata, Enoptrdata uint32
|
|
Data, Edata uint32
|
|
Bss, Ebss uint32
|
|
Noptrbss, Enoptrbss uint32
|
|
End, Gcdata, Gcbss uint32
|
|
Types, Etypes uint32
|
|
|
|
Typelinks, Typelinkslen, Typelinkscap uint32 // offsets from types
|
|
Itablinks, Itablinkslen, Itablinkscap uint32
|
|
|
|
Modulename, Modulenamelen uint32
|
|
Modulehashes, Modulehasheslen, Modulehashescap uint32
|
|
|
|
/* These fields we are not planning to use so skipping the parsing of them.
|
|
|
|
gcdatamask, gcbssmask bitvector
|
|
|
|
typemap map[typeOff]*_type // offset to *_rtype in previous module
|
|
|
|
next *moduledata
|
|
*/
|
|
}
|
|
|
|
// Moduledata structure for Go 1.5 to 1.6
|
|
|
|
type moduledata564 struct {
|
|
Pclntable, Pclntablelen, Pclntablecap uint64
|
|
Ftab, Ftablen, Ftabcap uint64
|
|
Filetab, Filetablen, Filetabcap uint64
|
|
Findfunctab uint64
|
|
Minpc, Maxpc uint64
|
|
|
|
Text, Etext uint64
|
|
Noptrdata, Enoptrdata uint64
|
|
Data, Edata uint64
|
|
Bss, Ebss uint64
|
|
Noptrbss, Enoptrbss uint64
|
|
End, Gcdata, Gcbss uint64
|
|
|
|
Typelinks, Typelinkslen, Typelinkscap uint64
|
|
|
|
Modulename, Modulenamelen uint64
|
|
Modulehashes, Modulehasheslen, Modulehashescap uint64
|
|
|
|
/* These fields we are not planning to use so skipping the parsing of them.
|
|
|
|
gcdatamask, gcbssmask bitvector
|
|
|
|
typemap map[typeOff]*_type // offset to *_rtype in previous module
|
|
|
|
next *moduledata
|
|
*/
|
|
}
|
|
|
|
type moduledata532 struct {
|
|
Pclntable, Pclntablelen, Pclntablecap uint32
|
|
Ftab, Ftablen, Ftabcap uint32
|
|
Filetab, Filetablen, Filetabcap uint32
|
|
Findfunctab uint32
|
|
Minpc, Maxpc uint32
|
|
|
|
Text, Etext uint32
|
|
Noptrdata, Enoptrdata uint32
|
|
Data, Edata uint32
|
|
Bss, Ebss uint32
|
|
Noptrbss, Enoptrbss uint32
|
|
End, Gcdata, Gcbss uint32
|
|
|
|
Typelinks, Typelinkslen, Typelinkscap uint32
|
|
|
|
Modulename, Modulenamelen uint32
|
|
Modulehashes, Modulehasheslen, Modulehashescap uint32
|
|
|
|
/* These fields we are not planning to use so skipping the parsing of them.
|
|
|
|
gcdatamask, gcbssmask bitvector
|
|
|
|
typemap map[typeOff]*_type // offset to *_rtype in previous module
|
|
|
|
next *moduledata
|
|
*/
|
|
}
|