1// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package dwarf_test
6
7import (
8	. "debug/dwarf"
9	"encoding/binary"
10	"path/filepath"
11	"reflect"
12	"testing"
13)
14
15func TestSplit(t *testing.T) {
16	// debug/dwarf doesn't (currently) support split DWARF, but
17	// the attributes that pointed to the split DWARF used to
18	// cause loading the DWARF data to fail entirely (issue
19	// #12592). Test that we can at least read the DWARF data.
20	d := elfData(t, "testdata/split.elf")
21	r := d.Reader()
22	e, err := r.Next()
23	if err != nil {
24		t.Fatal(err)
25	}
26	if e.Tag != TagCompileUnit {
27		t.Fatalf("bad tag: have %s, want %s", e.Tag, TagCompileUnit)
28	}
29	// Check that we were able to parse the unknown section offset
30	// field, even if we can't figure out its DWARF class.
31	const AttrGNUAddrBase Attr = 0x2133
32	f := e.AttrField(AttrGNUAddrBase)
33	if _, ok := f.Val.(int64); !ok {
34		t.Fatalf("bad attribute value type: have %T, want int64", f.Val)
35	}
36	if f.Class != ClassUnknown {
37		t.Fatalf("bad class: have %s, want %s", f.Class, ClassUnknown)
38	}
39}
40
41// wantRange maps from a PC to the ranges of the compilation unit
42// containing that PC.
43type wantRange struct {
44	pc     uint64
45	ranges [][2]uint64
46}
47
48func TestReaderSeek(t *testing.T) {
49	want := []wantRange{
50		{0x40059d, [][2]uint64{{0x40059d, 0x400601}}},
51		{0x400600, [][2]uint64{{0x40059d, 0x400601}}},
52		{0x400601, [][2]uint64{{0x400601, 0x400611}}},
53		{0x4005f0, [][2]uint64{{0x40059d, 0x400601}}}, // loop test
54		{0x10, nil},
55		{0x400611, nil},
56	}
57	testRanges(t, "testdata/line-gcc.elf", want)
58
59	want = []wantRange{
60		{0x401122, [][2]uint64{{0x401122, 0x401166}}},
61		{0x401165, [][2]uint64{{0x401122, 0x401166}}},
62		{0x401166, [][2]uint64{{0x401166, 0x401179}}},
63	}
64	testRanges(t, "testdata/line-gcc-dwarf5.elf", want)
65
66	want = []wantRange{
67		{0x401130, [][2]uint64{{0x401130, 0x40117e}}},
68		{0x40117d, [][2]uint64{{0x401130, 0x40117e}}},
69		{0x40117e, nil},
70	}
71	testRanges(t, "testdata/line-clang-dwarf5.elf", want)
72
73	want = []wantRange{
74		{0x401126, [][2]uint64{{0x401126, 0x40116a}}},
75		{0x40116a, [][2]uint64{{0x40116a, 0x401180}}},
76	}
77	testRanges(t, "testdata/line-gcc-zstd.elf", want)
78}
79
80func TestRangesSection(t *testing.T) {
81	want := []wantRange{
82		{0x400500, [][2]uint64{{0x400500, 0x400549}, {0x400400, 0x400408}}},
83		{0x400400, [][2]uint64{{0x400500, 0x400549}, {0x400400, 0x400408}}},
84		{0x400548, [][2]uint64{{0x400500, 0x400549}, {0x400400, 0x400408}}},
85		{0x400407, [][2]uint64{{0x400500, 0x400549}, {0x400400, 0x400408}}},
86		{0x400408, nil},
87		{0x400449, nil},
88		{0x4003ff, nil},
89	}
90	testRanges(t, "testdata/ranges.elf", want)
91}
92
93func TestRangesRnglistx(t *testing.T) {
94	want := []wantRange{
95		{0x401000, [][2]uint64{{0x401020, 0x40102c}, {0x401000, 0x40101d}}},
96		{0x40101c, [][2]uint64{{0x401020, 0x40102c}, {0x401000, 0x40101d}}},
97		{0x40101d, nil},
98		{0x40101f, nil},
99		{0x401020, [][2]uint64{{0x401020, 0x40102c}, {0x401000, 0x40101d}}},
100		{0x40102b, [][2]uint64{{0x401020, 0x40102c}, {0x401000, 0x40101d}}},
101		{0x40102c, nil},
102	}
103	testRanges(t, "testdata/rnglistx.elf", want)
104}
105
106func testRanges(t *testing.T, name string, want []wantRange) {
107	d := elfData(t, name)
108	r := d.Reader()
109	for _, w := range want {
110		entry, err := r.SeekPC(w.pc)
111		if err != nil {
112			if w.ranges != nil {
113				t.Errorf("%s: missing Entry for %#x", name, w.pc)
114			}
115			if err != ErrUnknownPC {
116				t.Errorf("%s: expected ErrUnknownPC for %#x, got %v", name, w.pc, err)
117			}
118			continue
119		}
120
121		ranges, err := d.Ranges(entry)
122		if err != nil {
123			t.Errorf("%s: %v", name, err)
124			continue
125		}
126		if !reflect.DeepEqual(ranges, w.ranges) {
127			t.Errorf("%s: for %#x got %x, expected %x", name, w.pc, ranges, w.ranges)
128		}
129	}
130}
131
132func TestReaderRanges(t *testing.T) {
133	type subprograms []struct {
134		name   string
135		ranges [][2]uint64
136	}
137	tests := []struct {
138		filename    string
139		subprograms subprograms
140	}{
141		{
142			"testdata/line-gcc.elf",
143			subprograms{
144				{"f1", [][2]uint64{{0x40059d, 0x4005e7}}},
145				{"main", [][2]uint64{{0x4005e7, 0x400601}}},
146				{"f2", [][2]uint64{{0x400601, 0x400611}}},
147			},
148		},
149		{
150			"testdata/line-gcc-dwarf5.elf",
151			subprograms{
152				{"main", [][2]uint64{{0x401147, 0x401166}}},
153				{"f1", [][2]uint64{{0x401122, 0x401147}}},
154				{"f2", [][2]uint64{{0x401166, 0x401179}}},
155			},
156		},
157		{
158			"testdata/line-clang-dwarf5.elf",
159			subprograms{
160				{"main", [][2]uint64{{0x401130, 0x401144}}},
161				{"f1", [][2]uint64{{0x401150, 0x40117e}}},
162				{"f2", [][2]uint64{{0x401180, 0x401197}}},
163			},
164		},
165		{
166			"testdata/line-gcc-zstd.elf",
167			subprograms{
168				{"f2", nil},
169				{"main", [][2]uint64{{0x40114b, 0x40116a}}},
170				{"f1", [][2]uint64{{0x401126, 0x40114b}}},
171				{"f2", [][2]uint64{{0x40116a, 0x401180}}},
172			},
173		},
174	}
175
176	for _, test := range tests {
177		d := elfData(t, test.filename)
178		subprograms := test.subprograms
179
180		r := d.Reader()
181		i := 0
182		for entry, err := r.Next(); entry != nil && err == nil; entry, err = r.Next() {
183			if entry.Tag != TagSubprogram {
184				continue
185			}
186
187			if i > len(subprograms) {
188				t.Fatalf("%s: too many subprograms (expected at most %d)", test.filename, i)
189			}
190
191			if got := entry.Val(AttrName).(string); got != subprograms[i].name {
192				t.Errorf("%s: subprogram %d name is %s, expected %s", test.filename, i, got, subprograms[i].name)
193			}
194			ranges, err := d.Ranges(entry)
195			if err != nil {
196				t.Errorf("%s: subprogram %d: %v", test.filename, i, err)
197				continue
198			}
199			if !reflect.DeepEqual(ranges, subprograms[i].ranges) {
200				t.Errorf("%s: subprogram %d ranges are %x, expected %x", test.filename, i, ranges, subprograms[i].ranges)
201			}
202			i++
203		}
204
205		if i < len(subprograms) {
206			t.Errorf("%s: saw only %d subprograms, expected %d", test.filename, i, len(subprograms))
207		}
208	}
209}
210
211func Test64Bit(t *testing.T) {
212	// I don't know how to generate a 64-bit DWARF debug
213	// compilation unit except by using XCOFF, so this is
214	// hand-written.
215	tests := []struct {
216		name      string
217		info      []byte
218		addrSize  int
219		byteOrder binary.ByteOrder
220	}{
221		{
222			"32-bit little",
223			[]byte{0x30, 0, 0, 0, // comp unit length
224				4, 0, // DWARF version 4
225				0, 0, 0, 0, // abbrev offset
226				8, // address size
227				0,
228				0, 0, 0, 0, 0, 0, 0, 0,
229				0, 0, 0, 0, 0, 0, 0, 0,
230				0, 0, 0, 0, 0, 0, 0, 0,
231				0, 0, 0, 0, 0, 0, 0, 0,
232				0, 0, 0, 0, 0, 0, 0, 0,
233			},
234			8, binary.LittleEndian,
235		},
236		{
237			"64-bit little",
238			[]byte{0xff, 0xff, 0xff, 0xff, // 64-bit DWARF
239				0x30, 0, 0, 0, 0, 0, 0, 0, // comp unit length
240				4, 0, // DWARF version 4
241				0, 0, 0, 0, 0, 0, 0, 0, // abbrev offset
242				8, // address size
243				0, 0, 0, 0, 0,
244				0, 0, 0, 0, 0, 0, 0, 0,
245				0, 0, 0, 0, 0, 0, 0, 0,
246				0, 0, 0, 0, 0, 0, 0, 0,
247				0, 0, 0, 0, 0, 0, 0, 0,
248			},
249			8, binary.LittleEndian,
250		},
251		{
252			"64-bit big",
253			[]byte{0xff, 0xff, 0xff, 0xff, // 64-bit DWARF
254				0, 0, 0, 0, 0, 0, 0, 0x30, // comp unit length
255				0, 4, // DWARF version 4
256				0, 0, 0, 0, 0, 0, 0, 0, // abbrev offset
257				8, // address size
258				0, 0, 0, 0, 0,
259				0, 0, 0, 0, 0, 0, 0, 0,
260				0, 0, 0, 0, 0, 0, 0, 0,
261				0, 0, 0, 0, 0, 0, 0, 0,
262				0, 0, 0, 0, 0, 0, 0, 0,
263			},
264			8, binary.BigEndian,
265		},
266	}
267
268	for _, test := range tests {
269		data, err := New(nil, nil, nil, test.info, nil, nil, nil, nil)
270		if err != nil {
271			t.Errorf("%s: %v", test.name, err)
272		}
273
274		r := data.Reader()
275		if r.AddressSize() != test.addrSize {
276			t.Errorf("%s: got address size %d, want %d", test.name, r.AddressSize(), test.addrSize)
277		}
278		if r.ByteOrder() != test.byteOrder {
279			t.Errorf("%s: got byte order %s, want %s", test.name, r.ByteOrder(), test.byteOrder)
280		}
281	}
282}
283
284func TestUnitIteration(t *testing.T) {
285	// Iterate over all ELF test files we have and ensure that
286	// we get the same set of compilation units skipping (method 0)
287	// and not skipping (method 1) CU children.
288	files, err := filepath.Glob(filepath.Join("testdata", "*.elf"))
289	if err != nil {
290		t.Fatal(err)
291	}
292	for _, file := range files {
293		t.Run(file, func(t *testing.T) {
294			d := elfData(t, file)
295			var units [2][]any
296			for method := range units {
297				for r := d.Reader(); ; {
298					ent, err := r.Next()
299					if err != nil {
300						t.Fatal(err)
301					}
302					if ent == nil {
303						break
304					}
305					if ent.Tag == TagCompileUnit {
306						units[method] = append(units[method], ent.Val(AttrName))
307					}
308					if method == 0 {
309						if ent.Tag != TagCompileUnit {
310							t.Fatalf("found unexpected tag %v on top level", ent.Tag)
311						}
312						r.SkipChildren()
313					}
314				}
315			}
316			t.Logf("skipping CUs:     %v", units[0])
317			t.Logf("not-skipping CUs: %v", units[1])
318			if !reflect.DeepEqual(units[0], units[1]) {
319				t.Fatal("set of CUs differ")
320			}
321		})
322	}
323}
324
325func TestIssue51758(t *testing.T) {
326	abbrev := []byte{0x21, 0xff,
327		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x5c,
328		0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c,
329		0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33,
330		0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37,
331		0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37,
332		0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c,
333		0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c,
334		0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33,
335		0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37,
336		0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37,
337		0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c,
338		0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c,
339		0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33,
340		0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37,
341		0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37,
342		0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c,
343		0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c,
344		0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x22, 0x5c,
345		0x6e, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x3a, 0x20,
346		0x5c, 0x22, 0x5c, 0x5c, 0x30, 0x30, 0x35, 0x5c, 0x5c, 0x30, 0x30,
347		0x30, 0x5c, 0x5c, 0x30, 0x30, 0x30, 0x5c, 0x5c, 0x30, 0x30, 0x30,
348		0x5c, 0x5c, 0x30, 0x30, 0x34, 0x5c, 0x5c, 0x30, 0x30, 0x30, 0x5c,
349		0x5c, 0x30, 0x30, 0x30, 0x2d, 0x5c, 0x5c, 0x30, 0x30, 0x30, 0x5c,
350		0x22, 0x5c, 0x6e, 0x20, 0x20, 0x7d, 0x5c, 0x6e, 0x7d, 0x5c, 0x6e,
351		0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x72, 0x61, 0x6d, 0x65,
352		0x3a, 0x20, 0x22, 0x21, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37,
353		0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33,
354		0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c,
355		0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37,
356		0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37,
357		0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33,
358		0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c,
359		0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37,
360		0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37,
361		0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33,
362		0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c,
363		0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37,
364		0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37,
365		0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33,
366		0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c,
367		0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37,
368		0x5c, 0x33, 0x37, 0x37, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69,
369		0x6e, 0x66, 0x6f, 0x3a, 0x20, 0x22, 0x5c, 0x30, 0x30, 0x35, 0x5c,
370		0x30, 0x30, 0x30, 0x5c, 0x30, 0x30, 0x30, 0x5c, 0x30, 0x30, 0x30,
371		0x5c, 0x30, 0x30, 0x34, 0x5c, 0x30, 0x30, 0x30, 0x5c, 0x30, 0x30,
372		0x30, 0x2d, 0x5c, 0x30, 0x30, 0x30, 0x22, 0x0a, 0x20, 0x20, 0x7d,
373		0x0a, 0x7d, 0x0a, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x7b, 0x0a, 0x7d,
374		0x0a, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x7b, 0x0a, 0x7d, 0x0a, 0x6c,
375		0x69, 0x73, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x4e, 0x65, 0x77,
376		0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x61, 0x62, 0x62, 0x72,
377		0x65, 0x76, 0x3a, 0x20, 0x22, 0x5c, 0x30, 0x30, 0x35, 0x5c, 0x30,
378		0x30, 0x30, 0x5c, 0x30, 0x30, 0x30, 0x5c, 0x30, 0x30, 0x30, 0x5c,
379		0x30, 0x30, 0x34, 0x5c, 0x30, 0x30, 0x30, 0x5c, 0x30, 0x30, 0x30,
380		0x2d, 0x5c, 0x30, 0x30, 0x30, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x7b,
381		0x5c, 0x6e, 0x20, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x7b, 0x5c, 0x6e,
382		0x20, 0x20, 0x20, 0x20, 0x61, 0x62, 0x62, 0x72, 0x65, 0x76, 0x3a,
383		0x20, 0x5c, 0x22, 0x21, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c,
384		0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33,
385		0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37,
386		0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37,
387		0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c,
388		0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c,
389		0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33,
390		0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37,
391		0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37,
392		0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c,
393		0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c,
394		0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33,
395		0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37,
396		0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37,
397		0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c,
398		0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c,
399		0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33,
400		0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37,
401		0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37,
402		0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c,
403		0x5c, 0x33, 0x37, 0x37, 0x5c, 0x22, 0x5c, 0x6e, 0x20, 0x20, 0x20,
404		0x20, 0x69, 0x6e, 0x66, 0x6f, 0x3a, 0x20, 0x5c, 0x22, 0x5c, 0x5c,
405		0x30, 0x30, 0x35, 0x5c, 0x5c, 0x30, 0x30, 0x30, 0x5c, 0x5c, 0x30,
406		0x30, 0x30, 0x5c, 0x5c, 0x30, 0x30, 0x30, 0x5c, 0x5c, 0x30, 0x30,
407		0x34, 0x5c, 0x5c, 0x30, 0x30, 0x30, 0x5c, 0x5c, 0x30, 0x30, 0x30,
408		0x2d, 0x5c, 0x5c, 0x30, 0x30, 0x30, 0x5c, 0x22, 0x5c, 0x6e, 0x20,
409		0x20, 0x7d, 0x5c, 0x6e, 0x7d, 0x5c, 0x6e, 0x22, 0x0a, 0x20, 0x20,
410		0x20, 0x20, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x22, 0x21,
411		0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37,
412		0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33,
413		0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c,
414		0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37,
415		0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37,
416		0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0xff, 0xff,
417		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
418		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
419		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
420		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
421		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
422		0xff}
423	aranges := []byte{0x2c}
424	frame := []byte{}
425	info := []byte{0x5, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x2d, 0x0, 0x5,
426		0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x2d, 0x0}
427
428	// The input above is malformed; the goal here it just to make sure
429	// that we don't get a panic or other bad behavior while trying to
430	// construct a dwarf.Data object from the input.  For good measure,
431	// test to make sure we can handle the case where the input is
432	// truncated as well.
433	for i := 0; i <= len(info); i++ {
434		truncated := info[:i]
435		dw, err := New(abbrev, aranges, frame, truncated, nil, nil, nil, nil)
436		if err == nil {
437			t.Errorf("expected error")
438		} else {
439			if dw != nil {
440				t.Errorf("got non-nil dw, wanted nil")
441			}
442		}
443	}
444}
445
446func TestIssue52045(t *testing.T) {
447	var abbrev, aranges, frame, line, pubnames, ranges, str []byte
448	info := []byte{0x7, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
449
450	// A hand-crafted input corresponding to a minimal-size
451	// .debug_info (header only, no DIEs) and an empty abbrev table.
452	data0, _ := New(abbrev, aranges, frame, info, line, pubnames, ranges, str)
453	reader0 := data0.Reader()
454	entry0, _ := reader0.SeekPC(0x0)
455	// main goal is to make sure we can get here without crashing
456	if entry0 != nil {
457		t.Errorf("got non-nil entry0, wanted nil")
458	}
459}
460