mirror of
https://github.com/golang/go
synced 2024-11-19 20:54:39 -07:00
cmd/nm: windows pe handling fixes
- output absolute addresses, not relative; - accept negative section numbers. Update #6936 Fixes #7738 LGTM=rsc R=golang-codereviews, bradfitz, ruiu, rsc CC=golang-codereviews https://golang.org/cl/85240046
This commit is contained in:
parent
387895f9ac
commit
06dc4e78c4
@ -19,6 +19,7 @@
|
||||
// d static data segment symbol
|
||||
// B bss segment symbol
|
||||
// b static bss segment symbol
|
||||
// C constant address
|
||||
// U referenced but undefined symbol
|
||||
//
|
||||
// Following established convention, the address is omitted for undefined
|
||||
|
40
src/cmd/nm/nm_test.go
Normal file
40
src/cmd/nm/nm_test.go
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNM(t *testing.T) {
|
||||
out, err := exec.Command("go", "build", "-o", "testnm.exe", "cmd/nm").CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("go build -o testnm.exe cmd/nm: %v\n%s", err, string(out))
|
||||
}
|
||||
defer os.Remove("testnm.exe")
|
||||
|
||||
testfiles := []string{
|
||||
"elf/testdata/gcc-386-freebsd-exec",
|
||||
"elf/testdata/gcc-amd64-linux-exec",
|
||||
"macho/testdata/gcc-386-darwin-exec",
|
||||
"macho/testdata/gcc-amd64-darwin-exec",
|
||||
"pe/testdata/gcc-amd64-mingw-exec",
|
||||
"pe/testdata/gcc-386-mingw-exec",
|
||||
"plan9obj/testdata/amd64-plan9-exec",
|
||||
"plan9obj/testdata/386-plan9-exec",
|
||||
}
|
||||
for _, f := range testfiles {
|
||||
exepath := filepath.Join(runtime.GOROOT(), "src", "pkg", "debug", f)
|
||||
cmd := exec.Command("./testnm.exe", exepath)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("go tool nm %v: %v\n%s", exepath, err, string(out))
|
||||
}
|
||||
}
|
||||
}
|
@ -18,12 +18,41 @@ func peSymbols(f *os.File) []Sym {
|
||||
return nil
|
||||
}
|
||||
|
||||
var imageBase uint64
|
||||
switch oh := p.OptionalHeader.(type) {
|
||||
case *pe.OptionalHeader32:
|
||||
imageBase = uint64(oh.ImageBase)
|
||||
case *pe.OptionalHeader64:
|
||||
imageBase = oh.ImageBase
|
||||
default:
|
||||
errorf("parsing %s: file format not recognized", f.Name())
|
||||
return nil
|
||||
}
|
||||
|
||||
var syms []Sym
|
||||
for _, s := range p.Symbols {
|
||||
const (
|
||||
N_UNDEF = 0 // An undefined (extern) symbol
|
||||
N_ABS = -1 // An absolute symbol (e_value is a constant, not an address)
|
||||
N_DEBUG = -2 // A debugging symbol
|
||||
)
|
||||
sym := Sym{Name: s.Name, Addr: uint64(s.Value), Code: '?'}
|
||||
if s.SectionNumber == 0 {
|
||||
switch s.SectionNumber {
|
||||
case N_UNDEF:
|
||||
sym.Code = 'U'
|
||||
} else if int(s.SectionNumber) <= len(p.Sections) {
|
||||
case N_ABS:
|
||||
sym.Code = 'C'
|
||||
case N_DEBUG:
|
||||
sym.Code = '?'
|
||||
default:
|
||||
if s.SectionNumber < 0 {
|
||||
errorf("parsing %s: invalid section number %d", f.Name(), s.SectionNumber)
|
||||
return nil
|
||||
}
|
||||
if len(p.Sections) < int(s.SectionNumber) {
|
||||
errorf("parsing %s: section number %d is large then max %d", f.Name(), s.SectionNumber, len(p.Sections))
|
||||
return nil
|
||||
}
|
||||
sect := p.Sections[s.SectionNumber-1]
|
||||
const (
|
||||
text = 0x20
|
||||
@ -46,6 +75,7 @@ func peSymbols(f *os.File) []Sym {
|
||||
case ch&bss != 0:
|
||||
sym.Code = 'B'
|
||||
}
|
||||
sym.Addr += imageBase + uint64(sect.VirtualAddress)
|
||||
}
|
||||
syms = append(syms, sym)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user