aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Brainman <alex.brainman@gmail.com>2014-04-21 19:28:02 +1000
committerAlex Brainman <alex.brainman@gmail.com>2014-04-21 19:28:02 +1000
commit80e7f972067b3da542ba86f969719456139f111d (patch)
tree59752558a05f85bf7ccf443d685cad41d9c1c15f
parent1bb4f37fcec4b22b663c995b0ff6a19a639d112d (diff)
downloadgo-80e7f972067b3da542ba86f969719456139f111d.tar.gz
go-80e7f972067b3da542ba86f969719456139f111d.zip
cmd/ld: correct addresses in windows pe symbol table
This should have been part of 36eb4a62fbb6, but I later discovered that addresses are all wrong. Appropriate test added now. LGTM=r R=golang-codereviews, r CC=golang-codereviews https://golang.org/cl/89470043
-rw-r--r--src/cmd/ld/pe.c13
-rw-r--r--src/cmd/nm/nm_test.go49
2 files changed, 61 insertions, 1 deletions
diff --git a/src/cmd/ld/pe.c b/src/cmd/ld/pe.c
index cd1dd03683..27c5574363 100644
--- a/src/cmd/ld/pe.c
+++ b/src/cmd/ld/pe.c
@@ -509,6 +509,17 @@ addsym(LSym *s, char *name, int type, vlong addr, vlong size, int ver, LSym *got
ncoffsym++;
}
+static vlong
+datoffsect(vlong addr)
+{
+ if(addr >= segdata.vaddr)
+ return addr - segdata.vaddr;
+ if(addr >= segtext.vaddr)
+ return addr - segtext.vaddr;
+ diag("datoff %#llx", addr);
+ return 0;
+}
+
static void
addsymtable(void)
{
@@ -540,7 +551,7 @@ addsymtable(void)
lputl(0);
lputl(s->strtbloff);
}
- lputl(datoff(s->sym->value));
+ lputl(datoffsect(s->sym->value));
wputl(s->sect);
wputl(0x0308); // "array of structs"
cput(2); // storage class: external
diff --git a/src/cmd/nm/nm_test.go b/src/cmd/nm/nm_test.go
index ba9dc00f56..761c5325f2 100644
--- a/src/cmd/nm/nm_test.go
+++ b/src/cmd/nm/nm_test.go
@@ -5,13 +5,55 @@
package main
import (
+ "bufio"
+ "bytes"
+ "fmt"
"os"
"os/exec"
"path/filepath"
"runtime"
+ "strings"
"testing"
)
+var testData uint32
+
+func checkSymbols(t *testing.T, nmoutput []byte) {
+ var checkSymbolsFound, testDataFound bool
+ scanner := bufio.NewScanner(bytes.NewBuffer(nmoutput))
+ for scanner.Scan() {
+ f := strings.Fields(scanner.Text())
+ if len(f) < 3 {
+ t.Error("nm must have at least 3 columns")
+ continue
+ }
+ switch f[2] {
+ case "cmd/nm.checkSymbols":
+ checkSymbolsFound = true
+ addr := "0x" + f[0]
+ if addr != fmt.Sprintf("%p", checkSymbols) {
+ t.Errorf("nm shows wrong address %v for checkSymbols (%p)", addr, checkSymbols)
+ }
+ case "cmd/nm.testData":
+ testDataFound = true
+ addr := "0x" + f[0]
+ if addr != fmt.Sprintf("%p", &testData) {
+ t.Errorf("nm shows wrong address %v for testData (%p)", addr, &testData)
+ }
+ }
+ }
+ if err := scanner.Err(); err != nil {
+ t.Errorf("error while reading symbols: %v", err)
+ return
+ }
+ if !checkSymbolsFound {
+ t.Error("nm shows no checkSymbols symbol")
+ }
+ if !testDataFound {
+ t.Error("nm shows no testData symbol")
+ }
+}
+
func TestNM(t *testing.T) {
out, err := exec.Command("go", "build", "-o", "testnm.exe", "cmd/nm").CombinedOutput()
if err != nil {
@@ -37,4 +79,11 @@ func TestNM(t *testing.T) {
t.Fatalf("go tool nm %v: %v\n%s", exepath, err, string(out))
}
}
+
+ cmd := exec.Command("./testnm.exe", os.Args[0])
+ out, err = cmd.CombinedOutput()
+ if err != nil {
+ t.Fatalf("go tool nm %v: %v\n%s", os.Args[0], err, string(out))
+ }
+ checkSymbols(t, out)
}