github.com/cnboonhan/delve@v0.0.0-20230908061759-363f2388c2fb/pkg/dwarf/loclist/loclist5_test.go (about)

     1  package loclist
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"testing"
     7  
     8  	"github.com/go-delve/delve/pkg/dwarf/leb128"
     9  )
    10  
    11  func TestLoclist5(t *testing.T) {
    12  	buf := new(bytes.Buffer)
    13  
    14  	p32 := func(n uint32) { binary.Write(buf, binary.LittleEndian, n) }
    15  	p16 := func(n uint16) { binary.Write(buf, binary.LittleEndian, n) }
    16  	p8 := func(n uint8) { binary.Write(buf, binary.LittleEndian, n) }
    17  	uleb := func(n uint64) { leb128.EncodeUnsigned(buf, n) }
    18  
    19  	p32(0x0) // length (use 0 because it is ignored)
    20  	p16(0x5) // version
    21  	p8(4)    // address size
    22  	p8(0)    // segment selector size
    23  	p32(0)   // offset_entry_count
    24  
    25  	off := buf.Len()
    26  
    27  	// (offset) start_base+0x10200 .. start_base+0x10300: 0x2
    28  	p8(_DW_LLE_offset_pair)
    29  	uleb(0x10200)
    30  	uleb(0x10300)
    31  	uleb(4)
    32  	p32(2)
    33  
    34  	// base address -> 0x02000000
    35  	p8(_DW_LLE_base_address)
    36  	p32(0x02000000)
    37  
    38  	// (offset) 0x02010400 .. 0x02010500: 3
    39  	p8(_DW_LLE_offset_pair)
    40  	uleb(0x10400)
    41  	uleb(0x10500)
    42  	uleb(4)
    43  	p32(3)
    44  
    45  	// (offset) 0x02010600 .. 0x02010600: 4
    46  	p8(_DW_LLE_offset_pair)
    47  	uleb(0x10600)
    48  	uleb(0x10600)
    49  	uleb(4)
    50  	p32(4)
    51  
    52  	// (offset) 0x02010800 .. 0x02010900: 5
    53  	p8(_DW_LLE_offset_pair)
    54  	uleb(0x10800)
    55  	uleb(0x10900)
    56  	uleb(4)
    57  	p32(5)
    58  
    59  	// (start end) 0x2010a00 .. 0x2010b00: 6
    60  	p8(_DW_LLE_start_end)
    61  	p32(0x2010a00)
    62  	p32(0x2010b00)
    63  	uleb(4)
    64  	p32(6)
    65  
    66  	// (start length) 0x2010c00 .. 0x2010d00: 7
    67  	p8(_DW_LLE_start_length)
    68  	p32(0x2010c00)
    69  	uleb(0x100)
    70  	uleb(4)
    71  	p32(7)
    72  
    73  	// (offset) 0x02000000 .. 0x02000001: 8
    74  	p8(_DW_LLE_offset_pair)
    75  	uleb(0)
    76  	uleb(1)
    77  	uleb(4)
    78  	p32(8)
    79  
    80  	// default location 10
    81  	p8(_DW_LLE_default_location)
    82  	uleb(4)
    83  	p32(10)
    84  
    85  	// loclist end
    86  	p8(_DW_LLE_end_of_list)
    87  
    88  	type testCase struct {
    89  		pc  uint64
    90  		tgt Entry
    91  	}
    92  
    93  	testCases := []testCase{
    94  		{0x01000000, Entry{0x01000000, 0x01000001, []byte{10, 0, 0, 0}}}, // default entry
    95  		{0x01010200, Entry{0x01010200, 0x01010300, []byte{2, 0, 0, 0}}},  // offset pair entry
    96  		{0x01010210, Entry{0x01010200, 0x01010300, []byte{2, 0, 0, 0}}},  // offset pair entry
    97  		{0x01010300, Entry{0x01010300, 0x01010301, []byte{10, 0, 0, 0}}}, // default entry (one past offset pair entry)
    98  		{0x02010400, Entry{0x02010400, 0x02010500, []byte{3, 0, 0, 0}}},  // offset pair entry, after base address selection
    99  		{0x02010600, Entry{0x02010600, 0x02010601, []byte{10, 0, 0, 0}}}, // default entry (beginning of empty offset pair entry)
   100  		{0x02010800, Entry{0x02010800, 0x02010900, []byte{5, 0, 0, 0}}},  // offset pair entry after empty offset pair
   101  		{0x02010a00, Entry{0x02010a00, 0x02010b00, []byte{6, 0, 0, 0}}},  // start end entry
   102  		{0x02010c00, Entry{0x02010c00, 0x02010d00, []byte{7, 0, 0, 0}}},  // start length entry
   103  		{0x02000000, Entry{0x02000000, 0x02000001, []byte{8, 0, 0, 0}}},  // out of order offset pair entry
   104  		{0x02000001, Entry{0x02000001, 0x02000002, []byte{10, 0, 0, 0}}}, // default entry (after out of order offset pair)
   105  	}
   106  
   107  	ll := NewDwarf5Reader(buf.Bytes())
   108  
   109  	for _, tc := range testCases {
   110  		e, err := ll.Find(off, 0x0, 0x01000000, tc.pc, nil)
   111  		if err != nil {
   112  			t.Errorf("error returned for %#x: %v", tc.pc, err)
   113  			continue
   114  		}
   115  		if e.LowPC != tc.tgt.LowPC || e.HighPC != tc.tgt.HighPC || !bytes.Equal(e.Instr, tc.tgt.Instr) {
   116  			t.Errorf("output mismatch for %#x,\nexpected %#v,\ngot     %#v", tc.pc, tc.tgt, e)
   117  		}
   118  	}
   119  }