Skip to content

Commit a91f1ef

Browse files
committed
refactor: merge findGlobals
1 parent 82f42f1 commit a91f1ef

File tree

3 files changed

+77
-120
lines changed

3 files changed

+77
-120
lines changed

src/runtime/os_uefi.go

Lines changed: 1 addition & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -11,44 +11,6 @@ const baremetal = true
1111

1212
const GOOS = "uefi"
1313

14-
// MS-DOS stub with PE header offset:
15-
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#ms-dos-stub-image-only
16-
type exeHeader struct {
17-
signature uint16
18-
_ [58]byte // skip DOS header
19-
peHeader uint32 // at offset 0x3C
20-
}
21-
22-
// COFF file header:
23-
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#file-headers
24-
type peHeader struct {
25-
magic uint32
26-
machine uint16
27-
numberOfSections uint16
28-
timeDateStamp uint32
29-
pointerToSymbolTable uint32
30-
numberOfSymbols uint32
31-
sizeOfOptionalHeader uint16
32-
characteristics uint16
33-
}
34-
35-
// COFF section header:
36-
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#section-table-section-headers
37-
type peSection struct {
38-
name [8]byte
39-
virtualSize uint32
40-
virtualAddress uint32
41-
sizeOfRawData uint32
42-
pointerToRawData uint32
43-
pointerToRelocations uint32
44-
pointerToLinenumbers uint32
45-
numberOfRelocations uint16
46-
numberOfLinenumbers uint16
47-
characteristics uint32
48-
}
49-
50-
var module *exeHeader
51-
5214
// Mark global variables.
5315
// Unfortunately, the linker doesn't provide symbols for the start and end of
5416
// the data/bss sections. Therefore these addresses need to be determined at
@@ -57,15 +19,6 @@ var module *exeHeader
5719
// Most of this function is based on the documentation in
5820
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format.
5921
func findGlobals(found func(start, end uintptr)) {
60-
// Constants used in this function.
61-
const (
62-
// https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulehandleexa
63-
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT = 0x00000002
64-
65-
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format
66-
IMAGE_SCN_MEM_WRITE = 0x80000000
67-
)
68-
6922
if module == nil {
7023
var loadedImage *uefi.EFI_LOADED_IMAGE_PROTOCOL
7124

@@ -78,22 +31,5 @@ func findGlobals(found func(start, end uintptr)) {
7831
module = (*exeHeader)(unsafe.Pointer(loadedImage.ImageBase))
7932
}
8033

81-
// Find the PE header at offset 0x3C.
82-
pe := (*peHeader)(unsafe.Add(unsafe.Pointer(module), module.peHeader))
83-
if pe.magic != 0x00004550 { // 0x4550 is "PE"
84-
uefi.DebugPrint("cannot find PE header", uint64(pe.magic))
85-
return
86-
}
87-
88-
// Iterate through sections.
89-
section := (*peSection)(unsafe.Pointer(uintptr(unsafe.Pointer(pe)) + uintptr(pe.sizeOfOptionalHeader) + unsafe.Sizeof(peHeader{})))
90-
for i := 0; i < int(pe.numberOfSections); i++ {
91-
if section.characteristics&IMAGE_SCN_MEM_WRITE != 0 {
92-
// Found a writable section. Scan the entire section for roots.
93-
start := uintptr(unsafe.Pointer(module)) + uintptr(section.virtualAddress)
94-
end := uintptr(unsafe.Pointer(module)) + uintptr(section.virtualAddress) + uintptr(section.virtualSize)
95-
found(start, end)
96-
}
97-
section = (*peSection)(unsafe.Add(unsafe.Pointer(section), unsafe.Sizeof(peSection{})))
98-
}
34+
findGlobalsForPE(found)
9935
}

src/runtime/os_winabi.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
//go:build windows || uefi
2+
3+
package runtime
4+
5+
import (
6+
"machine/uefi"
7+
"unsafe"
8+
)
9+
10+
// MS-DOS stub with PE header offset:
11+
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#ms-dos-stub-image-only
12+
type exeHeader struct {
13+
signature uint16
14+
_ [58]byte // skip DOS header
15+
peHeader uint32 // at offset 0x3C
16+
}
17+
18+
// COFF file header:
19+
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#file-headers
20+
type peHeader struct {
21+
magic uint32
22+
machine uint16
23+
numberOfSections uint16
24+
timeDateStamp uint32
25+
pointerToSymbolTable uint32
26+
numberOfSymbols uint32
27+
sizeOfOptionalHeader uint16
28+
characteristics uint16
29+
}
30+
31+
// COFF section header:
32+
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#section-table-section-headers
33+
type peSection struct {
34+
name [8]byte
35+
virtualSize uint32
36+
virtualAddress uint32
37+
sizeOfRawData uint32
38+
pointerToRawData uint32
39+
pointerToRelocations uint32
40+
pointerToLinenumbers uint32
41+
numberOfRelocations uint16
42+
numberOfLinenumbers uint16
43+
characteristics uint32
44+
}
45+
46+
var module *exeHeader
47+
48+
func findGlobalsForPE(found func(start, end uintptr)) {
49+
// Constants used in this function.
50+
const (
51+
// https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulehandleexa
52+
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT = 0x00000002
53+
54+
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format
55+
IMAGE_SCN_MEM_WRITE = 0x80000000
56+
)
57+
58+
pe := (*peHeader)(unsafe.Add(unsafe.Pointer(module), module.peHeader))
59+
if pe.magic != 0x00004550 { // 0x4550 is "PE"
60+
uefi.DebugPrint("cannot find PE header", uint64(pe.magic))
61+
return
62+
}
63+
64+
// Iterate through sections.
65+
section := (*peSection)(unsafe.Pointer(uintptr(unsafe.Pointer(pe)) + uintptr(pe.sizeOfOptionalHeader) + unsafe.Sizeof(peHeader{})))
66+
for i := 0; i < int(pe.numberOfSections); i++ {
67+
if section.characteristics&IMAGE_SCN_MEM_WRITE != 0 {
68+
// Found a writable section. Scan the entire section for roots.
69+
start := uintptr(unsafe.Pointer(module)) + uintptr(section.virtualAddress)
70+
end := uintptr(unsafe.Pointer(module)) + uintptr(section.virtualAddress) + uintptr(section.virtualSize)
71+
found(start, end)
72+
}
73+
section = (*peSection)(unsafe.Add(unsafe.Pointer(section), unsafe.Sizeof(peSection{})))
74+
}
75+
}

src/runtime/os_windows.go

Lines changed: 1 addition & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -7,44 +7,6 @@ const GOOS = "windows"
77
//export GetModuleHandleExA
88
func _GetModuleHandleExA(dwFlags uint32, lpModuleName unsafe.Pointer, phModule **exeHeader) bool
99

10-
// MS-DOS stub with PE header offset:
11-
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#ms-dos-stub-image-only
12-
type exeHeader struct {
13-
signature uint16
14-
_ [58]byte // skip DOS header
15-
peHeader uint32 // at offset 0x3C
16-
}
17-
18-
// COFF file header:
19-
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#file-headers
20-
type peHeader struct {
21-
magic uint32
22-
machine uint16
23-
numberOfSections uint16
24-
timeDateStamp uint32
25-
pointerToSymbolTable uint32
26-
numberOfSymbols uint32
27-
sizeOfOptionalHeader uint16
28-
characteristics uint16
29-
}
30-
31-
// COFF section header:
32-
// https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#section-table-section-headers
33-
type peSection struct {
34-
name [8]byte
35-
virtualSize uint32
36-
virtualAddress uint32
37-
sizeOfRawData uint32
38-
pointerToRawData uint32
39-
pointerToRelocations uint32
40-
pointerToLinenumbers uint32
41-
numberOfRelocations uint16
42-
numberOfLinenumbers uint16
43-
characteristics uint32
44-
}
45-
46-
var module *exeHeader
47-
4810
// Mark global variables.
4911
// Unfortunately, the linker doesn't provide symbols for the start and end of
5012
// the data/bss sections. Therefore these addresses need to be determined at
@@ -72,23 +34,7 @@ func findGlobals(found func(start, end uintptr)) {
7234
}
7335
}
7436

