1 //===-- DWARFLocationDescription.cpp ----------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "DWARFLocationDescription.h" 11 #include "DWARFDefines.h" 12 #include "lldb/lldb-private.h" 13 #include "lldb/Core/Stream.h" 14 15 16 using namespace lldb_private; 17 18 static int print_dwarf_exp_op (Stream &s, const DataExtractor& data, lldb::offset_t *offset_ptr, int address_size, int dwarf_ref_size); 19 20 int 21 print_dwarf_expression (Stream &s, 22 const DataExtractor& data, 23 int address_size, 24 int dwarf_ref_size, 25 bool location_expression) 26 { 27 int op_count = 0; 28 lldb::offset_t offset = 0; 29 while (data.ValidOffset(offset)) 30 { 31 if (location_expression && op_count > 0) 32 { 33 // err (baton, "Dwarf location expressions may only have one operand!"); 34 return 1; 35 } 36 if (op_count > 0) 37 { 38 s.PutCString(", "); 39 } 40 if (print_dwarf_exp_op (s, data, &offset, address_size, dwarf_ref_size) == 1) 41 return 1; 42 op_count++; 43 } 44 45 return 0; 46 } 47 48 static int 49 print_dwarf_exp_op (Stream &s, 50 const DataExtractor& data, 51 lldb::offset_t *offset_ptr, 52 int address_size, 53 int dwarf_ref_size) 54 { 55 uint8_t opcode = data.GetU8(offset_ptr); 56 DRC_class opcode_class; 57 uint64_t uint; 58 int64_t sint; 59 60 int size; 61 62 opcode_class = DW_OP_value_to_class (opcode) & (~DRC_DWARFv3); 63 64 s.Printf("%s ", DW_OP_value_to_name (opcode)); 65 66 /* Does this take zero parameters? If so we can shortcut this function. */ 67 if (opcode_class == DRC_ZEROOPERANDS) 68 return 0; 69 70 if (opcode_class == DRC_TWOOPERANDS && opcode == DW_OP_bregx) 71 { 72 uint = data.GetULEB128(offset_ptr); 73 sint = data.GetSLEB128(offset_ptr); 74 s.Printf("%" PRIu64 " %" PRIi64, uint, sint); 75 return 0; 76 } 77 if (opcode_class != DRC_ONEOPERAND) 78 { 79 s.Printf("UNKNOWN OP %u", opcode); 80 return 1; 81 } 82 83 switch (opcode) 84 { 85 case DW_OP_addr: size = address_size; break; 86 case DW_OP_const1u: size = 1; break; 87 case DW_OP_const1s: size = -1; break; 88 case DW_OP_const2u: size = 2; break; 89 case DW_OP_const2s: size = -2; break; 90 case DW_OP_const4u: size = 4; break; 91 case DW_OP_const4s: size = -4; break; 92 case DW_OP_const8u: size = 8; break; 93 case DW_OP_const8s: size = -8; break; 94 case DW_OP_constu: size = 128; break; 95 case DW_OP_consts: size = -128; break; 96 case DW_OP_fbreg: size = -128; break; 97 case DW_OP_breg0: 98 case DW_OP_breg1: 99 case DW_OP_breg2: 100 case DW_OP_breg3: 101 case DW_OP_breg4: 102 case DW_OP_breg5: 103 case DW_OP_breg6: 104 case DW_OP_breg7: 105 case DW_OP_breg8: 106 case DW_OP_breg9: 107 case DW_OP_breg10: 108 case DW_OP_breg11: 109 case DW_OP_breg12: 110 case DW_OP_breg13: 111 case DW_OP_breg14: 112 case DW_OP_breg15: 113 case DW_OP_breg16: 114 case DW_OP_breg17: 115 case DW_OP_breg18: 116 case DW_OP_breg19: 117 case DW_OP_breg20: 118 case DW_OP_breg21: 119 case DW_OP_breg22: 120 case DW_OP_breg23: 121 case DW_OP_breg24: 122 case DW_OP_breg25: 123 case DW_OP_breg26: 124 case DW_OP_breg27: 125 case DW_OP_breg28: 126 case DW_OP_breg29: 127 case DW_OP_breg30: 128 case DW_OP_breg31: 129 size = -128; break; 130 case DW_OP_pick: 131 size = 1; break; 132 case DW_OP_deref_size: 133 size = 1; break; 134 case DW_OP_xderef_size: 135 size = 1; break; 136 case DW_OP_plus_uconst: 137 size = 128; break; 138 case DW_OP_skip: 139 size = -2; break; 140 case DW_OP_bra: 141 size = -2; break; 142 case DW_OP_call2: 143 size = 2; break; 144 case DW_OP_call4: 145 size = 4; break; 146 case DW_OP_call_ref: 147 size = dwarf_ref_size; break; 148 case DW_OP_piece: 149 size = 128; break; 150 case DW_OP_regx: 151 size = 128; break; 152 default: 153 s.Printf("UNKNOWN ONE-OPERAND OPCODE, #%u", opcode); 154 return 1; 155 } 156 157 switch (size) 158 { 159 case -1: sint = (int8_t) data.GetU8(offset_ptr); s.Printf("%+" PRIi64, sint); break; 160 case -2: sint = (int16_t) data.GetU16(offset_ptr); s.Printf("%+" PRIi64, sint); break; 161 case -4: sint = (int32_t) data.GetU32(offset_ptr); s.Printf("%+" PRIi64, sint); break; 162 case -8: sint = (int64_t) data.GetU64(offset_ptr); s.Printf("%+" PRIi64, sint); break; 163 case -128: sint = data.GetSLEB128(offset_ptr); s.Printf("%+" PRIi64, sint); break; 164 case 1: uint = data.GetU8(offset_ptr); s.Printf("0x%2.2" PRIx64, uint); break; 165 case 2: uint = data.GetU16(offset_ptr); s.Printf("0x%4.4" PRIx64, uint); break; 166 case 4: uint = data.GetU32(offset_ptr); s.Printf("0x%8.8" PRIx64, uint); break; 167 case 8: uint = data.GetU64(offset_ptr); s.Printf("0x%16.16" PRIx64, uint); break; 168 case 128: uint = data.GetULEB128(offset_ptr); s.Printf("0x%" PRIx64, uint); break; 169 } 170 171 return 0; 172 } 173