|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * |
|
5 * This program is free software: you can redistribute it and/or modify |
|
6 * it under the terms of the GNU Lesser General Public License as published by |
|
7 * the Free Software Foundation, either version 3 of the License, or |
|
8 * (at your option) any later version. |
|
9 * |
|
10 * This program is distributed in the hope that it will be useful, |
|
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
13 * GNU Lesser General Public License for more details. |
|
14 * |
|
15 * You should have received a copy of the GNU Lesser General Public License |
|
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
17 */ |
|
18 |
|
19 #include <iostream> |
|
20 #include "dwarfmanager.h" |
|
21 |
|
22 void EditLocationExpression (Dwarf_Byte_Ptr data, unsigned int pointer_size, unsigned long length, FileShdrPair & aPair) |
|
23 { |
|
24 unsigned op; |
|
25 size_t bytes_read; |
|
26 Dwarf_Byte_Ptr end = data + length; |
|
27 |
|
28 while (data < end){ |
|
29 op = *data++; |
|
30 |
|
31 switch (op){ |
|
32 case DW_OP_addr: |
|
33 LinearAddr addr = READ_UNALIGNED4(data); |
|
34 LinearAddr relocatedAddr = aPair.iXIPFileDetails.Relocate(addr); |
|
35 WRITE_UNALIGNED4(data, relocatedAddr); |
|
36 data += pointer_size; |
|
37 break; |
|
38 case DW_OP_deref: |
|
39 break; |
|
40 case DW_OP_const1u: |
|
41 case DW_OP_const1s: |
|
42 data++; |
|
43 break; |
|
44 case DW_OP_const2u: |
|
45 case DW_OP_const2s: |
|
46 data += 2; |
|
47 break; |
|
48 case DW_OP_const4u: |
|
49 case DW_OP_const4s: |
|
50 data += 4; |
|
51 break; |
|
52 case DW_OP_const8u: |
|
53 case DW_OP_const8s: |
|
54 data += 8; |
|
55 break; |
|
56 case DW_OP_constu: |
|
57 case DW_OP_consts: |
|
58 { |
|
59 ULEB128(data, bytes_read); |
|
60 break; |
|
61 } |
|
62 case DW_OP_dup: |
|
63 case DW_OP_drop: |
|
64 case DW_OP_over: |
|
65 break; |
|
66 case DW_OP_pick: |
|
67 data++; |
|
68 break; |
|
69 case DW_OP_swap: |
|
70 case DW_OP_rot: |
|
71 case DW_OP_xderef: |
|
72 case DW_OP_abs: |
|
73 case DW_OP_and: |
|
74 case DW_OP_div: |
|
75 case DW_OP_minus: |
|
76 case DW_OP_mod: |
|
77 case DW_OP_mul: |
|
78 case DW_OP_neg: |
|
79 case DW_OP_not: |
|
80 case DW_OP_or: |
|
81 case DW_OP_plus: |
|
82 break; |
|
83 case DW_OP_plus_uconst: |
|
84 { |
|
85 ULEB128(data, bytes_read); |
|
86 break; |
|
87 } |
|
88 case DW_OP_shl: |
|
89 case DW_OP_shr: |
|
90 case DW_OP_shra: |
|
91 case DW_OP_xor: |
|
92 break; |
|
93 case DW_OP_bra: |
|
94 data += 2; |
|
95 break; |
|
96 case DW_OP_eq: |
|
97 case DW_OP_ge: |
|
98 case DW_OP_gt: |
|
99 case DW_OP_le: |
|
100 case DW_OP_lt: |
|
101 case DW_OP_ne: |
|
102 break; |
|
103 case DW_OP_skip: |
|
104 data += 2; |
|
105 break; |
|
106 |
|
107 case DW_OP_lit0: |
|
108 case DW_OP_lit1: |
|
109 case DW_OP_lit2: |
|
110 case DW_OP_lit3: |
|
111 case DW_OP_lit4: |
|
112 case DW_OP_lit5: |
|
113 case DW_OP_lit6: |
|
114 case DW_OP_lit7: |
|
115 case DW_OP_lit8: |
|
116 case DW_OP_lit9: |
|
117 case DW_OP_lit10: |
|
118 case DW_OP_lit11: |
|
119 case DW_OP_lit12: |
|
120 case DW_OP_lit13: |
|
121 case DW_OP_lit14: |
|
122 case DW_OP_lit15: |
|
123 case DW_OP_lit16: |
|
124 case DW_OP_lit17: |
|
125 case DW_OP_lit18: |
|
126 case DW_OP_lit19: |
|
127 case DW_OP_lit20: |
|
128 case DW_OP_lit21: |
|
129 case DW_OP_lit22: |
|
130 case DW_OP_lit23: |
|
131 case DW_OP_lit24: |
|
132 case DW_OP_lit25: |
|
133 case DW_OP_lit26: |
|
134 case DW_OP_lit27: |
|
135 case DW_OP_lit28: |
|
136 case DW_OP_lit29: |
|
137 case DW_OP_lit30: |
|
138 case DW_OP_lit31: |
|
139 break; |
|
140 |
|
141 case DW_OP_reg0: |
|
142 case DW_OP_reg1: |
|
143 case DW_OP_reg2: |
|
144 case DW_OP_reg3: |
|
145 case DW_OP_reg4: |
|
146 case DW_OP_reg5: |
|
147 case DW_OP_reg6: |
|
148 case DW_OP_reg7: |
|
149 case DW_OP_reg8: |
|
150 case DW_OP_reg9: |
|
151 case DW_OP_reg10: |
|
152 case DW_OP_reg11: |
|
153 case DW_OP_reg12: |
|
154 case DW_OP_reg13: |
|
155 case DW_OP_reg14: |
|
156 case DW_OP_reg15: |
|
157 case DW_OP_reg16: |
|
158 case DW_OP_reg17: |
|
159 case DW_OP_reg18: |
|
160 case DW_OP_reg19: |
|
161 case DW_OP_reg20: |
|
162 case DW_OP_reg21: |
|
163 case DW_OP_reg22: |
|
164 case DW_OP_reg23: |
|
165 case DW_OP_reg24: |
|
166 case DW_OP_reg25: |
|
167 case DW_OP_reg26: |
|
168 case DW_OP_reg27: |
|
169 case DW_OP_reg28: |
|
170 case DW_OP_reg29: |
|
171 case DW_OP_reg30: |
|
172 case DW_OP_reg31: |
|
173 break; |
|
174 |
|
175 case DW_OP_breg0: |
|
176 case DW_OP_breg1: |
|
177 case DW_OP_breg2: |
|
178 case DW_OP_breg3: |
|
179 case DW_OP_breg4: |
|
180 case DW_OP_breg5: |
|
181 case DW_OP_breg6: |
|
182 case DW_OP_breg7: |
|
183 case DW_OP_breg8: |
|
184 case DW_OP_breg9: |
|
185 case DW_OP_breg10: |
|
186 case DW_OP_breg11: |
|
187 case DW_OP_breg12: |
|
188 case DW_OP_breg13: |
|
189 case DW_OP_breg14: |
|
190 case DW_OP_breg15: |
|
191 case DW_OP_breg16: |
|
192 case DW_OP_breg17: |
|
193 case DW_OP_breg18: |
|
194 case DW_OP_breg19: |
|
195 case DW_OP_breg20: |
|
196 case DW_OP_breg21: |
|
197 case DW_OP_breg22: |
|
198 case DW_OP_breg23: |
|
199 case DW_OP_breg24: |
|
200 case DW_OP_breg25: |
|
201 case DW_OP_breg26: |
|
202 case DW_OP_breg27: |
|
203 case DW_OP_breg28: |
|
204 case DW_OP_breg29: |
|
205 case DW_OP_breg30: |
|
206 case DW_OP_breg31: |
|
207 case DW_OP_fbreg: |
|
208 { |
|
209 ULEB128(data, bytes_read); |
|
210 break; |
|
211 } |
|
212 case DW_OP_bregx: |
|
213 { |
|
214 ULEB128(data, bytes_read); |
|
215 ULEB128(data, bytes_read); |
|
216 break; |
|
217 } |
|
218 case DW_OP_piece: |
|
219 { |
|
220 ULEB128(data, bytes_read); |
|
221 break; |
|
222 } |
|
223 case DW_OP_deref_size: |
|
224 case DW_OP_xderef_size: |
|
225 data++; |
|
226 break; |
|
227 case DW_OP_nop: |
|
228 /* DWARF 3 extensions. */ |
|
229 case DW_OP_push_object_address: |
|
230 break; |
|
231 case DW_OP_call2: |
|
232 /* XXX: Strictly speaking for 64-bit DWARF3 files |
|
233 this ought to be an 8-byte wide computation. */ |
|
234 data += 2; |
|
235 break; |
|
236 case DW_OP_call4: |
|
237 /* XXX: Strictly speaking for 64-bit DWARF3 files |
|
238 this ought to be an 8-byte wide computation. */ |
|
239 data += 4; |
|
240 break; |
|
241 case DW_OP_call_ref: |
|
242 /* XXX: Strictly speaking for 64-bit DWARF3 files |
|
243 this ought to be an 8-byte wide computation. */ |
|
244 data += 4; |
|
245 break; |
|
246 case DW_OP_form_tls_address: |
|
247 case DW_OP_call_frame_cfa: |
|
248 break; |
|
249 case DW_OP_bit_piece: |
|
250 { |
|
251 // Handily the spec doesn't describe the operands - but by analogy with |
|
252 // DW_OP_piece we assume these are ULEB128 encoded. |
|
253 ULEB128(data, bytes_read); |
|
254 ULEB128(data, bytes_read); |
|
255 break; |
|
256 } |
|
257 |
|
258 /* GNU extensions. */ |
|
259 case DW_OP_GNU_push_tls_address: |
|
260 //case DW_OP_GNU_uninit: |
|
261 /* FIXME: Is there data associated with this OP ? */ |
|
262 break; |
|
263 |
|
264 default: |
|
265 // bail - can't do anything else sensible here |
|
266 cerr << "Warning: Unrecognized opcode " << op << " in Dwarf expression.\n"; |
|
267 return; |
|
268 } |
|
269 |
|
270 } |
|
271 } |