Skip to content
Snippets Groups Projects
Commit 20819440 authored by Cherry Zhang's avatar Cherry Zhang
Browse files

cmd/internal/objfile: correct file table reading for Go object file

Apparently I never actually understood the new file table in Go
object files. The PC value stream actually encodes the file index
in the per-CU table. I thought it was indexing into a per-function
table, which then contains index to the per-CU table. Remove the
extra indirection.

Change-Id: I0aea5629f7b3888ebe3a04fea437aa15ce89519e
Reviewed-on: https://go-review.googlesource.com/c/go/+/262779


Trust: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: default avatarThan McIntosh <thanm@google.com>
Reviewed-by: default avatarJeremy Faller <jeremy@golang.org>
parent 771f5f2e
No related branches found
No related tags found
No related merge requests found
...@@ -267,13 +267,11 @@ func (f *goobjFile) PCToLine(pc uint64) (string, int, *gosym.Func) { ...@@ -267,13 +267,11 @@ func (f *goobjFile) PCToLine(pc uint64) (string, int, *gosym.Func) {
} }
b := r.BytesAt(r.DataOff(isym), r.DataSize(isym)) b := r.BytesAt(r.DataOff(isym), r.DataSize(isym))
var info *goobj.FuncInfo var info *goobj.FuncInfo
lengths := info.ReadFuncInfoLengths(b)
pcline := getSymData(info.ReadPcline(b)) pcline := getSymData(info.ReadPcline(b))
line := int(pcValue(pcline, pc-addr, f.arch)) line := int(pcValue(pcline, pc-addr, f.arch))
pcfile := getSymData(info.ReadPcfile(b)) pcfile := getSymData(info.ReadPcfile(b))
fileID := pcValue(pcfile, pc-addr, f.arch) fileID := pcValue(pcfile, pc-addr, f.arch)
globalFileID := info.ReadFile(b, lengths.FileOff, uint32(fileID)) fileName := r.File(int(fileID))
fileName := r.File(int(globalFileID))
// Note: we provide only the name in the Func structure. // Note: we provide only the name in the Func structure.
// We could provide more if needed. // We could provide more if needed.
return fileName, line, &gosym.Func{Sym: &gosym.Sym{Name: osym.Name(r)}} return fileName, line, &gosym.Func{Sym: &gosym.Sym{Name: osym.Name(r)}}
......
...@@ -333,3 +333,41 @@ func TestDisasmGoobj(t *testing.T) { ...@@ -333,3 +333,41 @@ func TestDisasmGoobj(t *testing.T) {
t.Logf("full disassembly:\n%s", text) t.Logf("full disassembly:\n%s", text)
} }
} }
func TestGoobjFileNumber(t *testing.T) {
// Test that file table in Go object file is parsed correctly.
testenv.MustHaveGoBuild(t)
t.Parallel()
tmpdir, err := ioutil.TempDir("", "TestGoobjFileNumber")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmpdir)
obj := filepath.Join(tmpdir, "p.a")
cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", obj)
cmd.Dir = filepath.Join("testdata/testfilenum")
out, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("build failed: %v\n%s", err, out)
}
cmd = exec.Command(exe, obj)
out, err = cmd.CombinedOutput()
if err != nil {
t.Fatalf("objdump failed: %v\n%s", err, out)
}
text := string(out)
for _, s := range []string{"a.go", "b.go", "c.go"} {
if !strings.Contains(text, s) {
t.Errorf("output missing '%s'", s)
}
}
if t.Failed() {
t.Logf("output:\n%s", text)
}
}
// Copyright 2020 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 p
func A() {}
// Copyright 2020 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 p
func B() {}
// Copyright 2020 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 p
func C() {}
module objdumptest
go 1.16
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment