1254721Semaste//===-- DWARFLocationDescription.cpp ----------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "DWARFLocationDescription.h" 11254721Semaste#include "DWARFDefines.h" 12254721Semaste#include "lldb/lldb-private.h" 13254721Semaste#include "lldb/Core/Stream.h" 14254721Semaste 15254721Semaste 16254721Semasteusing namespace lldb_private; 17254721Semaste 18263363Semastestatic int print_dwarf_exp_op (Stream &s, const DWARFDataExtractor& data, lldb::offset_t *offset_ptr, int address_size, int dwarf_ref_size); 19254721Semaste 20254721Semasteint 21254721Semasteprint_dwarf_expression (Stream &s, 22263363Semaste const DWARFDataExtractor& data, 23254721Semaste int address_size, 24254721Semaste int dwarf_ref_size, 25254721Semaste bool location_expression) 26254721Semaste{ 27254721Semaste int op_count = 0; 28254721Semaste lldb::offset_t offset = 0; 29254721Semaste while (data.ValidOffset(offset)) 30254721Semaste { 31254721Semaste if (location_expression && op_count > 0) 32254721Semaste { 33254721Semaste // err (baton, "Dwarf location expressions may only have one operand!"); 34254721Semaste return 1; 35254721Semaste } 36254721Semaste if (op_count > 0) 37254721Semaste { 38254721Semaste s.PutCString(", "); 39254721Semaste } 40254721Semaste if (print_dwarf_exp_op (s, data, &offset, address_size, dwarf_ref_size) == 1) 41254721Semaste return 1; 42254721Semaste op_count++; 43254721Semaste } 44254721Semaste 45254721Semaste return 0; 46254721Semaste} 47254721Semaste 48254721Semastestatic int 49254721Semasteprint_dwarf_exp_op (Stream &s, 50263363Semaste const DWARFDataExtractor& data, 51254721Semaste lldb::offset_t *offset_ptr, 52254721Semaste int address_size, 53254721Semaste int dwarf_ref_size) 54254721Semaste{ 55254721Semaste uint8_t opcode = data.GetU8(offset_ptr); 56254721Semaste DRC_class opcode_class; 57254721Semaste uint64_t uint; 58254721Semaste int64_t sint; 59254721Semaste 60254721Semaste int size; 61254721Semaste 62254721Semaste opcode_class = DW_OP_value_to_class (opcode) & (~DRC_DWARFv3); 63254721Semaste 64254721Semaste s.Printf("%s ", DW_OP_value_to_name (opcode)); 65254721Semaste 66254721Semaste /* Does this take zero parameters? If so we can shortcut this function. */ 67254721Semaste if (opcode_class == DRC_ZEROOPERANDS) 68254721Semaste return 0; 69254721Semaste 70254721Semaste if (opcode_class == DRC_TWOOPERANDS && opcode == DW_OP_bregx) 71254721Semaste { 72254721Semaste uint = data.GetULEB128(offset_ptr); 73254721Semaste sint = data.GetSLEB128(offset_ptr); 74254721Semaste s.Printf("%" PRIu64 " %" PRIi64, uint, sint); 75254721Semaste return 0; 76254721Semaste } 77254721Semaste if (opcode_class != DRC_ONEOPERAND) 78254721Semaste { 79254721Semaste s.Printf("UNKNOWN OP %u", opcode); 80254721Semaste return 1; 81254721Semaste } 82254721Semaste 83254721Semaste switch (opcode) 84254721Semaste { 85254721Semaste case DW_OP_addr: size = address_size; break; 86254721Semaste case DW_OP_const1u: size = 1; break; 87254721Semaste case DW_OP_const1s: size = -1; break; 88254721Semaste case DW_OP_const2u: size = 2; break; 89254721Semaste case DW_OP_const2s: size = -2; break; 90254721Semaste case DW_OP_const4u: size = 4; break; 91254721Semaste case DW_OP_const4s: size = -4; break; 92254721Semaste case DW_OP_const8u: size = 8; break; 93254721Semaste case DW_OP_const8s: size = -8; break; 94254721Semaste case DW_OP_constu: size = 128; break; 95254721Semaste case DW_OP_consts: size = -128; break; 96254721Semaste case DW_OP_fbreg: size = -128; break; 97254721Semaste case DW_OP_breg0: 98254721Semaste case DW_OP_breg1: 99254721Semaste case DW_OP_breg2: 100254721Semaste case DW_OP_breg3: 101254721Semaste case DW_OP_breg4: 102254721Semaste case DW_OP_breg5: 103254721Semaste case DW_OP_breg6: 104254721Semaste case DW_OP_breg7: 105254721Semaste case DW_OP_breg8: 106254721Semaste case DW_OP_breg9: 107254721Semaste case DW_OP_breg10: 108254721Semaste case DW_OP_breg11: 109254721Semaste case DW_OP_breg12: 110254721Semaste case DW_OP_breg13: 111254721Semaste case DW_OP_breg14: 112254721Semaste case DW_OP_breg15: 113254721Semaste case DW_OP_breg16: 114254721Semaste case DW_OP_breg17: 115254721Semaste case DW_OP_breg18: 116254721Semaste case DW_OP_breg19: 117254721Semaste case DW_OP_breg20: 118254721Semaste case DW_OP_breg21: 119254721Semaste case DW_OP_breg22: 120254721Semaste case DW_OP_breg23: 121254721Semaste case DW_OP_breg24: 122254721Semaste case DW_OP_breg25: 123254721Semaste case DW_OP_breg26: 124254721Semaste case DW_OP_breg27: 125254721Semaste case DW_OP_breg28: 126254721Semaste case DW_OP_breg29: 127254721Semaste case DW_OP_breg30: 128254721Semaste case DW_OP_breg31: 129254721Semaste size = -128; break; 130254721Semaste case DW_OP_pick: 131254721Semaste size = 1; break; 132254721Semaste case DW_OP_deref_size: 133254721Semaste size = 1; break; 134254721Semaste case DW_OP_xderef_size: 135254721Semaste size = 1; break; 136254721Semaste case DW_OP_plus_uconst: 137254721Semaste size = 128; break; 138254721Semaste case DW_OP_skip: 139254721Semaste size = -2; break; 140254721Semaste case DW_OP_bra: 141254721Semaste size = -2; break; 142254721Semaste case DW_OP_call2: 143254721Semaste size = 2; break; 144254721Semaste case DW_OP_call4: 145254721Semaste size = 4; break; 146254721Semaste case DW_OP_call_ref: 147254721Semaste size = dwarf_ref_size; break; 148254721Semaste case DW_OP_piece: 149254721Semaste size = 128; break; 150254721Semaste case DW_OP_regx: 151254721Semaste size = 128; break; 152254721Semaste default: 153254721Semaste s.Printf("UNKNOWN ONE-OPERAND OPCODE, #%u", opcode); 154254721Semaste return 1; 155254721Semaste } 156254721Semaste 157254721Semaste switch (size) 158254721Semaste { 159254721Semaste case -1: sint = (int8_t) data.GetU8(offset_ptr); s.Printf("%+" PRIi64, sint); break; 160254721Semaste case -2: sint = (int16_t) data.GetU16(offset_ptr); s.Printf("%+" PRIi64, sint); break; 161254721Semaste case -4: sint = (int32_t) data.GetU32(offset_ptr); s.Printf("%+" PRIi64, sint); break; 162254721Semaste case -8: sint = (int64_t) data.GetU64(offset_ptr); s.Printf("%+" PRIi64, sint); break; 163254721Semaste case -128: sint = data.GetSLEB128(offset_ptr); s.Printf("%+" PRIi64, sint); break; 164254721Semaste case 1: uint = data.GetU8(offset_ptr); s.Printf("0x%2.2" PRIx64, uint); break; 165254721Semaste case 2: uint = data.GetU16(offset_ptr); s.Printf("0x%4.4" PRIx64, uint); break; 166254721Semaste case 4: uint = data.GetU32(offset_ptr); s.Printf("0x%8.8" PRIx64, uint); break; 167254721Semaste case 8: uint = data.GetU64(offset_ptr); s.Printf("0x%16.16" PRIx64, uint); break; 168254721Semaste case 128: uint = data.GetULEB128(offset_ptr); s.Printf("0x%" PRIx64, uint); break; 169254721Semaste } 170254721Semaste 171254721Semaste return 0; 172254721Semaste} 173