75-
// Find the PE header at offset 0x3C.
76-
pe := (*peHeader)(unsafe.Add(unsafe.Pointer(module), module.peHeader))
77-
if gcAsserts && pe.magic != 0x00004550 { // 0x4550 is "PE"
78-
runtimePanic("cannot find PE header")
79-
}
80-
81-
// Iterate through sections.
82-
section := (*peSection)(unsafe.Pointer(uintptr(unsafe.Pointer(pe)) + uintptr(pe.sizeOfOptionalHeader) + unsafe.Sizeof(peHeader{})))
83-
for i := 0; i < int(pe.numberOfSections); i++ {
84-
if section.characteristics&IMAGE_SCN_MEM_WRITE != 0 {
85-
// Found a writable section. Scan the entire section for roots.
86-
start := uintptr(unsafe.Pointer(module)) + uintptr(section.virtualAddress)
87-
end := uintptr(unsafe.Pointer(module)) + uintptr(section.virtualAddress) + uintptr(section.virtualSize)
88-
found(start, end)
89-
}
90-
section = (*peSection)(unsafe.Add(unsafe.Pointer(section), unsafe.Sizeof(peSection{})))
91-
}
37+
findGlobalsForPE(found)
9238
}
9339

9440
type systeminfo struct {

0 commit comments

Comments
 (0)