Source file src/debug/dwarf/entry_test.go

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

View as plain text