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([]byte{0}, nil, nil, test.info, nil, nil, nil, nil)
   271  		if err != nil {
   272  			t.Errorf("%s: %v", test.name, err)
   273  			continue
   274  		}
   275  
   276  		r := data.Reader()
   277  		if r.AddressSize() != test.addrSize {
   278  			t.Errorf("%s: got address size %d, want %d", test.name, r.AddressSize(), test.addrSize)
   279  		}
   280  		if r.ByteOrder() != test.byteOrder {
   281  			t.Errorf("%s: got byte order %s, want %s", test.name, r.ByteOrder(), test.byteOrder)
   282  		}
   283  	}
   284  }
   285  
   286  func TestUnitIteration(t *testing.T) {
   287  	// Iterate over all ELF test files we have and ensure that
   288  	// we get the same set of compilation units skipping (method 0)
   289  	// and not skipping (method 1) CU children.
   290  	files, err := filepath.Glob(filepath.Join("testdata", "*.elf"))
   291  	if err != nil {
   292  		t.Fatal(err)
   293  	}
   294  	for _, file := range files {
   295  		t.Run(file, func(t *testing.T) {
   296  			d := elfData(t, file)
   297  			var units [2][]any
   298  			for method := range units {
   299  				for r := d.Reader(); ; {
   300  					ent, err := r.Next()
   301  					if err != nil {
   302  						t.Fatal(err)
   303  					}
   304  					if ent == nil {
   305  						break
   306  					}
   307  					if ent.Tag == TagCompileUnit {
   308  						units[method] = append(units[method], ent.Val(AttrName))
   309  					}
   310  					if method == 0 {
   311  						if ent.Tag != TagCompileUnit {
   312  							t.Fatalf("found unexpected tag %v on top level", ent.Tag)
   313  						}
   314  						r.SkipChildren()
   315  					}
   316  				}
   317  			}
   318  			t.Logf("skipping CUs:     %v", units[0])
   319  			t.Logf("not-skipping CUs: %v", units[1])
   320  			if !reflect.DeepEqual(units[0], units[1]) {
   321  				t.Fatal("set of CUs differ")
   322  			}
   323  		})
   324  	}
   325  }
   326  
   327  func TestIssue51758(t *testing.T) {
   328  	abbrev := []byte{0x21, 0xff,
   329  		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x5c,
   330  		0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c,
   331  		0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33,
   332  		0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37,
   333  		0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37,
   334  		0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c,
   335  		0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c,
   336  		0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33,
   337  		0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37,
   338  		0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37,
   339  		0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c,
   340  		0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c,
   341  		0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33,
   342  		0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37,
   343  		0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37,
   344  		0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c,
   345  		0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c,
   346  		0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x22, 0x5c,
   347  		0x6e, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x3a, 0x20,
   348  		0x5c, 0x22, 0x5c, 0x5c, 0x30, 0x30, 0x35, 0x5c, 0x5c, 0x30, 0x30,
   349  		0x30, 0x5c, 0x5c, 0x30, 0x30, 0x30, 0x5c, 0x5c, 0x30, 0x30, 0x30,
   350  		0x5c, 0x5c, 0x30, 0x30, 0x34, 0x5c, 0x5c, 0x30, 0x30, 0x30, 0x5c,
   351  		0x5c, 0x30, 0x30, 0x30, 0x2d, 0x5c, 0x5c, 0x30, 0x30, 0x30, 0x5c,
   352  		0x22, 0x5c, 0x6e, 0x20, 0x20, 0x7d, 0x5c, 0x6e, 0x7d, 0x5c, 0x6e,
   353  		0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x72, 0x61, 0x6d, 0x65,
   354  		0x3a, 0x20, 0x22, 0x21, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37,
   355  		0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33,
   356  		0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c,
   357  		0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37,
   358  		0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37,
   359  		0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33,
   360  		0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c,
   361  		0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37,
   362  		0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37,
   363  		0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33,
   364  		0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c,
   365  		0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37,
   366  		0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37,
   367  		0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33,
   368  		0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c,
   369  		0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37,
   370  		0x5c, 0x33, 0x37, 0x37, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69,
   371  		0x6e, 0x66, 0x6f, 0x3a, 0x20, 0x22, 0x5c, 0x30, 0x30, 0x35, 0x5c,
   372  		0x30, 0x30, 0x30, 0x5c, 0x30, 0x30, 0x30, 0x5c, 0x30, 0x30, 0x30,
   373  		0x5c, 0x30, 0x30, 0x34, 0x5c, 0x30, 0x30, 0x30, 0x5c, 0x30, 0x30,
   374  		0x30, 0x2d, 0x5c, 0x30, 0x30, 0x30, 0x22, 0x0a, 0x20, 0x20, 0x7d,
   375  		0x0a, 0x7d, 0x0a, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x7b, 0x0a, 0x7d,
   376  		0x0a, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x7b, 0x0a, 0x7d, 0x0a, 0x6c,
   377  		0x69, 0x73, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x4e, 0x65, 0x77,
   378  		0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x61, 0x62, 0x62, 0x72,
   379  		0x65, 0x76, 0x3a, 0x20, 0x22, 0x5c, 0x30, 0x30, 0x35, 0x5c, 0x30,
   380  		0x30, 0x30, 0x5c, 0x30, 0x30, 0x30, 0x5c, 0x30, 0x30, 0x30, 0x5c,
   381  		0x30, 0x30, 0x34, 0x5c, 0x30, 0x30, 0x30, 0x5c, 0x30, 0x30, 0x30,
   382  		0x2d, 0x5c, 0x30, 0x30, 0x30, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x7b,
   383  		0x5c, 0x6e, 0x20, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x7b, 0x5c, 0x6e,
   384  		0x20, 0x20, 0x20, 0x20, 0x61, 0x62, 0x62, 0x72, 0x65, 0x76, 0x3a,
   385  		0x20, 0x5c, 0x22, 0x21, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c,
   386  		0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33,
   387  		0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37,
   388  		0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37,
   389  		0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c,
   390  		0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c,
   391  		0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33,
   392  		0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37,
   393  		0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37,
   394  		0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c,
   395  		0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c,
   396  		0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33,
   397  		0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37,
   398  		0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37,
   399  		0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c,
   400  		0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c,
   401  		0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33,
   402  		0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37,
   403  		0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37,
   404  		0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x5c, 0x33, 0x37, 0x37, 0x5c,
   405  		0x5c, 0x33, 0x37, 0x37, 0x5c, 0x22, 0x5c, 0x6e, 0x20, 0x20, 0x20,
   406  		0x20, 0x69, 0x6e, 0x66, 0x6f, 0x3a, 0x20, 0x5c, 0x22, 0x5c, 0x5c,
   407  		0x30, 0x30, 0x35, 0x5c, 0x5c, 0x30, 0x30, 0x30, 0x5c, 0x5c, 0x30,
   408  		0x30, 0x30, 0x5c, 0x5c, 0x30, 0x30, 0x30, 0x5c, 0x5c, 0x30, 0x30,
   409  		0x34, 0x5c, 0x5c, 0x30, 0x30, 0x30, 0x5c, 0x5c, 0x30, 0x30, 0x30,
   410  		0x2d, 0x5c, 0x5c, 0x30, 0x30, 0x30, 0x5c, 0x22, 0x5c, 0x6e, 0x20,
   411  		0x20, 0x7d, 0x5c, 0x6e, 0x7d, 0x5c, 0x6e, 0x22, 0x0a, 0x20, 0x20,
   412  		0x20, 0x20, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x22, 0x21,
   413  		0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37,
   414  		0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33,
   415  		0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c,
   416  		0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37,
   417  		0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37,
   418  		0x37, 0x5c, 0x33, 0x37, 0x37, 0x5c, 0x33, 0x37, 0x37, 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, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   424  		0xff}
   425  	aranges := []byte{0x2c}
   426  	frame := []byte{}
   427  	info := []byte{0x5, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x2d, 0x0, 0x5,
   428  		0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x2d, 0x0}
   429  
   430  	// The input above is malformed; the goal here it just to make sure
   431  	// that we don't get a panic or other bad behavior while trying to
   432  	// construct a dwarf.Data object from the input.  For good measure,
   433  	// test to make sure we can handle the case where the input is
   434  	// truncated as well.
   435  	for i := 0; i <= len(info); i++ {
   436  		truncated := info[:i]
   437  		dw, err := New(abbrev, aranges, frame, truncated, nil, nil, nil, nil)
   438  		if err == nil {
   439  			t.Errorf("expected error")
   440  		} else {
   441  			if dw != nil {
   442  				t.Errorf("got non-nil dw, wanted nil")
   443  			}
   444  		}
   445  	}
   446  }
   447  
   448  func TestIssue52045(t *testing.T) {
   449  	var aranges, frame, line, pubnames, ranges, str []byte
   450  	abbrev := []byte{0}
   451  	info := []byte{0x7, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
   452  
   453  	// A hand-crafted input corresponding to a minimal-size
   454  	// .debug_info (header only, no DIEs) and an empty abbrev table.
   455  	data0, err := New(abbrev, aranges, frame, info, line, pubnames, ranges, str)
   456  	if err != nil {
   457  		t.Fatal(err)
   458  	}
   459  
   460  	reader0 := data0.Reader()
   461  	entry0, _ := reader0.SeekPC(0x0)
   462  	// main goal is to make sure we can get here without crashing
   463  	if entry0 != nil {
   464  		t.Errorf("got non-nil entry0, wanted nil")
   465  	}
   466  }
   467  
   468  func TestIssue57046(t *testing.T) {
   469  	f, err := elf.Open("testdata/issue57046-clang.elf5")
   470  	if err != nil {
   471  		t.Fatalf("elf.Open returns err: %v", err)
   472  	}
   473  	d, err := f.DWARF()
   474  	if err != nil {
   475  		t.Fatalf("f.DWARF returns err: %v", err)
   476  	}
   477  	// Write down all the subprogram DIEs.
   478  	spdies := []Offset{}
   479  	lopcs := []uint64{}
   480  	r := d.Reader()
   481  	for {
   482  		e, err := r.Next()
   483  		if err != nil {
   484  			t.Fatalf("r.Next() returns err: %v", err)
   485  		}
   486  		if e == nil {
   487  			break
   488  		}
   489  		if e.Tag != TagSubprogram {
   490  			continue
   491  		}
   492  		var name string
   493  		var lopc uint64
   494  		if n, ok := e.Val(AttrName).(string); ok {
   495  			name = n
   496  		}
   497  		if lo, ok := e.Val(AttrLowpc).(uint64); ok {
   498  			lopc = lo
   499  		}
   500  		if name == "" || lopc == 0 {
   501  			continue
   502  		}
   503  		spdies = append(spdies, e.Offset)
   504  		lopcs = append(lopcs, lopc)
   505  	}
   506  
   507  	// Seek to the second entry in spdies (corresponding to mom() in
   508  	// issue57046_part2.c) and take a look at it.
   509  	r2 := d.Reader()
   510  	r2.Seek(spdies[1])
   511  	e, err := r2.Next()
   512  	if err != nil {
   513  		t.Fatalf("r2.Next() returns err: %v", err)
   514  	}
   515  	if e == nil {
   516  		t.Fatalf("r2.Next() returned nil")
   517  	}
   518  
   519  	// Verify that the lopc we see matches what we saw before.
   520  	got := e.Val(AttrLowpc).(uint64)
   521  	if got != lopcs[1] {
   522  		t.Errorf("bad lopc for fn2 following seek: want %x got %x\n",
   523  			lopcs[1], got)
   524  	}
   525  }
   526  

View as plain text