type moduledata struct {
pcHeader *pcHeader
funcnametab []byte
cutab []uint32
filetab []byte
pctab []byte
pclntable []byte
ftab []functab
findfunctab uintptr
minpc, maxpc uintptr
text, etext uintptr
noptrdata, enoptrdata uintptr
data, edata uintptr
bss, ebss uintptr
noptrbss, enoptrbss uintptr
end, gcdata, gcbss uintptr
types, etypes uintptr
textsectmap []textsect
typelinks []int32 // offsets from types
itablinks []*itab
ptab []ptabEntry
pluginpath string
pkghashes []modulehash
modulename string
modulehashes []modulehash
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
}
go116magic
magic uint32 // 0xFFFFFFFA
type pcHeader struct {
magic uint32 // 0xFFFFFFFA
pad1, pad2 uint8 // 0,0
minLC uint8 // min instruction size
ptrSize uint8 // size of a ptr in bytes
nfunc int // number of functions in the module
nfiles uint // number of entries in the file tab.
funcnameOffset uintptr // offset to the funcnametab variable from pcHeader
cuOffset uintptr // offset to the cutab variable from pcHeader
filetabOffset uintptr // offset to the filetab variable from pcHeader
pctabOffset uintptr // offset to the pctab varible from pcHeader
pclnOffset uintptr // offset to the pclntab variable from pcHeader
}
Creates two new symbols: runtime.cutab, and runtime.filetab, and strips the filenames out of runtime.pclntab_old.
https://github.com/golang/go/commit/9ae8f71c9431d287893443fa2b7fbdb72a9b56a2
// Check header: 4-byte magic, two zeros, pc quantum, pointer size.
if len(t.Data) < 16 || t.Data[4] != 0 || t.Data[5] != 0 ||
(t.Data[6] != 1 && t.Data[6] != 2 && t.Data[6] != 4) || // pc quantum
(t.Data[7] != 4 && t.Data[7] != 8) { // pointer size
return
}
var possibleVersion version
leMagic := binary.LittleEndian.Uint32(t.Data)
beMagic := binary.BigEndian.Uint32(t.Data)
switch {
case leMagic == go12magic:
t.binary, possibleVersion = binary.LittleEndian, ver12
case beMagic == go12magic:
t.binary, possibleVersion = binary.BigEndian, ver12
case leMagic == go116magic:
t.binary, possibleVersion = binary.LittleEndian, ver116
case beMagic == go116magic:
t.binary, possibleVersion = binary.BigEndian, ver116
default:
return
}
// quantum and ptrSize are the same between 1.2 and 1.16
t.quantum = uint32(t.Data[6])
t.ptrsize = uint32(t.Data[7])
switch possibleVersion {
case ver116:
t.nfunctab = uint32(t.uintptr(t.Data[8:]))
t.nfiletab = uint32(t.uintptr(t.Data[8+t.ptrsize:]))
offset := t.uintptr(t.Data[8+2*t.ptrsize:])
t.funcnametab = t.Data[offset:]
offset = t.uintptr(t.Data[8+3*t.ptrsize:])
t.cutab = t.Data[offset:]
offset = t.uintptr(t.Data[8+4*t.ptrsize:])
t.filetab = t.Data[offset:]
offset = t.uintptr(t.Data[8+5*t.ptrsize:])
t.pctab = t.Data[offset:]
offset = t.uintptr(t.Data[8+6*t.ptrsize:])
t.funcdata = t.Data[offset:]
t.functab = t.Data[offset:]
functabsize := t.nfunctab*2*t.ptrsize + t.ptrsize
t.functab = t.functab[:functabsize]
case ver12:
t.nfunctab = uint32(t.uintptr(t.Data[8:]))
t.funcdata = t.Data
t.funcnametab = t.Data
t.functab = t.Data[8+t.ptrsize:]
t.pctab = t.Data
functabsize := t.nfunctab*2*t.ptrsize + t.ptrsize
fileoff := t.binary.Uint32(t.functab[functabsize:])
t.functab = t.functab[:functabsize]
t.filetab = t.Data[fileoff:]
t.nfiletab = t.binary.Uint32(t.filetab)
t.filetab = t.filetab[:t.nfiletab*4]
default:
panic("unreachable")
}
t.version = possibleVersion
https://github.com/golang/go/blob/master/src/debug/gosym/pclntab.go