Commit 06dc4e78 authored by Alex Brainman's avatar Alex Brainman Committed by Russ Cox

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
parent 387895f9
......@@ -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
......
// 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)
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment