mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-07-26 06:38:42 +00:00
UEFI Target groundwork: runtime: extract Windows PE globals scan helper (#5361)
* runtime: extract Windows PE globals scan helper * Update src/runtime/os_windows_pe.go * run goimports
This commit is contained in:
@@ -7,44 +7,6 @@ const GOOS = "windows"
|
||||
//export GetModuleHandleExA
|
||||
func _GetModuleHandleExA(dwFlags uint32, lpModuleName unsafe.Pointer, phModule **exeHeader) bool
|
||||
|
||||
// MS-DOS stub with PE header offset:
|
||||
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#ms-dos-stub-image-only
|
||||
type exeHeader struct {
|
||||
signature uint16
|
||||
_ [58]byte // skip DOS header
|
||||
peHeader uint32 // at offset 0x3C
|
||||
}
|
||||
|
||||
// COFF file header:
|
||||
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#file-headers
|
||||
type peHeader struct {
|
||||
magic uint32
|
||||
machine uint16
|
||||
numberOfSections uint16
|
||||
timeDateStamp uint32
|
||||
pointerToSymbolTable uint32
|
||||
numberOfSymbols uint32
|
||||
sizeOfOptionalHeader uint16
|
||||
characteristics uint16
|
||||
}
|
||||
|
||||
// COFF section header:
|
||||
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#section-table-section-headers
|
||||
type peSection struct {
|
||||
name [8]byte
|
||||
virtualSize uint32
|
||||
virtualAddress uint32
|
||||
sizeOfRawData uint32
|
||||
pointerToRawData uint32
|
||||
pointerToRelocations uint32
|
||||
pointerToLinenumbers uint32
|
||||
numberOfRelocations uint16
|
||||
numberOfLinenumbers uint16
|
||||
characteristics uint32
|
||||
}
|
||||
|
||||
var module *exeHeader
|
||||
|
||||
// Mark global variables.
|
||||
// Unfortunately, the linker doesn't provide symbols for the start and end of
|
||||
// the data/bss sections. Therefore these addresses need to be determined at
|
||||
@@ -57,9 +19,6 @@ func findGlobals(found func(start, end uintptr)) {
|
||||
const (
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulehandleexa
|
||||
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT = 0x00000002
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format
|
||||
IMAGE_SCN_MEM_WRITE = 0x80000000
|
||||
)
|
||||
|
||||
if module == nil {
|
||||
@@ -72,23 +31,7 @@ func findGlobals(found func(start, end uintptr)) {
|
||||
}
|
||||
}
|
||||
|
||||
// Find the PE header at offset 0x3C.
|
||||
pe := (*peHeader)(unsafe.Add(unsafe.Pointer(module), module.peHeader))
|
||||
if gcAsserts && pe.magic != 0x00004550 { // 0x4550 is "PE"
|
||||
runtimePanic("cannot find PE header")
|
||||
}
|
||||
|
||||
// Iterate through sections.
|
||||
section := (*peSection)(unsafe.Pointer(uintptr(unsafe.Pointer(pe)) + uintptr(pe.sizeOfOptionalHeader) + unsafe.Sizeof(peHeader{})))
|
||||
for i := 0; i < int(pe.numberOfSections); i++ {
|
||||
if section.characteristics&IMAGE_SCN_MEM_WRITE != 0 {
|
||||
// Found a writable section. Scan the entire section for roots.
|
||||
start := uintptr(unsafe.Pointer(module)) + uintptr(section.virtualAddress)
|
||||
end := uintptr(unsafe.Pointer(module)) + uintptr(section.virtualAddress) + uintptr(section.virtualSize)
|
||||
found(start, end)
|
||||
}
|
||||
section = (*peSection)(unsafe.Add(unsafe.Pointer(section), unsafe.Sizeof(peSection{})))
|
||||
}
|
||||
findGlobalsForPE(found)
|
||||
}
|
||||
|
||||
type systeminfo struct {
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
//go:build windows
|
||||
|
||||
package runtime
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// MS-DOS stub with PE header offset:
|
||||
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#ms-dos-stub-image-only
|
||||
type exeHeader struct {
|
||||
signature uint16
|
||||
_ [58]byte // skip DOS header
|
||||
peHeader uint32 // at offset 0x3C
|
||||
}
|
||||
|
||||
// COFF file header:
|
||||
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#file-headers
|
||||
type peHeader struct {
|
||||
magic uint32
|
||||
machine uint16
|
||||
numberOfSections uint16
|
||||
timeDateStamp uint32
|
||||
pointerToSymbolTable uint32
|
||||
numberOfSymbols uint32
|
||||
sizeOfOptionalHeader uint16
|
||||
characteristics uint16
|
||||
}
|
||||
|
||||
// COFF section header:
|
||||
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#section-table-section-headers
|
||||
type peSection struct {
|
||||
name [8]byte
|
||||
virtualSize uint32
|
||||
virtualAddress uint32
|
||||
sizeOfRawData uint32
|
||||
pointerToRawData uint32
|
||||
pointerToRelocations uint32
|
||||
pointerToLinenumbers uint32
|
||||
numberOfRelocations uint16
|
||||
numberOfLinenumbers uint16
|
||||
characteristics uint32
|
||||
}
|
||||
|
||||
var module *exeHeader
|
||||
|
||||
func findGlobalsForPE(found func(start, end uintptr)) {
|
||||
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format
|
||||
const imageSCNMemWrite = 0x80000000
|
||||
|
||||
pe := (*peHeader)(unsafe.Add(unsafe.Pointer(module), module.peHeader))
|
||||
if gcAsserts && pe.magic != 0x00004550 { // 0x4550 is "PE"
|
||||
runtimePanic("cannot find PE header")
|
||||
}
|
||||
|
||||
section := (*peSection)(unsafe.Pointer(uintptr(unsafe.Pointer(pe)) + uintptr(pe.sizeOfOptionalHeader) + unsafe.Sizeof(peHeader{})))
|
||||
for i := 0; i < int(pe.numberOfSections); i++ {
|
||||
if section.characteristics&imageSCNMemWrite != 0 {
|
||||
start := uintptr(unsafe.Pointer(module)) + uintptr(section.virtualAddress)
|
||||
end := uintptr(unsafe.Pointer(module)) + uintptr(section.virtualAddress) + uintptr(section.virtualSize)
|
||||
found(start, end)
|
||||
}
|
||||
section = (*peSection)(unsafe.Add(unsafe.Pointer(section), unsafe.Sizeof(peSection{})))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user