1 //===-- ABISysV_x86_64.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 "ABISysV_x86_64.h"
11
12 #include "llvm/ADT/STLExtras.h"
13 #include "llvm/ADT/StringSwitch.h"
14 #include "llvm/ADT/Triple.h"
15
16 #include "lldb/Core/Module.h"
17 #include "lldb/Core/PluginManager.h"
18 #include "lldb/Core/Value.h"
19 #include "lldb/Core/ValueObjectConstResult.h"
20 #include "lldb/Core/ValueObjectMemory.h"
21 #include "lldb/Core/ValueObjectRegister.h"
22 #include "lldb/Symbol/UnwindPlan.h"
23 #include "lldb/Target/Process.h"
24 #include "lldb/Target/RegisterContext.h"
25 #include "lldb/Target/StackFrame.h"
26 #include "lldb/Target/Target.h"
27 #include "lldb/Target/Thread.h"
28 #include "lldb/Utility/ConstString.h"
29 #include "lldb/Utility/DataExtractor.h"
30 #include "lldb/Utility/Log.h"
31 #include "lldb/Utility/RegisterValue.h"
32 #include "lldb/Utility/Status.h"
33
34 using namespace lldb;
35 using namespace lldb_private;
36
37 enum dwarf_regnums {
38 dwarf_rax = 0,
39 dwarf_rdx,
40 dwarf_rcx,
41 dwarf_rbx,
42 dwarf_rsi,
43 dwarf_rdi,
44 dwarf_rbp,
45 dwarf_rsp,
46 dwarf_r8,
47 dwarf_r9,
48 dwarf_r10,
49 dwarf_r11,
50 dwarf_r12,
51 dwarf_r13,
52 dwarf_r14,
53 dwarf_r15,
54 dwarf_rip,
55 dwarf_xmm0,
56 dwarf_xmm1,
57 dwarf_xmm2,
58 dwarf_xmm3,
59 dwarf_xmm4,
60 dwarf_xmm5,
61 dwarf_xmm6,
62 dwarf_xmm7,
63 dwarf_xmm8,
64 dwarf_xmm9,
65 dwarf_xmm10,
66 dwarf_xmm11,
67 dwarf_xmm12,
68 dwarf_xmm13,
69 dwarf_xmm14,
70 dwarf_xmm15,
71 dwarf_stmm0,
72 dwarf_stmm1,
73 dwarf_stmm2,
74 dwarf_stmm3,
75 dwarf_stmm4,
76 dwarf_stmm5,
77 dwarf_stmm6,
78 dwarf_stmm7,
79 dwarf_ymm0,
80 dwarf_ymm1,
81 dwarf_ymm2,
82 dwarf_ymm3,
83 dwarf_ymm4,
84 dwarf_ymm5,
85 dwarf_ymm6,
86 dwarf_ymm7,
87 dwarf_ymm8,
88 dwarf_ymm9,
89 dwarf_ymm10,
90 dwarf_ymm11,
91 dwarf_ymm12,
92 dwarf_ymm13,
93 dwarf_ymm14,
94 dwarf_ymm15,
95 dwarf_bnd0 = 126,
96 dwarf_bnd1,
97 dwarf_bnd2,
98 dwarf_bnd3
99 };
100
101 static RegisterInfo g_register_infos[] = {
102 // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME
103 // DWARF GENERIC PROCESS PLUGIN
104 // LLDB NATIVE
105 // ======== ======= == === ============= ===================
106 // ======================= =====================
107 // =========================== ===================== ======================
108 {"rax",
109 nullptr,
110 8,
111 0,
112 eEncodingUint,
113 eFormatHex,
114 {dwarf_rax, dwarf_rax, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
115 LLDB_INVALID_REGNUM},
116 nullptr,
117 nullptr,
118 nullptr,
119 0},
120 {"rbx",
121 nullptr,
122 8,
123 0,
124 eEncodingUint,
125 eFormatHex,
126 {dwarf_rbx, dwarf_rbx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
127 LLDB_INVALID_REGNUM},
128 nullptr,
129 nullptr,
130 nullptr,
131 0},
132 {"rcx",
133 "arg4",
134 8,
135 0,
136 eEncodingUint,
137 eFormatHex,
138 {dwarf_rcx, dwarf_rcx, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM,
139 LLDB_INVALID_REGNUM},
140 nullptr,
141 nullptr,
142 nullptr,
143 0},
144 {"rdx",
145 "arg3",
146 8,
147 0,
148 eEncodingUint,
149 eFormatHex,
150 {dwarf_rdx, dwarf_rdx, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM,
151 LLDB_INVALID_REGNUM},
152 nullptr,
153 nullptr,
154 nullptr,
155 0},
156 {"rsi",
157 "arg2",
158 8,
159 0,
160 eEncodingUint,
161 eFormatHex,
162 {dwarf_rsi, dwarf_rsi, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM,
163 LLDB_INVALID_REGNUM},
164 nullptr,
165 nullptr,
166 nullptr,
167 0},
168 {"rdi",
169 "arg1",
170 8,
171 0,
172 eEncodingUint,
173 eFormatHex,
174 {dwarf_rdi, dwarf_rdi, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM,
175 LLDB_INVALID_REGNUM},
176 nullptr,
177 nullptr,
178 nullptr,
179 0},
180 {"rbp",
181 "fp",
182 8,
183 0,
184 eEncodingUint,
185 eFormatHex,
186 {dwarf_rbp, dwarf_rbp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,
187 LLDB_INVALID_REGNUM},
188 nullptr,
189 nullptr,
190 nullptr,
191 0},
192 {"rsp",
193 "sp",
194 8,
195 0,
196 eEncodingUint,
197 eFormatHex,
198 {dwarf_rsp, dwarf_rsp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,
199 LLDB_INVALID_REGNUM},
200 nullptr,
201 nullptr,
202 nullptr,
203 0},
204 {"r8",
205 "arg5",
206 8,
207 0,
208 eEncodingUint,
209 eFormatHex,
210 {dwarf_r8, dwarf_r8, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM,
211 LLDB_INVALID_REGNUM},
212 nullptr,
213 nullptr,
214 nullptr,
215 0},
216 {"r9",
217 "arg6",
218 8,
219 0,
220 eEncodingUint,
221 eFormatHex,
222 {dwarf_r9, dwarf_r9, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM,
223 LLDB_INVALID_REGNUM},
224 nullptr,
225 nullptr,
226 nullptr,
227 0},
228 {"r10",
229 nullptr,
230 8,
231 0,
232 eEncodingUint,
233 eFormatHex,
234 {dwarf_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
235 LLDB_INVALID_REGNUM},
236 nullptr,
237 nullptr,
238 nullptr,
239 0},
240 {"r11",
241 nullptr,
242 8,
243 0,
244 eEncodingUint,
245 eFormatHex,
246 {dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
247 LLDB_INVALID_REGNUM},
248 nullptr,
249 nullptr,
250 nullptr,
251 0},
252 {"r12",
253 nullptr,
254 8,
255 0,
256 eEncodingUint,
257 eFormatHex,
258 {dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
259 LLDB_INVALID_REGNUM},
260 nullptr,
261 nullptr,
262 nullptr,
263 0},
264 {"r13",
265 nullptr,
266 8,
267 0,
268 eEncodingUint,
269 eFormatHex,
270 {dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
271 LLDB_INVALID_REGNUM},
272 nullptr,
273 nullptr,
274 nullptr,
275 0},
276 {"r14",
277 nullptr,
278 8,
279 0,
280 eEncodingUint,
281 eFormatHex,
282 {dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
283 LLDB_INVALID_REGNUM},
284 nullptr,
285 nullptr,
286 nullptr,
287 0},
288 {"r15",
289 nullptr,
290 8,
291 0,
292 eEncodingUint,
293 eFormatHex,
294 {dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
295 LLDB_INVALID_REGNUM},
296 nullptr,
297 nullptr,
298 nullptr,
299 0},
300 {"rip",
301 "pc",
302 8,
303 0,
304 eEncodingUint,
305 eFormatHex,
306 {dwarf_rip, dwarf_rip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,
307 LLDB_INVALID_REGNUM},
308 nullptr,
309 nullptr,
310 nullptr,
311 0},
312 {"rflags",
313 nullptr,
314 4,
315 0,
316 eEncodingUint,
317 eFormatHex,
318 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS,
319 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
320 nullptr,
321 nullptr,
322 nullptr,
323 0},
324 {"cs",
325 nullptr,
326 4,
327 0,
328 eEncodingUint,
329 eFormatHex,
330 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
331 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
332 nullptr,
333 nullptr,
334 nullptr,
335 0},
336 {"ss",
337 nullptr,
338 4,
339 0,
340 eEncodingUint,
341 eFormatHex,
342 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
343 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
344 nullptr,
345 nullptr,
346 nullptr,
347 0},
348 {"ds",
349 nullptr,
350 4,
351 0,
352 eEncodingUint,
353 eFormatHex,
354 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
355 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
356 nullptr,
357 nullptr,
358 nullptr,
359 0},
360 {"es",
361 nullptr,
362 4,
363 0,
364 eEncodingUint,
365 eFormatHex,
366 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
367 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
368 nullptr,
369 nullptr,
370 nullptr,
371 0},
372 {"fs",
373 nullptr,
374 4,
375 0,
376 eEncodingUint,
377 eFormatHex,
378 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
379 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
380 nullptr,
381 nullptr,
382 nullptr,
383 0},
384 {"gs",
385 nullptr,
386 4,
387 0,
388 eEncodingUint,
389 eFormatHex,
390 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
391 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
392 nullptr,
393 nullptr,
394 nullptr,
395 0},
396 {"stmm0",
397 nullptr,
398 10,
399 0,
400 eEncodingVector,
401 eFormatVectorOfUInt8,
402 {dwarf_stmm0, dwarf_stmm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
403 LLDB_INVALID_REGNUM},
404 nullptr,
405 nullptr,
406 nullptr,
407 0},
408 {"stmm1",
409 nullptr,
410 10,
411 0,
412 eEncodingVector,
413 eFormatVectorOfUInt8,
414 {dwarf_stmm1, dwarf_stmm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
415 LLDB_INVALID_REGNUM},
416 nullptr,
417 nullptr,
418 nullptr,
419 0},
420 {"stmm2",
421 nullptr,
422 10,
423 0,
424 eEncodingVector,
425 eFormatVectorOfUInt8,
426 {dwarf_stmm2, dwarf_stmm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
427 LLDB_INVALID_REGNUM},
428 nullptr,
429 nullptr,
430 nullptr,
431 0},
432 {"stmm3",
433 nullptr,
434 10,
435 0,
436 eEncodingVector,
437 eFormatVectorOfUInt8,
438 {dwarf_stmm3, dwarf_stmm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
439 LLDB_INVALID_REGNUM},
440 nullptr,
441 nullptr,
442 nullptr,
443 0},
444 {"stmm4",
445 nullptr,
446 10,
447 0,
448 eEncodingVector,
449 eFormatVectorOfUInt8,
450 {dwarf_stmm4, dwarf_stmm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
451 LLDB_INVALID_REGNUM},
452 nullptr,
453 nullptr,
454 nullptr,
455 0},
456 {"stmm5",
457 nullptr,
458 10,
459 0,
460 eEncodingVector,
461 eFormatVectorOfUInt8,
462 {dwarf_stmm5, dwarf_stmm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
463 LLDB_INVALID_REGNUM},
464 nullptr,
465 nullptr,
466 nullptr,
467 0},
468 {"stmm6",
469 nullptr,
470 10,
471 0,
472 eEncodingVector,
473 eFormatVectorOfUInt8,
474 {dwarf_stmm6, dwarf_stmm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
475 LLDB_INVALID_REGNUM},
476 nullptr,
477 nullptr,
478 nullptr,
479 0},
480 {"stmm7",
481 nullptr,
482 10,
483 0,
484 eEncodingVector,
485 eFormatVectorOfUInt8,
486 {dwarf_stmm7, dwarf_stmm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
487 LLDB_INVALID_REGNUM},
488 nullptr,
489 nullptr,
490 nullptr,
491 0},
492 {"fctrl",
493 nullptr,
494 4,
495 0,
496 eEncodingUint,
497 eFormatHex,
498 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
499 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
500 nullptr,
501 nullptr,
502 nullptr,
503 0},
504 {"fstat",
505 nullptr,
506 4,
507 0,
508 eEncodingUint,
509 eFormatHex,
510 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
511 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
512 nullptr,
513 nullptr,
514 nullptr,
515 0},
516 {"ftag",
517 nullptr,
518 4,
519 0,
520 eEncodingUint,
521 eFormatHex,
522 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
523 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
524 nullptr,
525 nullptr,
526 nullptr,
527 0},
528 {"fiseg",
529 nullptr,
530 4,
531 0,
532 eEncodingUint,
533 eFormatHex,
534 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
535 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
536 nullptr,
537 nullptr,
538 nullptr,
539 0},
540 {"fioff",
541 nullptr,
542 4,
543 0,
544 eEncodingUint,
545 eFormatHex,
546 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
547 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
548 nullptr,
549 nullptr,
550 nullptr,
551 0},
552 {"foseg",
553 nullptr,
554 4,
555 0,
556 eEncodingUint,
557 eFormatHex,
558 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
559 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
560 nullptr,
561 nullptr,
562 nullptr,
563 0},
564 {"fooff",
565 nullptr,
566 4,
567 0,
568 eEncodingUint,
569 eFormatHex,
570 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
571 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
572 nullptr,
573 nullptr,
574 nullptr,
575 0},
576 {"fop",
577 nullptr,
578 4,
579 0,
580 eEncodingUint,
581 eFormatHex,
582 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
583 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
584 nullptr,
585 nullptr,
586 nullptr,
587 0},
588 {"xmm0",
589 nullptr,
590 16,
591 0,
592 eEncodingVector,
593 eFormatVectorOfUInt8,
594 {dwarf_xmm0, dwarf_xmm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
595 LLDB_INVALID_REGNUM},
596 nullptr,
597 nullptr,
598 nullptr,
599 0},
600 {"xmm1",
601 nullptr,
602 16,
603 0,
604 eEncodingVector,
605 eFormatVectorOfUInt8,
606 {dwarf_xmm1, dwarf_xmm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
607 LLDB_INVALID_REGNUM},
608 nullptr,
609 nullptr,
610 nullptr,
611 0},
612 {"xmm2",
613 nullptr,
614 16,
615 0,
616 eEncodingVector,
617 eFormatVectorOfUInt8,
618 {dwarf_xmm2, dwarf_xmm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
619 LLDB_INVALID_REGNUM},
620 nullptr,
621 nullptr,
622 nullptr,
623 0},
624 {"xmm3",
625 nullptr,
626 16,
627 0,
628 eEncodingVector,
629 eFormatVectorOfUInt8,
630 {dwarf_xmm3, dwarf_xmm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
631 LLDB_INVALID_REGNUM},
632 nullptr,
633 nullptr,
634 nullptr,
635 0},
636 {"xmm4",
637 nullptr,
638 16,
639 0,
640 eEncodingVector,
641 eFormatVectorOfUInt8,
642 {dwarf_xmm4, dwarf_xmm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
643 LLDB_INVALID_REGNUM},
644 nullptr,
645 nullptr,
646 nullptr,
647 0},
648 {"xmm5",
649 nullptr,
650 16,
651 0,
652 eEncodingVector,
653 eFormatVectorOfUInt8,
654 {dwarf_xmm5, dwarf_xmm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
655 LLDB_INVALID_REGNUM},
656 nullptr,
657 nullptr,
658 nullptr,
659 0},
660 {"xmm6",
661 nullptr,
662 16,
663 0,
664 eEncodingVector,
665 eFormatVectorOfUInt8,
666 {dwarf_xmm6, dwarf_xmm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
667 LLDB_INVALID_REGNUM},
668 nullptr,
669 nullptr,
670 nullptr,
671 0},
672 {"xmm7",
673 nullptr,
674 16,
675 0,
676 eEncodingVector,
677 eFormatVectorOfUInt8,
678 {dwarf_xmm7, dwarf_xmm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
679 LLDB_INVALID_REGNUM},
680 nullptr,
681 nullptr,
682 nullptr,
683 0},
684 {"xmm8",
685 nullptr,
686 16,
687 0,
688 eEncodingVector,
689 eFormatVectorOfUInt8,
690 {dwarf_xmm8, dwarf_xmm8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
691 LLDB_INVALID_REGNUM},
692 nullptr,
693 nullptr,
694 nullptr,
695 0},
696 {"xmm9",
697 nullptr,
698 16,
699 0,
700 eEncodingVector,
701 eFormatVectorOfUInt8,
702 {dwarf_xmm9, dwarf_xmm9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
703 LLDB_INVALID_REGNUM},
704 nullptr,
705 nullptr,
706 nullptr,
707 0},
708 {"xmm10",
709 nullptr,
710 16,
711 0,
712 eEncodingVector,
713 eFormatVectorOfUInt8,
714 {dwarf_xmm10, dwarf_xmm10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
715 LLDB_INVALID_REGNUM},
716 nullptr,
717 nullptr,
718 nullptr,
719 0},
720 {"xmm11",
721 nullptr,
722 16,
723 0,
724 eEncodingVector,
725 eFormatVectorOfUInt8,
726 {dwarf_xmm11, dwarf_xmm11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
727 LLDB_INVALID_REGNUM},
728 nullptr,
729 nullptr,
730 nullptr,
731 0},
732 {"xmm12",
733 nullptr,
734 16,
735 0,
736 eEncodingVector,
737 eFormatVectorOfUInt8,
738 {dwarf_xmm12, dwarf_xmm12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
739 LLDB_INVALID_REGNUM},
740 nullptr,
741 nullptr,
742 nullptr,
743 0},
744 {"xmm13",
745 nullptr,
746 16,
747 0,
748 eEncodingVector,
749 eFormatVectorOfUInt8,
750 {dwarf_xmm13, dwarf_xmm13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
751 LLDB_INVALID_REGNUM},
752 nullptr,
753 nullptr,
754 nullptr,
755 0},
756 {"xmm14",
757 nullptr,
758 16,
759 0,
760 eEncodingVector,
761 eFormatVectorOfUInt8,
762 {dwarf_xmm14, dwarf_xmm14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
763 LLDB_INVALID_REGNUM},
764 nullptr,
765 nullptr,
766 nullptr,
767 0},
768 {"xmm15",
769 nullptr,
770 16,
771 0,
772 eEncodingVector,
773 eFormatVectorOfUInt8,
774 {dwarf_xmm15, dwarf_xmm15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
775 LLDB_INVALID_REGNUM},
776 nullptr,
777 nullptr,
778 nullptr,
779 0},
780 {"mxcsr",
781 nullptr,
782 4,
783 0,
784 eEncodingUint,
785 eFormatHex,
786 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
787 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
788 nullptr,
789 nullptr,
790 nullptr,
791 0},
792 {"ymm0",
793 nullptr,
794 32,
795 0,
796 eEncodingVector,
797 eFormatVectorOfUInt8,
798 {dwarf_ymm0, dwarf_ymm0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
799 LLDB_INVALID_REGNUM},
800 nullptr,
801 nullptr,
802 nullptr,
803 0},
804 {"ymm1",
805 nullptr,
806 32,
807 0,
808 eEncodingVector,
809 eFormatVectorOfUInt8,
810 {dwarf_ymm1, dwarf_ymm1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
811 LLDB_INVALID_REGNUM},
812 nullptr,
813 nullptr,
814 nullptr,
815 0},
816 {"ymm2",
817 nullptr,
818 32,
819 0,
820 eEncodingVector,
821 eFormatVectorOfUInt8,
822 {dwarf_ymm2, dwarf_ymm2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
823 LLDB_INVALID_REGNUM},
824 nullptr,
825 nullptr,
826 nullptr,
827 0},
828 {"ymm3",
829 nullptr,
830 32,
831 0,
832 eEncodingVector,
833 eFormatVectorOfUInt8,
834 {dwarf_ymm3, dwarf_ymm3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
835 LLDB_INVALID_REGNUM},
836 nullptr,
837 nullptr,
838 nullptr,
839 0},
840 {"ymm4",
841 nullptr,
842 32,
843 0,
844 eEncodingVector,
845 eFormatVectorOfUInt8,
846 {dwarf_ymm4, dwarf_ymm4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
847 LLDB_INVALID_REGNUM},
848 nullptr,
849 nullptr,
850 nullptr,
851 0},
852 {"ymm5",
853 nullptr,
854 32,
855 0,
856 eEncodingVector,
857 eFormatVectorOfUInt8,
858 {dwarf_ymm5, dwarf_ymm5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
859 LLDB_INVALID_REGNUM},
860 nullptr,
861 nullptr,
862 nullptr,
863 0},
864 {"ymm6",
865 nullptr,
866 32,
867 0,
868 eEncodingVector,
869 eFormatVectorOfUInt8,
870 {dwarf_ymm6, dwarf_ymm6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
871 LLDB_INVALID_REGNUM},
872 nullptr,
873 nullptr,
874 nullptr,
875 0},
876 {"ymm7",
877 nullptr,
878 32,
879 0,
880 eEncodingVector,
881 eFormatVectorOfUInt8,
882 {dwarf_ymm7, dwarf_ymm7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
883 LLDB_INVALID_REGNUM},
884 nullptr,
885 nullptr,
886 nullptr,
887 0},
888 {"ymm8",
889 nullptr,
890 32,
891 0,
892 eEncodingVector,
893 eFormatVectorOfUInt8,
894 {dwarf_ymm8, dwarf_ymm8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
895 LLDB_INVALID_REGNUM},
896 nullptr,
897 nullptr,
898 nullptr,
899 0},
900 {"ymm9",
901 nullptr,
902 32,
903 0,
904 eEncodingVector,
905 eFormatVectorOfUInt8,
906 {dwarf_ymm9, dwarf_ymm9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
907 LLDB_INVALID_REGNUM},
908 nullptr,
909 nullptr,
910 nullptr,
911 0},
912 {"ymm10",
913 nullptr,
914 32,
915 0,
916 eEncodingVector,
917 eFormatVectorOfUInt8,
918 {dwarf_ymm10, dwarf_ymm10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
919 LLDB_INVALID_REGNUM},
920 nullptr,
921 nullptr,
922 nullptr,
923 0},
924 {"ymm11",
925 nullptr,
926 32,
927 0,
928 eEncodingVector,
929 eFormatVectorOfUInt8,
930 {dwarf_ymm11, dwarf_ymm11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
931 LLDB_INVALID_REGNUM},
932 nullptr,
933 nullptr,
934 nullptr,
935 0},
936 {"ymm12",
937 nullptr,
938 32,
939 0,
940 eEncodingVector,
941 eFormatVectorOfUInt8,
942 {dwarf_ymm12, dwarf_ymm12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
943 LLDB_INVALID_REGNUM},
944 nullptr,
945 nullptr,
946 nullptr,
947 0},
948 {"ymm13",
949 nullptr,
950 32,
951 0,
952 eEncodingVector,
953 eFormatVectorOfUInt8,
954 {dwarf_ymm13, dwarf_ymm13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
955 LLDB_INVALID_REGNUM},
956 nullptr,
957 nullptr,
958 nullptr,
959 0},
960 {"ymm14",
961 nullptr,
962 32,
963 0,
964 eEncodingVector,
965 eFormatVectorOfUInt8,
966 {dwarf_ymm14, dwarf_ymm14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
967 LLDB_INVALID_REGNUM},
968 nullptr,
969 nullptr,
970 nullptr,
971 0},
972 {"ymm15",
973 nullptr,
974 32,
975 0,
976 eEncodingVector,
977 eFormatVectorOfUInt8,
978 {dwarf_ymm15, dwarf_ymm15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
979 LLDB_INVALID_REGNUM},
980 nullptr,
981 nullptr,
982 nullptr,
983 0},
984 {"bnd0",
985 nullptr,
986 16,
987 0,
988 eEncodingVector,
989 eFormatVectorOfUInt64,
990 {dwarf_bnd0, dwarf_bnd0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
991 LLDB_INVALID_REGNUM},
992 nullptr,
993 nullptr,
994 nullptr,
995 0},
996 {"bnd1",
997 nullptr,
998 16,
999 0,
1000 eEncodingVector,
1001 eFormatVectorOfUInt64,
1002 {dwarf_bnd1, dwarf_bnd1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1003 LLDB_INVALID_REGNUM},
1004 nullptr,
1005 nullptr,
1006 nullptr,
1007 0},
1008 {"bnd2",
1009 nullptr,
1010 16,
1011 0,
1012 eEncodingVector,
1013 eFormatVectorOfUInt64,
1014 {dwarf_bnd2, dwarf_bnd2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1015 LLDB_INVALID_REGNUM},
1016 nullptr,
1017 nullptr,
1018 nullptr,
1019 0},
1020 {"bnd3",
1021 nullptr,
1022 16,
1023 0,
1024 eEncodingVector,
1025 eFormatVectorOfUInt64,
1026 {dwarf_bnd3, dwarf_bnd3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1027 LLDB_INVALID_REGNUM},
1028 nullptr,
1029 nullptr,
1030 nullptr,
1031 0},
1032 {"bndcfgu",
1033 nullptr,
1034 8,
1035 0,
1036 eEncodingVector,
1037 eFormatVectorOfUInt8,
1038 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1039 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1040 nullptr,
1041 nullptr,
1042 nullptr,
1043 0},
1044 {"bndstatus",
1045 nullptr,
1046 8,
1047 0,
1048 eEncodingVector,
1049 eFormatVectorOfUInt8,
1050 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
1051 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},
1052 nullptr,
1053 nullptr,
1054 nullptr,
1055 0}};
1056
1057 static const uint32_t k_num_register_infos =
1058 llvm::array_lengthof(g_register_infos);
1059 static bool g_register_info_names_constified = false;
1060
1061 const lldb_private::RegisterInfo *
GetRegisterInfoArray(uint32_t & count)1062 ABISysV_x86_64::GetRegisterInfoArray(uint32_t &count) {
1063 // Make the C-string names and alt_names for the register infos into const
1064 // C-string values by having the ConstString unique the names in the global
1065 // constant C-string pool.
1066 if (!g_register_info_names_constified) {
1067 g_register_info_names_constified = true;
1068 for (uint32_t i = 0; i < k_num_register_infos; ++i) {
1069 if (g_register_infos[i].name)
1070 g_register_infos[i].name =
1071 ConstString(g_register_infos[i].name).GetCString();
1072 if (g_register_infos[i].alt_name)
1073 g_register_infos[i].alt_name =
1074 ConstString(g_register_infos[i].alt_name).GetCString();
1075 }
1076 }
1077 count = k_num_register_infos;
1078 return g_register_infos;
1079 }
1080
GetPointerReturnRegister(const char * & name)1081 bool ABISysV_x86_64::GetPointerReturnRegister(const char *&name) {
1082 name = "rax";
1083 return true;
1084 }
1085
GetRedZoneSize() const1086 size_t ABISysV_x86_64::GetRedZoneSize() const { return 128; }
1087
1088 //------------------------------------------------------------------
1089 // Static Functions
1090 //------------------------------------------------------------------
1091
1092 ABISP
CreateInstance(lldb::ProcessSP process_sp,const ArchSpec & arch)1093 ABISysV_x86_64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) {
1094 if (arch.GetTriple().getArch() == llvm::Triple::x86_64) {
1095 return ABISP(new ABISysV_x86_64(process_sp));
1096 }
1097 return ABISP();
1098 }
1099
PrepareTrivialCall(Thread & thread,addr_t sp,addr_t func_addr,addr_t return_addr,llvm::ArrayRef<addr_t> args) const1100 bool ABISysV_x86_64::PrepareTrivialCall(Thread &thread, addr_t sp,
1101 addr_t func_addr, addr_t return_addr,
1102 llvm::ArrayRef<addr_t> args) const {
1103 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1104
1105 if (log) {
1106 StreamString s;
1107 s.Printf("ABISysV_x86_64::PrepareTrivialCall (tid = 0x%" PRIx64
1108 ", sp = 0x%" PRIx64 ", func_addr = 0x%" PRIx64
1109 ", return_addr = 0x%" PRIx64,
1110 thread.GetID(), (uint64_t)sp, (uint64_t)func_addr,
1111 (uint64_t)return_addr);
1112
1113 for (size_t i = 0; i < args.size(); ++i)
1114 s.Printf(", arg%" PRIu64 " = 0x%" PRIx64, static_cast<uint64_t>(i + 1),
1115 args[i]);
1116 s.PutCString(")");
1117 log->PutString(s.GetString());
1118 }
1119
1120 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1121 if (!reg_ctx)
1122 return false;
1123
1124 const RegisterInfo *reg_info = nullptr;
1125
1126 if (args.size() > 6) // TODO handle more than 6 arguments
1127 return false;
1128
1129 for (size_t i = 0; i < args.size(); ++i) {
1130 reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric,
1131 LLDB_REGNUM_GENERIC_ARG1 + i);
1132 if (log)
1133 log->Printf("About to write arg%" PRIu64 " (0x%" PRIx64 ") into %s",
1134 static_cast<uint64_t>(i + 1), args[i], reg_info->name);
1135 if (!reg_ctx->WriteRegisterFromUnsigned(reg_info, args[i]))
1136 return false;
1137 }
1138
1139 // First, align the SP
1140
1141 if (log)
1142 log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64,
1143 (uint64_t)sp, (uint64_t)(sp & ~0xfull));
1144
1145 sp &= ~(0xfull); // 16-byte alignment
1146
1147 sp -= 8;
1148
1149 Status error;
1150 const RegisterInfo *pc_reg_info =
1151 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
1152 const RegisterInfo *sp_reg_info =
1153 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
1154 ProcessSP process_sp(thread.GetProcess());
1155
1156 RegisterValue reg_value;
1157 if (log)
1158 log->Printf("Pushing the return address onto the stack: 0x%" PRIx64
1159 ": 0x%" PRIx64,
1160 (uint64_t)sp, (uint64_t)return_addr);
1161
1162 // Save return address onto the stack
1163 if (!process_sp->WritePointerToMemory(sp, return_addr, error))
1164 return false;
1165
1166 // %rsp is set to the actual stack value.
1167
1168 if (log)
1169 log->Printf("Writing SP: 0x%" PRIx64, (uint64_t)sp);
1170
1171 if (!reg_ctx->WriteRegisterFromUnsigned(sp_reg_info, sp))
1172 return false;
1173
1174 // %rip is set to the address of the called function.
1175
1176 if (log)
1177 log->Printf("Writing IP: 0x%" PRIx64, (uint64_t)func_addr);
1178
1179 if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_info, func_addr))
1180 return false;
1181
1182 return true;
1183 }
1184
ReadIntegerArgument(Scalar & scalar,unsigned int bit_width,bool is_signed,Thread & thread,uint32_t * argument_register_ids,unsigned int & current_argument_register,addr_t & current_stack_argument)1185 static bool ReadIntegerArgument(Scalar &scalar, unsigned int bit_width,
1186 bool is_signed, Thread &thread,
1187 uint32_t *argument_register_ids,
1188 unsigned int ¤t_argument_register,
1189 addr_t ¤t_stack_argument) {
1190 if (bit_width > 64)
1191 return false; // Scalar can't hold large integer arguments
1192
1193 if (current_argument_register < 6) {
1194 scalar = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
1195 argument_register_ids[current_argument_register], 0);
1196 current_argument_register++;
1197 if (is_signed)
1198 scalar.SignExtend(bit_width);
1199 } else {
1200 uint32_t byte_size = (bit_width + (8 - 1)) / 8;
1201 Status error;
1202 if (thread.GetProcess()->ReadScalarIntegerFromMemory(
1203 current_stack_argument, byte_size, is_signed, scalar, error)) {
1204 current_stack_argument += byte_size;
1205 return true;
1206 }
1207 return false;
1208 }
1209 return true;
1210 }
1211
GetArgumentValues(Thread & thread,ValueList & values) const1212 bool ABISysV_x86_64::GetArgumentValues(Thread &thread,
1213 ValueList &values) const {
1214 unsigned int num_values = values.GetSize();
1215 unsigned int value_index;
1216
1217 // Extract the register context so we can read arguments from registers
1218
1219 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1220
1221 if (!reg_ctx)
1222 return false;
1223
1224 // Get the pointer to the first stack argument so we have a place to start
1225 // when reading data
1226
1227 addr_t sp = reg_ctx->GetSP(0);
1228
1229 if (!sp)
1230 return false;
1231
1232 addr_t current_stack_argument = sp + 8; // jump over return address
1233
1234 uint32_t argument_register_ids[6];
1235
1236 argument_register_ids[0] =
1237 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1)
1238 ->kinds[eRegisterKindLLDB];
1239 argument_register_ids[1] =
1240 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG2)
1241 ->kinds[eRegisterKindLLDB];
1242 argument_register_ids[2] =
1243 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG3)
1244 ->kinds[eRegisterKindLLDB];
1245 argument_register_ids[3] =
1246 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG4)
1247 ->kinds[eRegisterKindLLDB];
1248 argument_register_ids[4] =
1249 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG5)
1250 ->kinds[eRegisterKindLLDB];
1251 argument_register_ids[5] =
1252 reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG6)
1253 ->kinds[eRegisterKindLLDB];
1254
1255 unsigned int current_argument_register = 0;
1256
1257 for (value_index = 0; value_index < num_values; ++value_index) {
1258 Value *value = values.GetValueAtIndex(value_index);
1259
1260 if (!value)
1261 return false;
1262
1263 // We currently only support extracting values with Clang QualTypes. Do we
1264 // care about others?
1265 CompilerType compiler_type = value->GetCompilerType();
1266 llvm::Optional<uint64_t> bit_size = compiler_type.GetBitSize(&thread);
1267 if (!bit_size)
1268 return false;
1269 bool is_signed;
1270
1271 if (compiler_type.IsIntegerOrEnumerationType(is_signed)) {
1272 ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed, thread,
1273 argument_register_ids, current_argument_register,
1274 current_stack_argument);
1275 } else if (compiler_type.IsPointerType()) {
1276 ReadIntegerArgument(value->GetScalar(), *bit_size, false, thread,
1277 argument_register_ids, current_argument_register,
1278 current_stack_argument);
1279 }
1280 }
1281
1282 return true;
1283 }
1284
SetReturnValueObject(lldb::StackFrameSP & frame_sp,lldb::ValueObjectSP & new_value_sp)1285 Status ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp,
1286 lldb::ValueObjectSP &new_value_sp) {
1287 Status error;
1288 if (!new_value_sp) {
1289 error.SetErrorString("Empty value object for return value.");
1290 return error;
1291 }
1292
1293 CompilerType compiler_type = new_value_sp->GetCompilerType();
1294 if (!compiler_type) {
1295 error.SetErrorString("Null clang type for return value.");
1296 return error;
1297 }
1298
1299 Thread *thread = frame_sp->GetThread().get();
1300
1301 bool is_signed;
1302 uint32_t count;
1303 bool is_complex;
1304
1305 RegisterContext *reg_ctx = thread->GetRegisterContext().get();
1306
1307 bool set_it_simple = false;
1308 if (compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1309 compiler_type.IsPointerType()) {
1310 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName("rax", 0);
1311
1312 DataExtractor data;
1313 Status data_error;
1314 size_t num_bytes = new_value_sp->GetData(data, data_error);
1315 if (data_error.Fail()) {
1316 error.SetErrorStringWithFormat(
1317 "Couldn't convert return value to raw data: %s",
1318 data_error.AsCString());
1319 return error;
1320 }
1321 lldb::offset_t offset = 0;
1322 if (num_bytes <= 8) {
1323 uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
1324
1325 if (reg_ctx->WriteRegisterFromUnsigned(reg_info, raw_value))
1326 set_it_simple = true;
1327 } else {
1328 error.SetErrorString("We don't support returning longer than 64 bit "
1329 "integer values at present.");
1330 }
1331 } else if (compiler_type.IsFloatingPointType(count, is_complex)) {
1332 if (is_complex)
1333 error.SetErrorString(
1334 "We don't support returning complex values at present");
1335 else {
1336 llvm::Optional<uint64_t> bit_width =
1337 compiler_type.GetBitSize(frame_sp.get());
1338 if (!bit_width) {
1339 error.SetErrorString("can't get type size");
1340 return error;
1341 }
1342 if (*bit_width <= 64) {
1343 const RegisterInfo *xmm0_info =
1344 reg_ctx->GetRegisterInfoByName("xmm0", 0);
1345 RegisterValue xmm0_value;
1346 DataExtractor data;
1347 Status data_error;
1348 size_t num_bytes = new_value_sp->GetData(data, data_error);
1349 if (data_error.Fail()) {
1350 error.SetErrorStringWithFormat(
1351 "Couldn't convert return value to raw data: %s",
1352 data_error.AsCString());
1353 return error;
1354 }
1355
1356 unsigned char buffer[16];
1357 ByteOrder byte_order = data.GetByteOrder();
1358
1359 data.CopyByteOrderedData(0, num_bytes, buffer, 16, byte_order);
1360 xmm0_value.SetBytes(buffer, 16, byte_order);
1361 reg_ctx->WriteRegister(xmm0_info, xmm0_value);
1362 set_it_simple = true;
1363 } else {
1364 // FIXME - don't know how to do 80 bit long doubles yet.
1365 error.SetErrorString(
1366 "We don't support returning float values > 64 bits at present");
1367 }
1368 }
1369 }
1370
1371 if (!set_it_simple) {
1372 // Okay we've got a structure or something that doesn't fit in a simple
1373 // register. We should figure out where it really goes, but we don't
1374 // support this yet.
1375 error.SetErrorString("We only support setting simple integer and float "
1376 "return types at present.");
1377 }
1378
1379 return error;
1380 }
1381
GetReturnValueObjectSimple(Thread & thread,CompilerType & return_compiler_type) const1382 ValueObjectSP ABISysV_x86_64::GetReturnValueObjectSimple(
1383 Thread &thread, CompilerType &return_compiler_type) const {
1384 ValueObjectSP return_valobj_sp;
1385 Value value;
1386
1387 if (!return_compiler_type)
1388 return return_valobj_sp;
1389
1390 // value.SetContext (Value::eContextTypeClangType, return_value_type);
1391 value.SetCompilerType(return_compiler_type);
1392
1393 RegisterContext *reg_ctx = thread.GetRegisterContext().get();
1394 if (!reg_ctx)
1395 return return_valobj_sp;
1396
1397 const uint32_t type_flags = return_compiler_type.GetTypeInfo();
1398 if (type_flags & eTypeIsScalar) {
1399 value.SetValueType(Value::eValueTypeScalar);
1400
1401 bool success = false;
1402 if (type_flags & eTypeIsInteger) {
1403 // Extract the register context so we can read arguments from registers
1404
1405 llvm::Optional<uint64_t> byte_size =
1406 return_compiler_type.GetByteSize(nullptr);
1407 if (!byte_size)
1408 return return_valobj_sp;
1409 uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(
1410 reg_ctx->GetRegisterInfoByName("rax", 0), 0);
1411 const bool is_signed = (type_flags & eTypeIsSigned) != 0;
1412 switch (*byte_size) {
1413 default:
1414 break;
1415
1416 case sizeof(uint64_t):
1417 if (is_signed)
1418 value.GetScalar() = (int64_t)(raw_value);
1419 else
1420 value.GetScalar() = (uint64_t)(raw_value);
1421 success = true;
1422 break;
1423
1424 case sizeof(uint32_t):
1425 if (is_signed)
1426 value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
1427 else
1428 value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
1429 success = true;
1430 break;
1431
1432 case sizeof(uint16_t):
1433 if (is_signed)
1434 value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
1435 else
1436 value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
1437 success = true;
1438 break;
1439
1440 case sizeof(uint8_t):
1441 if (is_signed)
1442 value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
1443 else
1444 value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
1445 success = true;
1446 break;
1447 }
1448 } else if (type_flags & eTypeIsFloat) {
1449 if (type_flags & eTypeIsComplex) {
1450 // Don't handle complex yet.
1451 } else {
1452 llvm::Optional<uint64_t> byte_size =
1453 return_compiler_type.GetByteSize(nullptr);
1454 if (byte_size && *byte_size <= sizeof(long double)) {
1455 const RegisterInfo *xmm0_info =
1456 reg_ctx->GetRegisterInfoByName("xmm0", 0);
1457 RegisterValue xmm0_value;
1458 if (reg_ctx->ReadRegister(xmm0_info, xmm0_value)) {
1459 DataExtractor data;
1460 if (xmm0_value.GetData(data)) {
1461 lldb::offset_t offset = 0;
1462 if (*byte_size == sizeof(float)) {
1463 value.GetScalar() = (float)data.GetFloat(&offset);
1464 success = true;
1465 } else if (*byte_size == sizeof(double)) {
1466 value.GetScalar() = (double)data.GetDouble(&offset);
1467 success = true;
1468 } else if (*byte_size == sizeof(long double)) {
1469 // Don't handle long double since that can be encoded as 80 bit
1470 // floats...
1471 }
1472 }
1473 }
1474 }
1475 }
1476 }
1477
1478 if (success)
1479 return_valobj_sp = ValueObjectConstResult::Create(
1480 thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
1481 } else if (type_flags & eTypeIsPointer) {
1482 unsigned rax_id =
1483 reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
1484 value.GetScalar() =
1485 (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,
1486 0);
1487 value.SetValueType(Value::eValueTypeScalar);
1488 return_valobj_sp = ValueObjectConstResult::Create(
1489 thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
1490 } else if (type_flags & eTypeIsVector) {
1491 llvm::Optional<uint64_t> byte_size =
1492 return_compiler_type.GetByteSize(nullptr);
1493 if (byte_size && *byte_size > 0) {
1494 const RegisterInfo *altivec_reg =
1495 reg_ctx->GetRegisterInfoByName("xmm0", 0);
1496 if (altivec_reg == nullptr)
1497 altivec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
1498
1499 if (altivec_reg) {
1500 if (*byte_size <= altivec_reg->byte_size) {
1501 ProcessSP process_sp(thread.GetProcess());
1502 if (process_sp) {
1503 std::unique_ptr<DataBufferHeap> heap_data_ap(
1504 new DataBufferHeap(*byte_size, 0));
1505 const ByteOrder byte_order = process_sp->GetByteOrder();
1506 RegisterValue reg_value;
1507 if (reg_ctx->ReadRegister(altivec_reg, reg_value)) {
1508 Status error;
1509 if (reg_value.GetAsMemoryData(
1510 altivec_reg, heap_data_ap->GetBytes(),
1511 heap_data_ap->GetByteSize(), byte_order, error)) {
1512 DataExtractor data(DataBufferSP(heap_data_ap.release()),
1513 byte_order, process_sp->GetTarget()
1514 .GetArchitecture()
1515 .GetAddressByteSize());
1516 return_valobj_sp = ValueObjectConstResult::Create(
1517 &thread, return_compiler_type, ConstString(""), data);
1518 }
1519 }
1520 }
1521 } else if (*byte_size <= altivec_reg->byte_size * 2) {
1522 const RegisterInfo *altivec_reg2 =
1523 reg_ctx->GetRegisterInfoByName("xmm1", 0);
1524 if (altivec_reg2) {
1525 ProcessSP process_sp(thread.GetProcess());
1526 if (process_sp) {
1527 std::unique_ptr<DataBufferHeap> heap_data_ap(
1528 new DataBufferHeap(*byte_size, 0));
1529 const ByteOrder byte_order = process_sp->GetByteOrder();
1530 RegisterValue reg_value;
1531 RegisterValue reg_value2;
1532 if (reg_ctx->ReadRegister(altivec_reg, reg_value) &&
1533 reg_ctx->ReadRegister(altivec_reg2, reg_value2)) {
1534
1535 Status error;
1536 if (reg_value.GetAsMemoryData(
1537 altivec_reg, heap_data_ap->GetBytes(),
1538 altivec_reg->byte_size, byte_order, error) &&
1539 reg_value2.GetAsMemoryData(
1540 altivec_reg2,
1541 heap_data_ap->GetBytes() + altivec_reg->byte_size,
1542 heap_data_ap->GetByteSize() - altivec_reg->byte_size,
1543 byte_order, error)) {
1544 DataExtractor data(DataBufferSP(heap_data_ap.release()),
1545 byte_order, process_sp->GetTarget()
1546 .GetArchitecture()
1547 .GetAddressByteSize());
1548 return_valobj_sp = ValueObjectConstResult::Create(
1549 &thread, return_compiler_type, ConstString(""), data);
1550 }
1551 }
1552 }
1553 }
1554 }
1555 }
1556 }
1557 }
1558
1559 return return_valobj_sp;
1560 }
1561
GetReturnValueObjectImpl(Thread & thread,CompilerType & return_compiler_type) const1562 ValueObjectSP ABISysV_x86_64::GetReturnValueObjectImpl(
1563 Thread &thread, CompilerType &return_compiler_type) const {
1564 ValueObjectSP return_valobj_sp;
1565
1566 if (!return_compiler_type)
1567 return return_valobj_sp;
1568
1569 ExecutionContext exe_ctx(thread.shared_from_this());
1570 return_valobj_sp = GetReturnValueObjectSimple(thread, return_compiler_type);
1571 if (return_valobj_sp)
1572 return return_valobj_sp;
1573
1574 RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
1575 if (!reg_ctx_sp)
1576 return return_valobj_sp;
1577
1578 llvm::Optional<uint64_t> bit_width = return_compiler_type.GetBitSize(&thread);
1579 if (!bit_width)
1580 return return_valobj_sp;
1581 if (return_compiler_type.IsAggregateType()) {
1582 Target *target = exe_ctx.GetTargetPtr();
1583 bool is_memory = true;
1584 if (*bit_width <= 128) {
1585 ByteOrder target_byte_order = target->GetArchitecture().GetByteOrder();
1586 DataBufferSP data_sp(new DataBufferHeap(16, 0));
1587 DataExtractor return_ext(data_sp, target_byte_order,
1588 target->GetArchitecture().GetAddressByteSize());
1589
1590 const RegisterInfo *rax_info =
1591 reg_ctx_sp->GetRegisterInfoByName("rax", 0);
1592 const RegisterInfo *rdx_info =
1593 reg_ctx_sp->GetRegisterInfoByName("rdx", 0);
1594 const RegisterInfo *xmm0_info =
1595 reg_ctx_sp->GetRegisterInfoByName("xmm0", 0);
1596 const RegisterInfo *xmm1_info =
1597 reg_ctx_sp->GetRegisterInfoByName("xmm1", 0);
1598
1599 RegisterValue rax_value, rdx_value, xmm0_value, xmm1_value;
1600 reg_ctx_sp->ReadRegister(rax_info, rax_value);
1601 reg_ctx_sp->ReadRegister(rdx_info, rdx_value);
1602 reg_ctx_sp->ReadRegister(xmm0_info, xmm0_value);
1603 reg_ctx_sp->ReadRegister(xmm1_info, xmm1_value);
1604
1605 DataExtractor rax_data, rdx_data, xmm0_data, xmm1_data;
1606
1607 rax_value.GetData(rax_data);
1608 rdx_value.GetData(rdx_data);
1609 xmm0_value.GetData(xmm0_data);
1610 xmm1_value.GetData(xmm1_data);
1611
1612 uint32_t fp_bytes =
1613 0; // Tracks how much of the xmm registers we've consumed so far
1614 uint32_t integer_bytes =
1615 0; // Tracks how much of the rax/rds registers we've consumed so far
1616
1617 const uint32_t num_children = return_compiler_type.GetNumFields();
1618
1619 // Since we are in the small struct regime, assume we are not in memory.
1620 is_memory = false;
1621
1622 for (uint32_t idx = 0; idx < num_children; idx++) {
1623 std::string name;
1624 uint64_t field_bit_offset = 0;
1625 bool is_signed;
1626 bool is_complex;
1627 uint32_t count;
1628
1629 CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex(
1630 idx, name, &field_bit_offset, nullptr, nullptr);
1631 llvm::Optional<uint64_t> field_bit_width =
1632 field_compiler_type.GetBitSize(&thread);
1633
1634 // if we don't know the size of the field (e.g. invalid type), just
1635 // bail out
1636 if (!field_bit_width || *field_bit_width == 0)
1637 break;
1638
1639 // If there are any unaligned fields, this is stored in memory.
1640 if (field_bit_offset % *field_bit_width != 0) {
1641 is_memory = true;
1642 break;
1643 }
1644
1645 uint32_t field_byte_width = *field_bit_width / 8;
1646 uint32_t field_byte_offset = field_bit_offset / 8;
1647
1648 DataExtractor *copy_from_extractor = nullptr;
1649 uint32_t copy_from_offset = 0;
1650
1651 if (field_compiler_type.IsIntegerOrEnumerationType(is_signed) ||
1652 field_compiler_type.IsPointerType()) {
1653 if (integer_bytes < 8) {
1654 if (integer_bytes + field_byte_width <= 8) {
1655 // This is in RAX, copy from register to our result structure:
1656 copy_from_extractor = &rax_data;
1657 copy_from_offset = integer_bytes;
1658 integer_bytes += field_byte_width;
1659 } else {
1660 // The next field wouldn't fit in the remaining space, so we
1661 // pushed it to rdx.
1662 copy_from_extractor = &rdx_data;
1663 copy_from_offset = 0;
1664 integer_bytes = 8 + field_byte_width;
1665 }
1666 } else if (integer_bytes + field_byte_width <= 16) {
1667 copy_from_extractor = &rdx_data;
1668 copy_from_offset = integer_bytes - 8;
1669 integer_bytes += field_byte_width;
1670 } else {
1671 // The last field didn't fit. I can't see how that would happen
1672 // w/o the overall size being greater than 16 bytes. For now,
1673 // return a nullptr return value object.
1674 return return_valobj_sp;
1675 }
1676 } else if (field_compiler_type.IsFloatingPointType(count, is_complex)) {
1677 // Structs with long doubles are always passed in memory.
1678 if (*field_bit_width == 128) {
1679 is_memory = true;
1680 break;
1681 } else if (*field_bit_width == 64) {
1682 // These have to be in a single xmm register.
1683 if (fp_bytes == 0)
1684 copy_from_extractor = &xmm0_data;
1685 else
1686 copy_from_extractor = &xmm1_data;
1687
1688 copy_from_offset = 0;
1689 fp_bytes += field_byte_width;
1690 } else if (*field_bit_width == 32) {
1691 // This one is kind of complicated. If we are in an "eightbyte"
1692 // with another float, we'll be stuffed into an xmm register with
1693 // it. If we are in an "eightbyte" with one or more ints, then we
1694 // will be stuffed into the appropriate GPR with them.
1695 bool in_gpr;
1696 if (field_byte_offset % 8 == 0) {
1697 // We are at the beginning of one of the eightbytes, so check the
1698 // next element (if any)
1699 if (idx == num_children - 1)
1700 in_gpr = false;
1701 else {
1702 uint64_t next_field_bit_offset = 0;
1703 CompilerType next_field_compiler_type =
1704 return_compiler_type.GetFieldAtIndex(idx + 1, name,
1705 &next_field_bit_offset,
1706 nullptr, nullptr);
1707 if (next_field_compiler_type.IsIntegerOrEnumerationType(
1708 is_signed))
1709 in_gpr = true;
1710 else {
1711 copy_from_offset = 0;
1712 in_gpr = false;
1713 }
1714 }
1715 } else if (field_byte_offset % 4 == 0) {
1716 // We are inside of an eightbyte, so see if the field before us
1717 // is floating point: This could happen if somebody put padding
1718 // in the structure.
1719 if (idx == 0)
1720 in_gpr = false;
1721 else {
1722 uint64_t prev_field_bit_offset = 0;
1723 CompilerType prev_field_compiler_type =
1724 return_compiler_type.GetFieldAtIndex(idx - 1, name,
1725 &prev_field_bit_offset,
1726 nullptr, nullptr);
1727 if (prev_field_compiler_type.IsIntegerOrEnumerationType(
1728 is_signed))
1729 in_gpr = true;
1730 else {
1731 copy_from_offset = 4;
1732 in_gpr = false;
1733 }
1734 }
1735 } else {
1736 is_memory = true;
1737 continue;
1738 }
1739
1740 // Okay, we've figured out whether we are in GPR or XMM, now figure
1741 // out which one.
1742 if (in_gpr) {
1743 if (integer_bytes < 8) {
1744 // This is in RAX, copy from register to our result structure:
1745 copy_from_extractor = &rax_data;
1746 copy_from_offset = integer_bytes;
1747 integer_bytes += field_byte_width;
1748 } else {
1749 copy_from_extractor = &rdx_data;
1750 copy_from_offset = integer_bytes - 8;
1751 integer_bytes += field_byte_width;
1752 }
1753 } else {
1754 if (fp_bytes < 8)
1755 copy_from_extractor = &xmm0_data;
1756 else
1757 copy_from_extractor = &xmm1_data;
1758
1759 fp_bytes += field_byte_width;
1760 }
1761 }
1762 }
1763
1764 // These two tests are just sanity checks. If I somehow get the type
1765 // calculation wrong above it is better to just return nothing than to
1766 // assert or crash.
1767 if (!copy_from_extractor)
1768 return return_valobj_sp;
1769 if (copy_from_offset + field_byte_width >
1770 copy_from_extractor->GetByteSize())
1771 return return_valobj_sp;
1772
1773 copy_from_extractor->CopyByteOrderedData(
1774 copy_from_offset, field_byte_width,
1775 data_sp->GetBytes() + field_byte_offset, field_byte_width,
1776 target_byte_order);
1777 }
1778
1779 if (!is_memory) {
1780 // The result is in our data buffer. Let's make a variable object out
1781 // of it:
1782 return_valobj_sp = ValueObjectConstResult::Create(
1783 &thread, return_compiler_type, ConstString(""), return_ext);
1784 }
1785 }
1786
1787 // FIXME: This is just taking a guess, rax may very well no longer hold the
1788 // return storage location.
1789 // If we are going to do this right, when we make a new frame we should
1790 // check to see if it uses a memory return, and if we are at the first
1791 // instruction and if so stash away the return location. Then we would
1792 // only return the memory return value if we know it is valid.
1793
1794 if (is_memory) {
1795 unsigned rax_id =
1796 reg_ctx_sp->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
1797 lldb::addr_t storage_addr =
1798 (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id,
1799 0);
1800 return_valobj_sp = ValueObjectMemory::Create(
1801 &thread, "", Address(storage_addr, nullptr), return_compiler_type);
1802 }
1803 }
1804
1805 return return_valobj_sp;
1806 }
1807
1808 // This defines the CFA as rsp+8
1809 // the saved pc is at CFA-8 (i.e. rsp+0)
1810 // The saved rsp is CFA+0
1811
CreateFunctionEntryUnwindPlan(UnwindPlan & unwind_plan)1812 bool ABISysV_x86_64::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) {
1813 unwind_plan.Clear();
1814 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1815
1816 uint32_t sp_reg_num = dwarf_rsp;
1817 uint32_t pc_reg_num = dwarf_rip;
1818
1819 UnwindPlan::RowSP row(new UnwindPlan::Row);
1820 row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 8);
1821 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false);
1822 row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
1823 unwind_plan.AppendRow(row);
1824 unwind_plan.SetSourceName("x86_64 at-func-entry default");
1825 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1826 return true;
1827 }
1828
1829 // This defines the CFA as rbp+16
1830 // The saved pc is at CFA-8 (i.e. rbp+8)
1831 // The saved rbp is at CFA-16 (i.e. rbp+0)
1832 // The saved rsp is CFA+0
1833
CreateDefaultUnwindPlan(UnwindPlan & unwind_plan)1834 bool ABISysV_x86_64::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) {
1835 unwind_plan.Clear();
1836 unwind_plan.SetRegisterKind(eRegisterKindDWARF);
1837
1838 uint32_t fp_reg_num = dwarf_rbp;
1839 uint32_t sp_reg_num = dwarf_rsp;
1840 uint32_t pc_reg_num = dwarf_rip;
1841
1842 UnwindPlan::RowSP row(new UnwindPlan::Row);
1843
1844 const int32_t ptr_size = 8;
1845 row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_rbp, 2 * ptr_size);
1846 row->SetOffset(0);
1847
1848 row->SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
1849 row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
1850 row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true);
1851
1852 unwind_plan.AppendRow(row);
1853 unwind_plan.SetSourceName("x86_64 default unwind plan");
1854 unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
1855 unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1856 return true;
1857 }
1858
RegisterIsVolatile(const RegisterInfo * reg_info)1859 bool ABISysV_x86_64::RegisterIsVolatile(const RegisterInfo *reg_info) {
1860 return !RegisterIsCalleeSaved(reg_info);
1861 }
1862
1863 // See "Register Usage" in the
1864 // "System V Application Binary Interface"
1865 // "AMD64 Architecture Processor Supplement" (or "x86-64(tm) Architecture
1866 // Processor Supplement" in earlier revisions) (this doc is also commonly
1867 // referred to as the x86-64/AMD64 psABI) Edited by Michael Matz, Jan Hubicka,
1868 // Andreas Jaeger, and Mark Mitchell current version is 0.99.6 released
1869 // 2012-07-02 at http://refspecs.linuxfoundation.org/elf/x86-64-abi-0.99.pdf
1870 // It's being revised & updated at https://github.com/hjl-tools/x86-psABI/
1871
RegisterIsCalleeSaved(const RegisterInfo * reg_info)1872 bool ABISysV_x86_64::RegisterIsCalleeSaved(const RegisterInfo *reg_info) {
1873 if (!reg_info)
1874 return false;
1875 assert(reg_info->name != nullptr && "unnamed register?");
1876 std::string Name = std::string(reg_info->name);
1877 bool IsCalleeSaved =
1878 llvm::StringSwitch<bool>(Name)
1879 .Cases("r12", "r13", "r14", "r15", "rbp", "ebp", "rbx", "ebx", true)
1880 .Cases("rip", "eip", "rsp", "esp", "sp", "fp", "pc", true)
1881 .Default(false);
1882 return IsCalleeSaved;
1883 }
1884
Initialize()1885 void ABISysV_x86_64::Initialize() {
1886 PluginManager::RegisterPlugin(
1887 GetPluginNameStatic(), "System V ABI for x86_64 targets", CreateInstance);
1888 }
1889
Terminate()1890 void ABISysV_x86_64::Terminate() {
1891 PluginManager::UnregisterPlugin(CreateInstance);
1892 }
1893
GetPluginNameStatic()1894 lldb_private::ConstString ABISysV_x86_64::GetPluginNameStatic() {
1895 static ConstString g_name("sysv-x86_64");
1896 return g_name;
1897 }
1898
1899 //------------------------------------------------------------------
1900 // PluginInterface protocol
1901 //------------------------------------------------------------------
1902
GetPluginName()1903 lldb_private::ConstString ABISysV_x86_64::GetPluginName() {
1904 return GetPluginNameStatic();
1905 }
1906
GetPluginVersion()1907 uint32_t ABISysV_x86_64::GetPluginVersion() { return 1; }
1908