mirror of
https://github.com/golang/go
synced 2024-11-17 10:54:50 -07:00
debug/pe: fix TestDWARF to work with relocations
Fixes #27904 Change-Id: Ie2aad20cd66785b6cc1018c0048824382cb39f8c Reviewed-on: https://go-review.googlesource.com/c/140158 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
68d52969dd
commit
3d19d95932
@ -298,6 +298,17 @@ const (
|
||||
linkCgoExternal
|
||||
)
|
||||
|
||||
func getImageBase(f *File) uintptr {
|
||||
switch oh := f.OptionalHeader.(type) {
|
||||
case *OptionalHeader32:
|
||||
return uintptr(oh.ImageBase)
|
||||
case *OptionalHeader64:
|
||||
return uintptr(oh.ImageBase)
|
||||
default:
|
||||
panic("unexpected optionalheader type")
|
||||
}
|
||||
}
|
||||
|
||||
func testDWARF(t *testing.T, linktype int) {
|
||||
if runtime.GOOS != "windows" {
|
||||
t.Skip("skipping windows only test")
|
||||
@ -347,14 +358,15 @@ func testDWARF(t *testing.T, linktype int) {
|
||||
if err != nil {
|
||||
t.Fatalf("running test executable failed: %s %s", err, out)
|
||||
}
|
||||
t.Logf("Testprog output:\n%s", string(out))
|
||||
|
||||
matches := regexp.MustCompile("main=(.*)\n").FindStringSubmatch(string(out))
|
||||
matches := regexp.MustCompile("offset=(.*)\n").FindStringSubmatch(string(out))
|
||||
if len(matches) < 2 {
|
||||
t.Fatalf("unexpected program output: %s", out)
|
||||
}
|
||||
wantaddr, err := strconv.ParseUint(matches[1], 0, 64)
|
||||
wantoffset, err := strconv.ParseUint(matches[1], 0, 64)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected main address %q: %s", matches[1], err)
|
||||
t.Fatalf("unexpected main offset %q: %s", matches[1], err)
|
||||
}
|
||||
|
||||
f, err := Open(exe)
|
||||
@ -363,6 +375,8 @@ func testDWARF(t *testing.T, linktype int) {
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
imageBase := getImageBase(f)
|
||||
|
||||
var foundDebugGDBScriptsSection bool
|
||||
for _, sect := range f.Sections {
|
||||
if sect.Name == ".debug_gdb_scripts" {
|
||||
@ -389,10 +403,20 @@ func testDWARF(t *testing.T, linktype int) {
|
||||
break
|
||||
}
|
||||
if e.Tag == dwarf.TagSubprogram {
|
||||
if name, ok := e.Val(dwarf.AttrName).(string); ok && name == "main.main" {
|
||||
if addr, ok := e.Val(dwarf.AttrLowpc).(uint64); ok && addr == wantaddr {
|
||||
return
|
||||
name, ok := e.Val(dwarf.AttrName).(string)
|
||||
if ok && name == "main.main" {
|
||||
t.Logf("Found main.main")
|
||||
addr, ok := e.Val(dwarf.AttrLowpc).(uint64)
|
||||
if !ok {
|
||||
t.Fatal("Failed to get AttrLowpc")
|
||||
}
|
||||
offset := uintptr(addr) - imageBase
|
||||
if offset != uintptr(wantoffset) {
|
||||
t.Fatal("Runtime offset (0x%x) did "+
|
||||
"not match dwarf offset "+
|
||||
"(0x%x)", wantoffset, offset)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -479,11 +503,52 @@ const testprog = `
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
import "syscall"
|
||||
import "unsafe"
|
||||
{{if .}}import "C"
|
||||
{{end}}
|
||||
|
||||
// struct MODULEINFO from the Windows SDK
|
||||
type moduleinfo struct {
|
||||
BaseOfDll uintptr
|
||||
SizeOfImage uint32
|
||||
EntryPoint uintptr
|
||||
}
|
||||
|
||||
func add(p unsafe.Pointer, x uintptr) unsafe.Pointer {
|
||||
return unsafe.Pointer(uintptr(p) + x)
|
||||
}
|
||||
|
||||
func funcPC(f interface{}) uintptr {
|
||||
var a uintptr
|
||||
return **(**uintptr)(add(unsafe.Pointer(&f), unsafe.Sizeof(a)))
|
||||
}
|
||||
|
||||
func main() {
|
||||
kernel32 := syscall.MustLoadDLL("kernel32.dll")
|
||||
psapi := syscall.MustLoadDLL("psapi.dll")
|
||||
getModuleHandle := kernel32.MustFindProc("GetModuleHandleW")
|
||||
getCurrentProcess := kernel32.MustFindProc("GetCurrentProcess")
|
||||
getModuleInformation := psapi.MustFindProc("GetModuleInformation")
|
||||
|
||||
procHandle, _, _ := getCurrentProcess.Call()
|
||||
moduleHandle, _, err := getModuleHandle.Call(0)
|
||||
if moduleHandle == 0 {
|
||||
panic(fmt.Sprintf("GetModuleHandle() failed: %d", err))
|
||||
}
|
||||
|
||||
var info moduleinfo
|
||||
ret, _, err := getModuleInformation.Call(procHandle, moduleHandle,
|
||||
uintptr(unsafe.Pointer(&info)), unsafe.Sizeof(info))
|
||||
|
||||
if ret == 0 {
|
||||
panic(fmt.Sprintf("GetModuleInformation() failed: %d", err))
|
||||
}
|
||||
|
||||
offset := funcPC(main) - info.BaseOfDll
|
||||
fmt.Printf("base=0x%x\n", info.BaseOfDll)
|
||||
fmt.Printf("main=%p\n", main)
|
||||
fmt.Printf("offset=0x%x\n", offset)
|
||||
}
|
||||
`
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user