]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.cpp
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / llvm / tools / lldb / source / Plugins / SymbolFile / DWARF / DWARFLocationDescription.cpp
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 }