Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 13 additions & 14 deletions internal/dwarf/tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,22 +59,22 @@ func newDWARFTreeReader(fileReader io.ReaderAt) (*Tree, error) {
continue
}

n := newNode(tree, entry)
var n *Node
if cur == nil {
if entry.Tag != dwarf.TagCompileUnit {
return nil, fmt.Errorf("unexpected root entry with tag %s", entry.Tag)
}

tree.root = n
cur = n

lr, err := dbg.LineReader(entry)
if err != nil {
return nil, fmt.Errorf("failed to create line reader: %w", err)
}

tree.files = lr.Files()
n = newNode(tree, entry, lr.Files())
tree.root = n
cur = n
} else {
n = newNode(tree, entry, cur.files)
cur.children = append(cur.children, n)
n.parent = cur

Expand All @@ -94,16 +94,14 @@ type Tree struct {
index map[dwarf.Offset]*Node
byType map[dwarf.Tag][]*Node

files []*dwarf.LineFile
llt *LoclistTable
rlt *RangeListTable
llt *LoclistTable
rlt *RangeListTable
}

func newTree(llt *LoclistTable, rlt *RangeListTable) *Tree {
return &Tree{
index: make(map[dwarf.Offset]*Node),
byType: make(map[dwarf.Tag][]*Node),
files: nil,
llt: llt,
rlt: rlt,
}
Expand All @@ -125,15 +123,16 @@ func (t *Tree) Dump() {
t.root.Dump(0)
}

func newNode(tree *Tree, entry *dwarf.Entry) *Node {
return &Node{tree: tree, entry: entry}
func newNode(tree *Tree, entry *dwarf.Entry, files []*dwarf.LineFile) *Node {
return &Node{tree: tree, entry: entry, files: files}
}

type Node struct {
tree *Tree
entry *dwarf.Entry
parent *Node
children []*Node
files []*dwarf.LineFile
}

func (n *Node) Entry() *dwarf.Entry {
Expand Down Expand Up @@ -200,7 +199,7 @@ func (n *Node) Dump(indent int) {
}

if attr.Attr == dwarf.AttrDeclFile {
fmt.Printf("%s %s: %s\n", strings.Repeat(" ", indent), attr.Attr, n.tree.files[attr.Val.(int64)].Name)
fmt.Printf("%s %s: %s\n", strings.Repeat(" ", indent), attr.Attr, n.files[attr.Val.(int64)].Name)
continue
}

Expand Down Expand Up @@ -381,7 +380,7 @@ func (n *Node) FileLineCol() string {

return ""
}
file := n.tree.files[fileIndex.(int64)]
file := n.files[fileIndex.(int64)]

fileLine := n.Entry().Val(dwarf.AttrDeclLine)
if fileLine != nil {
Expand All @@ -406,7 +405,7 @@ func (n *Node) CallFileLineCol() string {

return ""
}
file := n.tree.files[callFileIndex.(int64)]
file := n.files[callFileIndex.(int64)]

callLine := n.Entry().Val(dwarf.AttrCallLine)
if callLine != nil {
Expand Down
46 changes: 46 additions & 0 deletions internal/dwarf/tree_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Cilium

package dwarf

import (
"debug/dwarf"
"testing"
)

func TestNodeLocationsUseCompilationUnitFiles(t *testing.T) {
firstUnitFiles := []*dwarf.LineFile{{Name: "first.c"}}
secondUnitFiles := []*dwarf.LineFile{{Name: "second.c"}}

firstNode := &Node{
entry: &dwarf.Entry{Field: []dwarf.Field{
{Attr: dwarf.AttrDeclFile, Val: int64(0)},
{Attr: dwarf.AttrDeclLine, Val: int64(7)},
{Attr: dwarf.AttrCallFile, Val: int64(0)},
{Attr: dwarf.AttrCallLine, Val: int64(9)},
}},
files: firstUnitFiles,
}
secondNode := &Node{
entry: &dwarf.Entry{Field: []dwarf.Field{
{Attr: dwarf.AttrDeclFile, Val: int64(0)},
{Attr: dwarf.AttrDeclLine, Val: int64(11)},
{Attr: dwarf.AttrCallFile, Val: int64(0)},
{Attr: dwarf.AttrCallLine, Val: int64(13)},
}},
files: secondUnitFiles,
}

if got := firstNode.FileLineCol(); got != "first.c:7" {
t.Fatalf("first node declaration location = %q, want %q", got, "first.c:7")
}
if got := firstNode.CallFileLineCol(); got != "first.c:9" {
t.Fatalf("first node call location = %q, want %q", got, "first.c:9")
}
if got := secondNode.FileLineCol(); got != "second.c:11" {
t.Fatalf("second node declaration location = %q, want %q", got, "second.c:11")
}
if got := secondNode.CallFileLineCol(); got != "second.c:13" {
t.Fatalf("second node call location = %q, want %q", got, "second.c:13")
}
}