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: 27 additions & 0 deletions cmd/stackwhere/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,3 +282,30 @@ func TestListCollectionJSONOrdersEqualUsageByName(t *testing.T) {
t.Fatalf("unexpected JSON output: got %#v want %#v", got, want)
}
}

func TestListProgramSupportsStartXLengthRangeLists(t *testing.T) {
cmd := root()
cmd.SetArgs([]string{"list", "../../testdata/noinline.o", "entry", "-j"})

var stdout bytes.Buffer
cmd.SetOut(&stdout)

if err := cmd.Execute(); err != nil {
t.Fatalf("list command failed: %v", err)
}

var got slotList
if err := json.Unmarshal(stdout.Bytes(), &got); err != nil {
t.Fatalf("failed to decode JSON output: %v", err)
}

want := slotList{
{
{Offset: 4, Name: "r1", ByteSize: -1},
},
}
if len(got) != len(want) || len(got[0]) != len(want[0]) ||
got[0][0].Offset != want[0][0].Offset || got[0][0].Name != want[0][0].Name || got[0][0].ByteSize != want[0][0].ByteSize {
t.Fatalf("unexpected JSON output: got %#v want %#v", got, want)
}
}
27 changes: 25 additions & 2 deletions internal/dwarf/rangelist.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ const (
DW_RLE_end_of_list rangelistDescriptorCode = 0x00
DW_RLE_base_addressx rangelistDescriptorCode = 0x01
// DW_RLE_startx_endx = 0x02
// DW_RLE_startx_length = 0x03
DW_RLE_offset_pair rangelistDescriptorCode = 0x04
DW_RLE_startx_length rangelistDescriptorCode = 0x03
DW_RLE_offset_pair rangelistDescriptorCode = 0x04
// DW_RLE_base_address = 0x05
// DW_RLE_start_end = 0x06
// DW_RLE_start_length = 0x07
Expand Down Expand Up @@ -167,6 +167,29 @@ loop:
if idx < uint64(len(debugAddrs)) {
currentBase = debugAddrs[idx]
}
case DW_RLE_startx_length:
var startIdx, length uint64
var l uint32
startIdx, l, err = leb128.DecodeUnsigned(r)
if err != nil {
return nil, fmt.Errorf("error parsing startx length entry: %w", err)
}
off += uint64(l)

length, l, err = leb128.DecodeUnsigned(r)
if err != nil {
return nil, fmt.Errorf("error parsing startx length entry: %w", err)
}
off += uint64(l)

if startIdx >= uint64(len(debugAddrs)) {
return nil, fmt.Errorf("startx length entry references invalid debug address index: %d", startIdx)
}

entry.Ranges = append(entry.Ranges, Range{
Start: debugAddrs[startIdx],
End: debugAddrs[startIdx] + length,
})
case DW_RLE_offset_pair:
var rng Range
var l uint32
Expand Down
1 change: 1 addition & 0 deletions testdata/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ docker:
TARGETS := \
basic \
equal \
noinline \
spill

.PHONY: all
Expand Down
15 changes: 15 additions & 0 deletions testdata/noinline.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#define __section(X) __attribute__((section(X), used))
#define __noinline __attribute__((noinline))

static __noinline void helper(int *value)
{
*value = 42;
}

__section("tc") int entry(void *ctx)
{
int value = 0;

helper(&value);
return value;
}
Binary file added testdata/noinline.o
Binary file not shown.