1 | //===-- ABISysV_hexagon.cpp -----------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "ABISysV_hexagon.h" |
10 | |
11 | #include "llvm/IR/DerivedTypes.h" |
12 | #include "llvm/TargetParser/Triple.h" |
13 | |
14 | #include "lldb/Core/Module.h" |
15 | #include "lldb/Core/PluginManager.h" |
16 | #include "lldb/Core/Value.h" |
17 | #include "lldb/Core/ValueObjectConstResult.h" |
18 | #include "lldb/Core/ValueObjectMemory.h" |
19 | #include "lldb/Core/ValueObjectRegister.h" |
20 | #include "lldb/Symbol/UnwindPlan.h" |
21 | #include "lldb/Target/Process.h" |
22 | #include "lldb/Target/RegisterContext.h" |
23 | #include "lldb/Target/StackFrame.h" |
24 | #include "lldb/Target/Target.h" |
25 | #include "lldb/Target/Thread.h" |
26 | #include "lldb/Utility/ConstString.h" |
27 | #include "lldb/Utility/DataExtractor.h" |
28 | #include "lldb/Utility/Log.h" |
29 | #include "lldb/Utility/RegisterValue.h" |
30 | #include "lldb/Utility/Status.h" |
31 | |
32 | using namespace lldb; |
33 | using namespace lldb_private; |
34 | |
35 | LLDB_PLUGIN_DEFINE_ADV(ABISysV_hexagon, ABIHexagon) |
36 | |
37 | static const RegisterInfo g_register_infos[] = { |
38 | // hexagon-core.xml |
39 | {.name: "r00" , |
40 | .alt_name: "" , |
41 | .byte_size: 4, |
42 | .byte_offset: 0, |
43 | .encoding: eEncodingUint, |
44 | .format: eFormatAddressInfo, |
45 | .kinds: {0, 0, LLDB_INVALID_REGNUM, 0, 0}, |
46 | .value_regs: nullptr, |
47 | .invalidate_regs: nullptr, |
48 | .flags_type: nullptr, |
49 | }, |
50 | {.name: "r01" , |
51 | .alt_name: "" , |
52 | .byte_size: 4, |
53 | .byte_offset: 0, |
54 | .encoding: eEncodingUint, |
55 | .format: eFormatAddressInfo, |
56 | .kinds: {1, 1, LLDB_INVALID_REGNUM, 1, 1}, |
57 | .value_regs: nullptr, |
58 | .invalidate_regs: nullptr, |
59 | .flags_type: nullptr, |
60 | }, |
61 | {.name: "r02" , |
62 | .alt_name: "" , |
63 | .byte_size: 4, |
64 | .byte_offset: 0, |
65 | .encoding: eEncodingUint, |
66 | .format: eFormatAddressInfo, |
67 | .kinds: {2, 2, LLDB_INVALID_REGNUM, 2, 2}, |
68 | .value_regs: nullptr, |
69 | .invalidate_regs: nullptr, |
70 | .flags_type: nullptr, |
71 | }, |
72 | {.name: "r03" , |
73 | .alt_name: "" , |
74 | .byte_size: 4, |
75 | .byte_offset: 0, |
76 | .encoding: eEncodingUint, |
77 | .format: eFormatAddressInfo, |
78 | .kinds: {3, 3, LLDB_INVALID_REGNUM, 3, 3}, |
79 | .value_regs: nullptr, |
80 | .invalidate_regs: nullptr, |
81 | .flags_type: nullptr, |
82 | }, |
83 | {.name: "r04" , |
84 | .alt_name: "" , |
85 | .byte_size: 4, |
86 | .byte_offset: 0, |
87 | .encoding: eEncodingUint, |
88 | .format: eFormatAddressInfo, |
89 | .kinds: {4, 4, LLDB_INVALID_REGNUM, 4, 4}, |
90 | .value_regs: nullptr, |
91 | .invalidate_regs: nullptr, |
92 | .flags_type: nullptr, |
93 | }, |
94 | {.name: "r05" , |
95 | .alt_name: "" , |
96 | .byte_size: 4, |
97 | .byte_offset: 0, |
98 | .encoding: eEncodingUint, |
99 | .format: eFormatAddressInfo, |
100 | .kinds: {5, 5, LLDB_INVALID_REGNUM, 5, 5}, |
101 | .value_regs: nullptr, |
102 | .invalidate_regs: nullptr, |
103 | .flags_type: nullptr, |
104 | }, |
105 | {.name: "r06" , |
106 | .alt_name: "" , |
107 | .byte_size: 4, |
108 | .byte_offset: 0, |
109 | .encoding: eEncodingUint, |
110 | .format: eFormatAddressInfo, |
111 | .kinds: {6, 6, LLDB_INVALID_REGNUM, 6, 6}, |
112 | .value_regs: nullptr, |
113 | .invalidate_regs: nullptr, |
114 | .flags_type: nullptr, |
115 | }, |
116 | {.name: "r07" , |
117 | .alt_name: "" , |
118 | .byte_size: 4, |
119 | .byte_offset: 0, |
120 | .encoding: eEncodingUint, |
121 | .format: eFormatAddressInfo, |
122 | .kinds: {7, 7, LLDB_INVALID_REGNUM, 7, 7}, |
123 | .value_regs: nullptr, |
124 | .invalidate_regs: nullptr, |
125 | .flags_type: nullptr, |
126 | }, |
127 | {.name: "r08" , |
128 | .alt_name: "" , |
129 | .byte_size: 4, |
130 | .byte_offset: 0, |
131 | .encoding: eEncodingUint, |
132 | .format: eFormatAddressInfo, |
133 | .kinds: {8, 8, LLDB_INVALID_REGNUM, 8, 8}, |
134 | .value_regs: nullptr, |
135 | .invalidate_regs: nullptr, |
136 | .flags_type: nullptr, |
137 | }, |
138 | {.name: "r09" , |
139 | .alt_name: "" , |
140 | .byte_size: 4, |
141 | .byte_offset: 0, |
142 | .encoding: eEncodingUint, |
143 | .format: eFormatAddressInfo, |
144 | .kinds: {9, 9, LLDB_INVALID_REGNUM, 9, 9}, |
145 | .value_regs: nullptr, |
146 | .invalidate_regs: nullptr, |
147 | .flags_type: nullptr, |
148 | }, |
149 | {.name: "r10" , |
150 | .alt_name: "" , |
151 | .byte_size: 4, |
152 | .byte_offset: 0, |
153 | .encoding: eEncodingUint, |
154 | .format: eFormatAddressInfo, |
155 | .kinds: {10, 10, LLDB_INVALID_REGNUM, 10, 10}, |
156 | .value_regs: nullptr, |
157 | .invalidate_regs: nullptr, |
158 | .flags_type: nullptr, |
159 | }, |
160 | {.name: "r11" , |
161 | .alt_name: "" , |
162 | .byte_size: 4, |
163 | .byte_offset: 0, |
164 | .encoding: eEncodingUint, |
165 | .format: eFormatAddressInfo, |
166 | .kinds: {11, 11, LLDB_INVALID_REGNUM, 11, 11}, |
167 | .value_regs: nullptr, |
168 | .invalidate_regs: nullptr, |
169 | .flags_type: nullptr, |
170 | }, |
171 | {.name: "r12" , |
172 | .alt_name: "" , |
173 | .byte_size: 4, |
174 | .byte_offset: 0, |
175 | .encoding: eEncodingUint, |
176 | .format: eFormatAddressInfo, |
177 | .kinds: {12, 12, LLDB_INVALID_REGNUM, 12, 12}, |
178 | .value_regs: nullptr, |
179 | .invalidate_regs: nullptr, |
180 | .flags_type: nullptr, |
181 | }, |
182 | {.name: "r13" , |
183 | .alt_name: "" , |
184 | .byte_size: 4, |
185 | .byte_offset: 0, |
186 | .encoding: eEncodingUint, |
187 | .format: eFormatAddressInfo, |
188 | .kinds: {13, 13, LLDB_INVALID_REGNUM, 13, 13}, |
189 | .value_regs: nullptr, |
190 | .invalidate_regs: nullptr, |
191 | .flags_type: nullptr, |
192 | }, |
193 | {.name: "r14" , |
194 | .alt_name: "" , |
195 | .byte_size: 4, |
196 | .byte_offset: 0, |
197 | .encoding: eEncodingUint, |
198 | .format: eFormatAddressInfo, |
199 | .kinds: {14, 14, LLDB_INVALID_REGNUM, 14, 14}, |
200 | .value_regs: nullptr, |
201 | .invalidate_regs: nullptr, |
202 | .flags_type: nullptr, |
203 | }, |
204 | {.name: "r15" , |
205 | .alt_name: "" , |
206 | .byte_size: 4, |
207 | .byte_offset: 0, |
208 | .encoding: eEncodingUint, |
209 | .format: eFormatAddressInfo, |
210 | .kinds: {15, 15, LLDB_INVALID_REGNUM, 15, 15}, |
211 | .value_regs: nullptr, |
212 | .invalidate_regs: nullptr, |
213 | .flags_type: nullptr, |
214 | }, |
215 | {.name: "r16" , |
216 | .alt_name: "" , |
217 | .byte_size: 4, |
218 | .byte_offset: 0, |
219 | .encoding: eEncodingUint, |
220 | .format: eFormatAddressInfo, |
221 | .kinds: {16, 16, LLDB_INVALID_REGNUM, 16, 16}, |
222 | .value_regs: nullptr, |
223 | .invalidate_regs: nullptr, |
224 | .flags_type: nullptr, |
225 | }, |
226 | {.name: "r17" , |
227 | .alt_name: "" , |
228 | .byte_size: 4, |
229 | .byte_offset: 0, |
230 | .encoding: eEncodingUint, |
231 | .format: eFormatAddressInfo, |
232 | .kinds: {17, 17, LLDB_INVALID_REGNUM, 17, 17}, |
233 | .value_regs: nullptr, |
234 | .invalidate_regs: nullptr, |
235 | .flags_type: nullptr, |
236 | }, |
237 | {.name: "r18" , |
238 | .alt_name: "" , |
239 | .byte_size: 4, |
240 | .byte_offset: 0, |
241 | .encoding: eEncodingUint, |
242 | .format: eFormatAddressInfo, |
243 | .kinds: {18, 18, LLDB_INVALID_REGNUM, 18, 18}, |
244 | .value_regs: nullptr, |
245 | .invalidate_regs: nullptr, |
246 | .flags_type: nullptr, |
247 | }, |
248 | {.name: "r19" , |
249 | .alt_name: "" , |
250 | .byte_size: 4, |
251 | .byte_offset: 0, |
252 | .encoding: eEncodingUint, |
253 | .format: eFormatAddressInfo, |
254 | .kinds: {19, 19, LLDB_INVALID_REGNUM, 19, 19}, |
255 | .value_regs: nullptr, |
256 | .invalidate_regs: nullptr, |
257 | .flags_type: nullptr, |
258 | }, |
259 | {.name: "r20" , |
260 | .alt_name: "" , |
261 | .byte_size: 4, |
262 | .byte_offset: 0, |
263 | .encoding: eEncodingUint, |
264 | .format: eFormatAddressInfo, |
265 | .kinds: {20, 20, LLDB_INVALID_REGNUM, 20, 20}, |
266 | .value_regs: nullptr, |
267 | .invalidate_regs: nullptr, |
268 | .flags_type: nullptr, |
269 | }, |
270 | {.name: "r21" , |
271 | .alt_name: "" , |
272 | .byte_size: 4, |
273 | .byte_offset: 0, |
274 | .encoding: eEncodingUint, |
275 | .format: eFormatAddressInfo, |
276 | .kinds: {21, 21, LLDB_INVALID_REGNUM, 21, 21}, |
277 | .value_regs: nullptr, |
278 | .invalidate_regs: nullptr, |
279 | .flags_type: nullptr, |
280 | }, |
281 | {.name: "r22" , |
282 | .alt_name: "" , |
283 | .byte_size: 4, |
284 | .byte_offset: 0, |
285 | .encoding: eEncodingUint, |
286 | .format: eFormatAddressInfo, |
287 | .kinds: {22, 22, LLDB_INVALID_REGNUM, 22, 22}, |
288 | .value_regs: nullptr, |
289 | .invalidate_regs: nullptr, |
290 | .flags_type: nullptr, |
291 | }, |
292 | {.name: "r23" , |
293 | .alt_name: "" , |
294 | .byte_size: 4, |
295 | .byte_offset: 0, |
296 | .encoding: eEncodingUint, |
297 | .format: eFormatAddressInfo, |
298 | .kinds: {23, 23, LLDB_INVALID_REGNUM, 23, 23}, |
299 | .value_regs: nullptr, |
300 | .invalidate_regs: nullptr, |
301 | .flags_type: nullptr, |
302 | }, |
303 | {.name: "r24" , |
304 | .alt_name: "" , |
305 | .byte_size: 4, |
306 | .byte_offset: 0, |
307 | .encoding: eEncodingUint, |
308 | .format: eFormatAddressInfo, |
309 | .kinds: {24, 24, LLDB_INVALID_REGNUM, 24, 24}, |
310 | .value_regs: nullptr, |
311 | .invalidate_regs: nullptr, |
312 | .flags_type: nullptr, |
313 | }, |
314 | {.name: "r25" , |
315 | .alt_name: "" , |
316 | .byte_size: 4, |
317 | .byte_offset: 0, |
318 | .encoding: eEncodingUint, |
319 | .format: eFormatAddressInfo, |
320 | .kinds: {25, 25, LLDB_INVALID_REGNUM, 25, 25}, |
321 | .value_regs: nullptr, |
322 | .invalidate_regs: nullptr, |
323 | .flags_type: nullptr, |
324 | }, |
325 | {.name: "r26" , |
326 | .alt_name: "" , |
327 | .byte_size: 4, |
328 | .byte_offset: 0, |
329 | .encoding: eEncodingUint, |
330 | .format: eFormatAddressInfo, |
331 | .kinds: {26, 26, LLDB_INVALID_REGNUM, 26, 26}, |
332 | .value_regs: nullptr, |
333 | .invalidate_regs: nullptr, |
334 | .flags_type: nullptr, |
335 | }, |
336 | {.name: "r27" , |
337 | .alt_name: "" , |
338 | .byte_size: 4, |
339 | .byte_offset: 0, |
340 | .encoding: eEncodingUint, |
341 | .format: eFormatAddressInfo, |
342 | .kinds: {27, 27, LLDB_INVALID_REGNUM, 27, 27}, |
343 | .value_regs: nullptr, |
344 | .invalidate_regs: nullptr, |
345 | .flags_type: nullptr, |
346 | }, |
347 | {.name: "r28" , |
348 | .alt_name: "" , |
349 | .byte_size: 4, |
350 | .byte_offset: 0, |
351 | .encoding: eEncodingUint, |
352 | .format: eFormatAddressInfo, |
353 | .kinds: {28, 28, LLDB_INVALID_REGNUM, 28, 28}, |
354 | .value_regs: nullptr, |
355 | .invalidate_regs: nullptr, |
356 | .flags_type: nullptr, |
357 | }, |
358 | {.name: "sp" , |
359 | .alt_name: "r29" , |
360 | .byte_size: 4, |
361 | .byte_offset: 0, |
362 | .encoding: eEncodingUint, |
363 | .format: eFormatAddressInfo, |
364 | .kinds: {29, 29, LLDB_REGNUM_GENERIC_SP, 29, 29}, |
365 | .value_regs: nullptr, |
366 | .invalidate_regs: nullptr, |
367 | .flags_type: nullptr, |
368 | }, |
369 | {.name: "fp" , |
370 | .alt_name: "r30" , |
371 | .byte_size: 4, |
372 | .byte_offset: 0, |
373 | .encoding: eEncodingUint, |
374 | .format: eFormatAddressInfo, |
375 | .kinds: {30, 30, LLDB_REGNUM_GENERIC_FP, 30, 30}, |
376 | .value_regs: nullptr, |
377 | .invalidate_regs: nullptr, |
378 | .flags_type: nullptr, |
379 | }, |
380 | {.name: "lr" , |
381 | .alt_name: "r31" , |
382 | .byte_size: 4, |
383 | .byte_offset: 0, |
384 | .encoding: eEncodingUint, |
385 | .format: eFormatAddressInfo, |
386 | .kinds: {31, 31, LLDB_REGNUM_GENERIC_RA, 31, 31}, |
387 | .value_regs: nullptr, |
388 | .invalidate_regs: nullptr, |
389 | .flags_type: nullptr, |
390 | }, |
391 | {.name: "sa0" , |
392 | .alt_name: "" , |
393 | .byte_size: 4, |
394 | .byte_offset: 0, |
395 | .encoding: eEncodingUint, |
396 | .format: eFormatAddressInfo, |
397 | .kinds: {32, 32, LLDB_INVALID_REGNUM, 32, 32}, |
398 | .value_regs: nullptr, |
399 | .invalidate_regs: nullptr, |
400 | .flags_type: nullptr, |
401 | }, |
402 | {.name: "lc0" , |
403 | .alt_name: "" , |
404 | .byte_size: 4, |
405 | .byte_offset: 0, |
406 | .encoding: eEncodingUint, |
407 | .format: eFormatAddressInfo, |
408 | .kinds: {33, 33, LLDB_INVALID_REGNUM, 33, 33}, |
409 | .value_regs: nullptr, |
410 | .invalidate_regs: nullptr, |
411 | .flags_type: nullptr, |
412 | }, |
413 | {.name: "sa1" , |
414 | .alt_name: "" , |
415 | .byte_size: 4, |
416 | .byte_offset: 0, |
417 | .encoding: eEncodingUint, |
418 | .format: eFormatAddressInfo, |
419 | .kinds: {34, 34, LLDB_INVALID_REGNUM, 34, 34}, |
420 | .value_regs: nullptr, |
421 | .invalidate_regs: nullptr, |
422 | .flags_type: nullptr, |
423 | }, |
424 | {.name: "lc1" , |
425 | .alt_name: "" , |
426 | .byte_size: 4, |
427 | .byte_offset: 0, |
428 | .encoding: eEncodingUint, |
429 | .format: eFormatAddressInfo, |
430 | .kinds: {35, 35, LLDB_INVALID_REGNUM, 35, 35}, |
431 | .value_regs: nullptr, |
432 | .invalidate_regs: nullptr, |
433 | .flags_type: nullptr, |
434 | }, |
435 | // --> hexagon-v4/5/55/56-sim.xml |
436 | {.name: "p3_0" , |
437 | .alt_name: "" , |
438 | .byte_size: 4, |
439 | .byte_offset: 0, |
440 | .encoding: eEncodingUint, |
441 | .format: eFormatAddressInfo, |
442 | .kinds: {36, 36, LLDB_INVALID_REGNUM, 36, 36}, |
443 | .value_regs: nullptr, |
444 | .invalidate_regs: nullptr, |
445 | .flags_type: nullptr, |
446 | |
447 | }, |
448 | // PADDING { |
449 | {.name: "p00" , |
450 | .alt_name: "" , |
451 | .byte_size: 4, |
452 | .byte_offset: 0, |
453 | .encoding: eEncodingInvalid, |
454 | .format: eFormatInvalid, |
455 | .kinds: {37, 37, LLDB_INVALID_REGNUM, 37, 37}, |
456 | .value_regs: nullptr, |
457 | .invalidate_regs: nullptr, |
458 | .flags_type: nullptr, |
459 | }, |
460 | // } |
461 | {.name: "m0" , |
462 | .alt_name: "" , |
463 | .byte_size: 4, |
464 | .byte_offset: 0, |
465 | .encoding: eEncodingUint, |
466 | .format: eFormatAddressInfo, |
467 | .kinds: {38, 38, LLDB_INVALID_REGNUM, 38, 38}, |
468 | .value_regs: nullptr, |
469 | .invalidate_regs: nullptr, |
470 | .flags_type: nullptr, |
471 | }, |
472 | {.name: "m1" , |
473 | .alt_name: "" , |
474 | .byte_size: 4, |
475 | .byte_offset: 0, |
476 | .encoding: eEncodingUint, |
477 | .format: eFormatAddressInfo, |
478 | .kinds: {39, 39, LLDB_INVALID_REGNUM, 39, 39}, |
479 | .value_regs: nullptr, |
480 | .invalidate_regs: nullptr, |
481 | .flags_type: nullptr, |
482 | }, |
483 | {.name: "usr" , |
484 | .alt_name: "" , |
485 | .byte_size: 4, |
486 | .byte_offset: 0, |
487 | .encoding: eEncodingUint, |
488 | .format: eFormatAddressInfo, |
489 | .kinds: {40, 40, LLDB_INVALID_REGNUM, 40, 40}, |
490 | .value_regs: nullptr, |
491 | .invalidate_regs: nullptr, |
492 | .flags_type: nullptr, |
493 | }, |
494 | {.name: "pc" , |
495 | .alt_name: "" , |
496 | .byte_size: 4, |
497 | .byte_offset: 0, |
498 | .encoding: eEncodingUint, |
499 | .format: eFormatAddressInfo, |
500 | .kinds: {41, 41, LLDB_REGNUM_GENERIC_PC, 41, 41}, |
501 | .value_regs: nullptr, |
502 | .invalidate_regs: nullptr, |
503 | .flags_type: nullptr, |
504 | }, |
505 | {.name: "ugp" , |
506 | .alt_name: "" , |
507 | .byte_size: 4, |
508 | .byte_offset: 0, |
509 | .encoding: eEncodingUint, |
510 | .format: eFormatAddressInfo, |
511 | .kinds: {42, 42, LLDB_INVALID_REGNUM, 42, 42}, |
512 | .value_regs: nullptr, |
513 | .invalidate_regs: nullptr, |
514 | .flags_type: nullptr, |
515 | }, |
516 | {.name: "gp" , |
517 | .alt_name: "" , |
518 | .byte_size: 4, |
519 | .byte_offset: 0, |
520 | .encoding: eEncodingUint, |
521 | .format: eFormatAddressInfo, |
522 | .kinds: {43, 43, LLDB_INVALID_REGNUM, 43, 43}, |
523 | .value_regs: nullptr, |
524 | .invalidate_regs: nullptr, |
525 | .flags_type: nullptr, |
526 | }, |
527 | {.name: "cs0" , |
528 | .alt_name: "" , |
529 | .byte_size: 4, |
530 | .byte_offset: 0, |
531 | .encoding: eEncodingUint, |
532 | .format: eFormatAddressInfo, |
533 | .kinds: {44, 44, LLDB_INVALID_REGNUM, 44, 44}, |
534 | .value_regs: nullptr, |
535 | .invalidate_regs: nullptr, |
536 | .flags_type: nullptr, |
537 | }, |
538 | {.name: "cs1" , |
539 | .alt_name: "" , |
540 | .byte_size: 4, |
541 | .byte_offset: 0, |
542 | .encoding: eEncodingUint, |
543 | .format: eFormatAddressInfo, |
544 | .kinds: {45, 45, LLDB_INVALID_REGNUM, 45, 45}, |
545 | .value_regs: nullptr, |
546 | .invalidate_regs: nullptr, |
547 | .flags_type: nullptr, |
548 | }, |
549 | // PADDING { |
550 | {.name: "p01" , |
551 | .alt_name: "" , |
552 | .byte_size: 4, |
553 | .byte_offset: 0, |
554 | .encoding: eEncodingInvalid, |
555 | .format: eFormatInvalid, |
556 | .kinds: {46, 46, LLDB_INVALID_REGNUM, 46, 46}, |
557 | .value_regs: nullptr, |
558 | .invalidate_regs: nullptr, |
559 | .flags_type: nullptr, |
560 | }, |
561 | {.name: "p02" , |
562 | .alt_name: "" , |
563 | .byte_size: 4, |
564 | .byte_offset: 0, |
565 | .encoding: eEncodingInvalid, |
566 | .format: eFormatInvalid, |
567 | .kinds: {47, 47, LLDB_INVALID_REGNUM, 47, 47}, |
568 | .value_regs: nullptr, |
569 | .invalidate_regs: nullptr, |
570 | .flags_type: nullptr, |
571 | }, |
572 | {.name: "p03" , |
573 | .alt_name: "" , |
574 | .byte_size: 4, |
575 | .byte_offset: 0, |
576 | .encoding: eEncodingInvalid, |
577 | .format: eFormatInvalid, |
578 | .kinds: {48, 48, LLDB_INVALID_REGNUM, 48, 48}, |
579 | .value_regs: nullptr, |
580 | .invalidate_regs: nullptr, |
581 | .flags_type: nullptr, |
582 | }, |
583 | {.name: "p04" , |
584 | .alt_name: "" , |
585 | .byte_size: 4, |
586 | .byte_offset: 0, |
587 | .encoding: eEncodingInvalid, |
588 | .format: eFormatInvalid, |
589 | .kinds: {49, 49, LLDB_INVALID_REGNUM, 49, 49}, |
590 | .value_regs: nullptr, |
591 | .invalidate_regs: nullptr, |
592 | .flags_type: nullptr, |
593 | }, |
594 | {.name: "p05" , |
595 | .alt_name: "" , |
596 | .byte_size: 4, |
597 | .byte_offset: 0, |
598 | .encoding: eEncodingInvalid, |
599 | .format: eFormatInvalid, |
600 | .kinds: {50, 50, LLDB_INVALID_REGNUM, 50, 50}, |
601 | .value_regs: nullptr, |
602 | .invalidate_regs: nullptr, |
603 | .flags_type: nullptr, |
604 | }, |
605 | {.name: "p06" , |
606 | .alt_name: "" , |
607 | .byte_size: 4, |
608 | .byte_offset: 0, |
609 | .encoding: eEncodingInvalid, |
610 | .format: eFormatInvalid, |
611 | .kinds: {51, 51, LLDB_INVALID_REGNUM, 51, 51}, |
612 | .value_regs: nullptr, |
613 | .invalidate_regs: nullptr, |
614 | .flags_type: nullptr, |
615 | }, |
616 | {.name: "p07" , |
617 | .alt_name: "" , |
618 | .byte_size: 4, |
619 | .byte_offset: 0, |
620 | .encoding: eEncodingInvalid, |
621 | .format: eFormatInvalid, |
622 | .kinds: {52, 52, LLDB_INVALID_REGNUM, 52, 52}, |
623 | .value_regs: nullptr, |
624 | .invalidate_regs: nullptr, |
625 | .flags_type: nullptr, |
626 | }, |
627 | {.name: "p08" , |
628 | .alt_name: "" , |
629 | .byte_size: 4, |
630 | .byte_offset: 0, |
631 | .encoding: eEncodingInvalid, |
632 | .format: eFormatInvalid, |
633 | .kinds: {53, 53, LLDB_INVALID_REGNUM, 53, 53}, |
634 | .value_regs: nullptr, |
635 | .invalidate_regs: nullptr, |
636 | .flags_type: nullptr, |
637 | }, |
638 | {.name: "p09" , |
639 | .alt_name: "" , |
640 | .byte_size: 4, |
641 | .byte_offset: 0, |
642 | .encoding: eEncodingInvalid, |
643 | .format: eFormatInvalid, |
644 | .kinds: {54, 54, LLDB_INVALID_REGNUM, 54, 54}, |
645 | .value_regs: nullptr, |
646 | .invalidate_regs: nullptr, |
647 | .flags_type: nullptr, |
648 | }, |
649 | {.name: "p10" , |
650 | .alt_name: "" , |
651 | .byte_size: 4, |
652 | .byte_offset: 0, |
653 | .encoding: eEncodingInvalid, |
654 | .format: eFormatInvalid, |
655 | .kinds: {55, 55, LLDB_INVALID_REGNUM, 55, 55}, |
656 | .value_regs: nullptr, |
657 | .invalidate_regs: nullptr, |
658 | .flags_type: nullptr, |
659 | }, |
660 | {.name: "p11" , |
661 | .alt_name: "" , |
662 | .byte_size: 4, |
663 | .byte_offset: 0, |
664 | .encoding: eEncodingInvalid, |
665 | .format: eFormatInvalid, |
666 | .kinds: {56, 56, LLDB_INVALID_REGNUM, 56, 56}, |
667 | .value_regs: nullptr, |
668 | .invalidate_regs: nullptr, |
669 | .flags_type: nullptr, |
670 | }, |
671 | {.name: "p12" , |
672 | .alt_name: "" , |
673 | .byte_size: 4, |
674 | .byte_offset: 0, |
675 | .encoding: eEncodingInvalid, |
676 | .format: eFormatInvalid, |
677 | .kinds: {57, 57, LLDB_INVALID_REGNUM, 57, 57}, |
678 | .value_regs: nullptr, |
679 | .invalidate_regs: nullptr, |
680 | .flags_type: nullptr, |
681 | }, |
682 | {.name: "p13" , |
683 | .alt_name: "" , |
684 | .byte_size: 4, |
685 | .byte_offset: 0, |
686 | .encoding: eEncodingInvalid, |
687 | .format: eFormatInvalid, |
688 | .kinds: {58, 58, LLDB_INVALID_REGNUM, 58, 58}, |
689 | .value_regs: nullptr, |
690 | .invalidate_regs: nullptr, |
691 | .flags_type: nullptr, |
692 | }, |
693 | {.name: "p14" , |
694 | .alt_name: "" , |
695 | .byte_size: 4, |
696 | .byte_offset: 0, |
697 | .encoding: eEncodingInvalid, |
698 | .format: eFormatInvalid, |
699 | .kinds: {59, 59, LLDB_INVALID_REGNUM, 59, 59}, |
700 | .value_regs: nullptr, |
701 | .invalidate_regs: nullptr, |
702 | .flags_type: nullptr, |
703 | }, |
704 | {.name: "p15" , |
705 | .alt_name: "" , |
706 | .byte_size: 4, |
707 | .byte_offset: 0, |
708 | .encoding: eEncodingInvalid, |
709 | .format: eFormatInvalid, |
710 | .kinds: {60, 60, LLDB_INVALID_REGNUM, 60, 60}, |
711 | .value_regs: nullptr, |
712 | .invalidate_regs: nullptr, |
713 | .flags_type: nullptr, |
714 | }, |
715 | {.name: "p16" , |
716 | .alt_name: "" , |
717 | .byte_size: 4, |
718 | .byte_offset: 0, |
719 | .encoding: eEncodingInvalid, |
720 | .format: eFormatInvalid, |
721 | .kinds: {61, 61, LLDB_INVALID_REGNUM, 61, 61}, |
722 | .value_regs: nullptr, |
723 | .invalidate_regs: nullptr, |
724 | .flags_type: nullptr, |
725 | }, |
726 | {.name: "p17" , |
727 | .alt_name: "" , |
728 | .byte_size: 4, |
729 | .byte_offset: 0, |
730 | .encoding: eEncodingInvalid, |
731 | .format: eFormatInvalid, |
732 | .kinds: {62, 62, LLDB_INVALID_REGNUM, 62, 62}, |
733 | .value_regs: nullptr, |
734 | .invalidate_regs: nullptr, |
735 | .flags_type: nullptr, |
736 | }, |
737 | {.name: "p18" , |
738 | .alt_name: "" , |
739 | .byte_size: 4, |
740 | .byte_offset: 0, |
741 | .encoding: eEncodingInvalid, |
742 | .format: eFormatInvalid, |
743 | .kinds: {63, 63, LLDB_INVALID_REGNUM, 63, 63}, |
744 | .value_regs: nullptr, |
745 | .invalidate_regs: nullptr, |
746 | .flags_type: nullptr, |
747 | }, |
748 | // } |
749 | {.name: "sgp0" , |
750 | .alt_name: "" , |
751 | .byte_size: 4, |
752 | .byte_offset: 0, |
753 | .encoding: eEncodingUint, |
754 | .format: eFormatAddressInfo, |
755 | .kinds: {64, 64, LLDB_INVALID_REGNUM, 64, 64}, |
756 | .value_regs: nullptr, |
757 | .invalidate_regs: nullptr, |
758 | .flags_type: nullptr, |
759 | }, |
760 | // PADDING { |
761 | {.name: "p19" , |
762 | .alt_name: "" , |
763 | .byte_size: 4, |
764 | .byte_offset: 0, |
765 | .encoding: eEncodingInvalid, |
766 | .format: eFormatInvalid, |
767 | .kinds: {65, 65, LLDB_INVALID_REGNUM, 65, 65}, |
768 | .value_regs: nullptr, |
769 | .invalidate_regs: nullptr, |
770 | .flags_type: nullptr, |
771 | }, |
772 | // } |
773 | {.name: "stid" , |
774 | .alt_name: "" , |
775 | .byte_size: 4, |
776 | .byte_offset: 0, |
777 | .encoding: eEncodingUint, |
778 | .format: eFormatAddressInfo, |
779 | .kinds: {66, 66, LLDB_INVALID_REGNUM, 66, 66}, |
780 | .value_regs: nullptr, |
781 | .invalidate_regs: nullptr, |
782 | .flags_type: nullptr, |
783 | }, |
784 | {.name: "elr" , |
785 | .alt_name: "" , |
786 | .byte_size: 4, |
787 | .byte_offset: 0, |
788 | .encoding: eEncodingUint, |
789 | .format: eFormatAddressInfo, |
790 | .kinds: {67, 67, LLDB_INVALID_REGNUM, 67, 67}, |
791 | .value_regs: nullptr, |
792 | .invalidate_regs: nullptr, |
793 | .flags_type: nullptr, |
794 | }, |
795 | {.name: "badva0" , |
796 | .alt_name: "" , |
797 | .byte_size: 4, |
798 | .byte_offset: 0, |
799 | .encoding: eEncodingUint, |
800 | .format: eFormatAddressInfo, |
801 | .kinds: {68, 68, LLDB_INVALID_REGNUM, 68, 68}, |
802 | .value_regs: nullptr, |
803 | .invalidate_regs: nullptr, |
804 | .flags_type: nullptr, |
805 | }, |
806 | {.name: "badva1" , |
807 | .alt_name: "" , |
808 | .byte_size: 4, |
809 | .byte_offset: 0, |
810 | .encoding: eEncodingUint, |
811 | .format: eFormatAddressInfo, |
812 | .kinds: {69, 69, LLDB_INVALID_REGNUM, 69, 69}, |
813 | .value_regs: nullptr, |
814 | .invalidate_regs: nullptr, |
815 | .flags_type: nullptr, |
816 | }, |
817 | {.name: "ssr" , |
818 | .alt_name: "" , |
819 | .byte_size: 4, |
820 | .byte_offset: 0, |
821 | .encoding: eEncodingUint, |
822 | .format: eFormatAddressInfo, |
823 | .kinds: {70, 70, LLDB_INVALID_REGNUM, 70, 70}, |
824 | .value_regs: nullptr, |
825 | .invalidate_regs: nullptr, |
826 | .flags_type: nullptr, |
827 | }, |
828 | {.name: "ccr" , |
829 | .alt_name: "" , |
830 | .byte_size: 4, |
831 | .byte_offset: 0, |
832 | .encoding: eEncodingUint, |
833 | .format: eFormatAddressInfo, |
834 | .kinds: {71, 71, LLDB_INVALID_REGNUM, 71, 71}, |
835 | .value_regs: nullptr, |
836 | .invalidate_regs: nullptr, |
837 | .flags_type: nullptr, |
838 | }, |
839 | {.name: "htid" , |
840 | .alt_name: "" , |
841 | .byte_size: 4, |
842 | .byte_offset: 0, |
843 | .encoding: eEncodingUint, |
844 | .format: eFormatAddressInfo, |
845 | .kinds: {72, 72, LLDB_INVALID_REGNUM, 72, 72}, |
846 | .value_regs: nullptr, |
847 | .invalidate_regs: nullptr, |
848 | .flags_type: nullptr, |
849 | }, |
850 | // PADDING { |
851 | {.name: "p20" , |
852 | .alt_name: "" , |
853 | .byte_size: 4, |
854 | .byte_offset: 0, |
855 | .encoding: eEncodingInvalid, |
856 | .format: eFormatInvalid, |
857 | .kinds: {73, 73, LLDB_INVALID_REGNUM, 73, 73}, |
858 | .value_regs: nullptr, |
859 | .invalidate_regs: nullptr, |
860 | .flags_type: nullptr, |
861 | }, |
862 | // } |
863 | {.name: "imask" , |
864 | .alt_name: "" , |
865 | .byte_size: 4, |
866 | .byte_offset: 0, |
867 | .encoding: eEncodingUint, |
868 | .format: eFormatAddressInfo, |
869 | .kinds: {74, 74, LLDB_INVALID_REGNUM, 74, 74}, |
870 | .value_regs: nullptr, |
871 | .invalidate_regs: nullptr, |
872 | .flags_type: nullptr, |
873 | }, |
874 | // PADDING { |
875 | {.name: "p21" , |
876 | .alt_name: "" , |
877 | .byte_size: 4, |
878 | .byte_offset: 0, |
879 | .encoding: eEncodingInvalid, |
880 | .format: eFormatInvalid, |
881 | .kinds: {75, 75, LLDB_INVALID_REGNUM, 75, 75}, |
882 | .value_regs: nullptr, |
883 | .invalidate_regs: nullptr, |
884 | .flags_type: nullptr, |
885 | }, |
886 | {.name: "p22" , |
887 | .alt_name: "" , |
888 | .byte_size: 4, |
889 | .byte_offset: 0, |
890 | .encoding: eEncodingInvalid, |
891 | .format: eFormatInvalid, |
892 | .kinds: {76, 76, LLDB_INVALID_REGNUM, 76, 76}, |
893 | .value_regs: nullptr, |
894 | .invalidate_regs: nullptr, |
895 | .flags_type: nullptr, |
896 | }, |
897 | {.name: "p23" , |
898 | .alt_name: "" , |
899 | .byte_size: 4, |
900 | .byte_offset: 0, |
901 | .encoding: eEncodingInvalid, |
902 | .format: eFormatInvalid, |
903 | .kinds: {77, 77, LLDB_INVALID_REGNUM, 77, 77}, |
904 | .value_regs: nullptr, |
905 | .invalidate_regs: nullptr, |
906 | .flags_type: nullptr, |
907 | }, |
908 | {.name: "p24" , |
909 | .alt_name: "" , |
910 | .byte_size: 4, |
911 | .byte_offset: 0, |
912 | .encoding: eEncodingInvalid, |
913 | .format: eFormatInvalid, |
914 | .kinds: {78, 78, LLDB_INVALID_REGNUM, 78, 78}, |
915 | .value_regs: nullptr, |
916 | .invalidate_regs: nullptr, |
917 | .flags_type: nullptr, |
918 | }, |
919 | {.name: "p25" , |
920 | .alt_name: "" , |
921 | .byte_size: 4, |
922 | .byte_offset: 0, |
923 | .encoding: eEncodingInvalid, |
924 | .format: eFormatInvalid, |
925 | .kinds: {79, 79, LLDB_INVALID_REGNUM, 79, 79}, |
926 | .value_regs: nullptr, |
927 | .invalidate_regs: nullptr, |
928 | .flags_type: nullptr, |
929 | }, |
930 | // } |
931 | {.name: "g0" , |
932 | .alt_name: "" , |
933 | .byte_size: 4, |
934 | .byte_offset: 0, |
935 | .encoding: eEncodingUint, |
936 | .format: eFormatAddressInfo, |
937 | .kinds: {80, 80, LLDB_INVALID_REGNUM, 80, 80}, |
938 | .value_regs: nullptr, |
939 | .invalidate_regs: nullptr, |
940 | .flags_type: nullptr, |
941 | }, |
942 | {.name: "g1" , |
943 | .alt_name: "" , |
944 | .byte_size: 4, |
945 | .byte_offset: 0, |
946 | .encoding: eEncodingUint, |
947 | .format: eFormatAddressInfo, |
948 | .kinds: {81, 81, LLDB_INVALID_REGNUM, 81, 81}, |
949 | .value_regs: nullptr, |
950 | .invalidate_regs: nullptr, |
951 | .flags_type: nullptr, |
952 | }, |
953 | {.name: "g2" , |
954 | .alt_name: "" , |
955 | .byte_size: 4, |
956 | .byte_offset: 0, |
957 | .encoding: eEncodingUint, |
958 | .format: eFormatAddressInfo, |
959 | .kinds: {82, 82, LLDB_INVALID_REGNUM, 82, 82}, |
960 | .value_regs: nullptr, |
961 | .invalidate_regs: nullptr, |
962 | .flags_type: nullptr, |
963 | }, |
964 | {.name: "g3" , |
965 | .alt_name: "" , |
966 | .byte_size: 4, |
967 | .byte_offset: 0, |
968 | .encoding: eEncodingUint, |
969 | .format: eFormatAddressInfo, |
970 | .kinds: {83, 83, LLDB_INVALID_REGNUM, 83, 83}, |
971 | .value_regs: nullptr, |
972 | .invalidate_regs: nullptr, |
973 | .flags_type: nullptr, |
974 | }}; |
975 | |
976 | static const uint32_t k_num_register_infos = |
977 | sizeof(g_register_infos) / sizeof(RegisterInfo); |
978 | |
979 | const lldb_private::RegisterInfo * |
980 | ABISysV_hexagon::GetRegisterInfoArray(uint32_t &count) { |
981 | count = k_num_register_infos; |
982 | return g_register_infos; |
983 | } |
984 | |
985 | /* |
986 | http://en.wikipedia.org/wiki/Red_zone_%28computing%29 |
987 | |
988 | In computing, a red zone is a fixed size area in memory beyond the stack |
989 | pointer that has not been |
990 | "allocated". This region of memory is not to be modified by |
991 | interrupt/exception/signal handlers. |
992 | This allows the space to be used for temporary data without the extra |
993 | overhead of modifying the |
994 | stack pointer. The x86-64 ABI mandates a 128 byte red zone.[1] The OpenRISC |
995 | toolchain assumes a |
996 | 128 byte red zone though it is not documented. |
997 | */ |
998 | size_t ABISysV_hexagon::GetRedZoneSize() const { return 0; } |
999 | |
1000 | // Static Functions |
1001 | |
1002 | ABISP |
1003 | ABISysV_hexagon::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { |
1004 | if (arch.GetTriple().getArch() == llvm::Triple::hexagon) { |
1005 | return ABISP( |
1006 | new ABISysV_hexagon(std::move(process_sp), MakeMCRegisterInfo(arch))); |
1007 | } |
1008 | return ABISP(); |
1009 | } |
1010 | |
1011 | bool ABISysV_hexagon::PrepareTrivialCall(Thread &thread, lldb::addr_t sp, |
1012 | lldb::addr_t pc, lldb::addr_t ra, |
1013 | llvm::ArrayRef<addr_t> args) const { |
1014 | // we don't use the traditional trivial call specialized for jit |
1015 | return false; |
1016 | } |
1017 | |
1018 | /* |
1019 | |
1020 | // AD: |
1021 | // . safeguard the current stack |
1022 | // . how can we know that the called function will create its own frame |
1023 | properly? |
1024 | // . we could manually make a new stack first: |
1025 | // 2. push RA |
1026 | // 3. push FP |
1027 | // 4. FP = SP |
1028 | // 5. SP = SP ( since no locals in our temp frame ) |
1029 | |
1030 | // AD 6/05/2014 |
1031 | // . variable argument list parameters are not passed via registers, they are |
1032 | passed on |
1033 | // the stack. This presents us with a problem, since we need to know when |
1034 | the valist |
1035 | // starts. Currently I can find out if a function is varg, but not how many |
1036 | // real parameters it takes. Thus I don't know when to start spilling the |
1037 | vargs. For |
1038 | // the time being, to progress, I will assume that it takes on real parameter |
1039 | before |
1040 | // the vargs list starts. |
1041 | |
1042 | // AD 06/05/2014 |
1043 | // . how do we adhere to the stack alignment requirements |
1044 | |
1045 | // AD 06/05/2014 |
1046 | // . handle 64bit values and their register / stack requirements |
1047 | |
1048 | */ |
1049 | #define HEX_ABI_DEBUG 0 |
1050 | bool ABISysV_hexagon::PrepareTrivialCall( |
1051 | Thread &thread, lldb::addr_t sp, lldb::addr_t pc, lldb::addr_t ra, |
1052 | llvm::Type &prototype, llvm::ArrayRef<ABI::CallArgument> args) const { |
1053 | // default number of register passed arguments for varg functions |
1054 | const int nVArgRegParams = 1; |
1055 | Status error; |
1056 | |
1057 | // grab the process so we have access to the memory for spilling |
1058 | lldb::ProcessSP proc = thread.GetProcess(); |
1059 | |
1060 | // get the register context for modifying all of the registers |
1061 | RegisterContext *reg_ctx = thread.GetRegisterContext().get(); |
1062 | if (!reg_ctx) |
1063 | return false; |
1064 | |
1065 | uint32_t pc_reg = reg_ctx->ConvertRegisterKindToRegisterNumber( |
1066 | kind: eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); |
1067 | if (pc_reg == LLDB_INVALID_REGNUM) |
1068 | return false; |
1069 | |
1070 | uint32_t ra_reg = reg_ctx->ConvertRegisterKindToRegisterNumber( |
1071 | kind: eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA); |
1072 | if (ra_reg == LLDB_INVALID_REGNUM) |
1073 | return false; |
1074 | |
1075 | uint32_t sp_reg = reg_ctx->ConvertRegisterKindToRegisterNumber( |
1076 | kind: eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); |
1077 | if (sp_reg == LLDB_INVALID_REGNUM) |
1078 | return false; |
1079 | |
1080 | // push host data onto target |
1081 | for (size_t i = 0; i < args.size(); i++) { |
1082 | const ABI::CallArgument &arg = args[i]; |
1083 | // skip over target values |
1084 | if (arg.type == ABI::CallArgument::TargetValue) |
1085 | continue; |
1086 | // round up to 8 byte multiple |
1087 | size_t argSize = (arg.size | 0x7) + 1; |
1088 | |
1089 | // create space on the stack for this data |
1090 | sp -= argSize; |
1091 | |
1092 | // write this argument onto the stack of the host process |
1093 | proc->WriteMemory(vm_addr: sp, buf: arg.data_up.get(), size: arg.size, error); |
1094 | if (error.Fail()) |
1095 | return false; |
1096 | |
1097 | // update the argument with the target pointer |
1098 | // XXX: This is a gross hack for getting around the const |
1099 | *const_cast<lldb::addr_t *>(&arg.value) = sp; |
1100 | } |
1101 | |
1102 | #if HEX_ABI_DEBUG |
1103 | // print the original stack pointer |
1104 | printf("sp : %04" PRIx64 " \n" , sp); |
1105 | #endif |
1106 | |
1107 | // make sure number of parameters matches prototype |
1108 | assert(prototype.getFunctionNumParams() == args.size()); |
1109 | |
1110 | // check if this is a variable argument function |
1111 | bool isVArg = prototype.isFunctionVarArg(); |
1112 | |
1113 | // number of arguments passed by register |
1114 | int nRegArgs = nVArgRegParams; |
1115 | if (!isVArg) { |
1116 | // number of arguments is limited by [R0 : R5] space |
1117 | nRegArgs = args.size(); |
1118 | if (nRegArgs > 6) |
1119 | nRegArgs = 6; |
1120 | } |
1121 | |
1122 | // pass arguments that are passed via registers |
1123 | for (int i = 0; i < nRegArgs; i++) { |
1124 | // get the parameter as a u32 |
1125 | uint32_t param = (uint32_t)args[i].value; |
1126 | // write argument into register |
1127 | if (!reg_ctx->WriteRegisterFromUnsigned(reg: i, uval: param)) |
1128 | return false; |
1129 | } |
1130 | |
1131 | // number of arguments to spill onto stack |
1132 | int nSpillArgs = args.size() - nRegArgs; |
1133 | // make space on the stack for arguments |
1134 | sp -= 4 * nSpillArgs; |
1135 | // align stack on an 8 byte boundary |
1136 | if (sp & 7) |
1137 | sp -= 4; |
1138 | |
1139 | // arguments that are passed on the stack |
1140 | for (size_t i = nRegArgs, offs = 0; i < args.size(); i++) { |
1141 | // get the parameter as a u32 |
1142 | uint32_t param = (uint32_t)args[i].value; |
1143 | // write argument to stack |
1144 | proc->WriteMemory(vm_addr: sp + offs, buf: (void *)¶m, size: sizeof(param), error); |
1145 | if (!error.Success()) |
1146 | return false; |
1147 | // |
1148 | offs += 4; |
1149 | } |
1150 | |
1151 | // update registers with current function call state |
1152 | reg_ctx->WriteRegisterFromUnsigned(reg: pc_reg, uval: pc); |
1153 | reg_ctx->WriteRegisterFromUnsigned(reg: ra_reg, uval: ra); |
1154 | reg_ctx->WriteRegisterFromUnsigned(reg: sp_reg, uval: sp); |
1155 | |
1156 | #if HEX_ABI_DEBUG |
1157 | // quick and dirty stack dumper for debugging |
1158 | for (int i = -8; i < 8; i++) { |
1159 | uint32_t data = 0; |
1160 | lldb::addr_t addr = sp + i * 4; |
1161 | proc->ReadMemory(addr, (void *)&data, sizeof(data), error); |
1162 | printf("\n0x%04" PRIx64 " 0x%08x " , addr, data); |
1163 | if (i == 0) |
1164 | printf("<<-- sp" ); |
1165 | } |
1166 | printf("\n" ); |
1167 | #endif |
1168 | |
1169 | return true; |
1170 | } |
1171 | |
1172 | bool ABISysV_hexagon::GetArgumentValues(Thread &thread, |
1173 | ValueList &values) const { |
1174 | return false; |
1175 | } |
1176 | |
1177 | Status |
1178 | ABISysV_hexagon::SetReturnValueObject(lldb::StackFrameSP &frame_sp, |
1179 | lldb::ValueObjectSP &new_value_sp) { |
1180 | Status error; |
1181 | return error; |
1182 | } |
1183 | |
1184 | ValueObjectSP ABISysV_hexagon::GetReturnValueObjectSimple( |
1185 | Thread &thread, CompilerType &return_compiler_type) const { |
1186 | ValueObjectSP return_valobj_sp; |
1187 | return return_valobj_sp; |
1188 | } |
1189 | |
1190 | ValueObjectSP ABISysV_hexagon::GetReturnValueObjectImpl( |
1191 | Thread &thread, CompilerType &return_compiler_type) const { |
1192 | ValueObjectSP return_valobj_sp; |
1193 | return return_valobj_sp; |
1194 | } |
1195 | |
1196 | // called when we are on the first instruction of a new function for hexagon |
1197 | // the return address is in RA (R31) |
1198 | bool ABISysV_hexagon::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { |
1199 | unwind_plan.Clear(); |
1200 | unwind_plan.SetRegisterKind(eRegisterKindGeneric); |
1201 | unwind_plan.SetReturnAddressRegister(LLDB_REGNUM_GENERIC_RA); |
1202 | |
1203 | UnwindPlan::RowSP row(new UnwindPlan::Row); |
1204 | |
1205 | // Our Call Frame Address is the stack pointer value |
1206 | row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_SP, offset: 4); |
1207 | row->SetOffset(0); |
1208 | |
1209 | // The previous PC is in the LR |
1210 | row->SetRegisterLocationToRegister(LLDB_REGNUM_GENERIC_PC, |
1211 | LLDB_REGNUM_GENERIC_RA, can_replace: true); |
1212 | unwind_plan.AppendRow(row_sp: row); |
1213 | |
1214 | unwind_plan.SetSourceName("hexagon at-func-entry default" ); |
1215 | unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); |
1216 | return true; |
1217 | } |
1218 | |
1219 | bool ABISysV_hexagon::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { |
1220 | unwind_plan.Clear(); |
1221 | unwind_plan.SetRegisterKind(eRegisterKindGeneric); |
1222 | |
1223 | uint32_t fp_reg_num = LLDB_REGNUM_GENERIC_FP; |
1224 | uint32_t sp_reg_num = LLDB_REGNUM_GENERIC_SP; |
1225 | uint32_t pc_reg_num = LLDB_REGNUM_GENERIC_PC; |
1226 | |
1227 | UnwindPlan::RowSP row(new UnwindPlan::Row); |
1228 | |
1229 | row->SetUnspecifiedRegistersAreUndefined(true); |
1230 | row->GetCFAValue().SetIsRegisterPlusOffset(LLDB_REGNUM_GENERIC_FP, offset: 8); |
1231 | |
1232 | row->SetRegisterLocationToAtCFAPlusOffset(reg_num: fp_reg_num, offset: -8, can_replace: true); |
1233 | row->SetRegisterLocationToAtCFAPlusOffset(reg_num: pc_reg_num, offset: -4, can_replace: true); |
1234 | row->SetRegisterLocationToIsCFAPlusOffset(reg_num: sp_reg_num, offset: 0, can_replace: true); |
1235 | |
1236 | unwind_plan.AppendRow(row_sp: row); |
1237 | unwind_plan.SetSourceName("hexagon default unwind plan" ); |
1238 | unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); |
1239 | unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); |
1240 | unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo); |
1241 | return true; |
1242 | } |
1243 | |
1244 | /* |
1245 | Register Usage Saved By |
1246 | |
1247 | R0 - R5 parameters(a) - |
1248 | R6 - R15 Scratch(b) Caller |
1249 | R16 - R27 Scratch Callee |
1250 | R28 Scratch(b) Caller |
1251 | R29 - R31 Stack Frames Callee(c) |
1252 | P3:0 Processor State Caller |
1253 | |
1254 | a = the caller can change parameter values |
1255 | b = R14 - R15 and R28 are used by the procedure linkage table |
1256 | c = R29 - R31 are saved and restored by allocframe() and deallocframe() |
1257 | */ |
1258 | bool ABISysV_hexagon::RegisterIsVolatile(const RegisterInfo *reg_info) { |
1259 | return !RegisterIsCalleeSaved(reg_info); |
1260 | } |
1261 | |
1262 | bool ABISysV_hexagon::RegisterIsCalleeSaved(const RegisterInfo *reg_info) { |
1263 | int reg = ((reg_info->byte_offset) / 4); |
1264 | |
1265 | bool save = (reg >= 16) && (reg <= 27); |
1266 | save |= (reg >= 29) && (reg <= 32); |
1267 | |
1268 | return save; |
1269 | } |
1270 | |
1271 | void ABISysV_hexagon::Initialize() { |
1272 | PluginManager::RegisterPlugin(name: GetPluginNameStatic(), |
1273 | description: "System V ABI for hexagon targets" , |
1274 | create_callback: CreateInstance); |
1275 | } |
1276 | |
1277 | void ABISysV_hexagon::Terminate() { |
1278 | PluginManager::UnregisterPlugin(create_callback: CreateInstance); |
1279 | } |
1280 | |
1281 | // get value object specialized to work with llvm IR types |
1282 | lldb::ValueObjectSP |
1283 | ABISysV_hexagon::GetReturnValueObjectImpl(lldb_private::Thread &thread, |
1284 | llvm::Type &retType) const { |
1285 | Value value; |
1286 | ValueObjectSP vObjSP; |
1287 | |
1288 | // get the current register context |
1289 | RegisterContext *reg_ctx = thread.GetRegisterContext().get(); |
1290 | if (!reg_ctx) |
1291 | return vObjSP; |
1292 | |
1293 | // for now just pop R0 to find the return value |
1294 | const lldb_private::RegisterInfo *r0_info = |
1295 | reg_ctx->GetRegisterInfoAtIndex(reg: 0); |
1296 | if (r0_info == nullptr) |
1297 | return vObjSP; |
1298 | |
1299 | // void return type |
1300 | if (retType.isVoidTy()) { |
1301 | value.GetScalar() = 0; |
1302 | } |
1303 | // integer / pointer return type |
1304 | else if (retType.isIntegerTy() || retType.isPointerTy()) { |
1305 | // read r0 register value |
1306 | lldb_private::RegisterValue r0_value; |
1307 | if (!reg_ctx->ReadRegister(reg_info: r0_info, reg_value&: r0_value)) |
1308 | return vObjSP; |
1309 | |
1310 | // push r0 into value |
1311 | uint32_t r0_u32 = r0_value.GetAsUInt32(); |
1312 | |
1313 | // account for integer size |
1314 | if (retType.isIntegerTy() && retType.isSized()) { |
1315 | uint64_t size = retType.getScalarSizeInBits(); |
1316 | uint64_t mask = (1ull << size) - 1; |
1317 | // mask out higher order bits then the type we expect |
1318 | r0_u32 &= mask; |
1319 | } |
1320 | |
1321 | value.GetScalar() = r0_u32; |
1322 | } |
1323 | // unsupported return type |
1324 | else |
1325 | return vObjSP; |
1326 | |
1327 | // pack the value into a ValueObjectSP |
1328 | vObjSP = ValueObjectConstResult::Create(exe_scope: thread.GetStackFrameAtIndex(idx: 0).get(), |
1329 | value, name: ConstString("" )); |
1330 | return vObjSP; |
1331 | } |
1332 | |