23#include "llvm/Support/MathExtras.h"
36 UNWIND_IS_NOT_FUNCTION_START = 0x80000000, UNWIND_HAS_LSDA = 0x40000000,
37 UNWIND_PERSONALITY_MASK = 0x30000000,
41 UNWIND_X86_MODE_MASK = 0x0F000000,
42 UNWIND_X86_MODE_EBP_FRAME = 0x01000000,
43 UNWIND_X86_MODE_STACK_IMMD = 0x02000000,
44 UNWIND_X86_MODE_STACK_IND = 0x03000000,
45 UNWIND_X86_MODE_DWARF = 0x04000000,
47 UNWIND_X86_EBP_FRAME_REGISTERS = 0x00007FFF,
48 UNWIND_X86_EBP_FRAME_OFFSET = 0x00FF0000,
50 UNWIND_X86_FRAMELESS_STACK_SIZE = 0x00FF0000,
51 UNWIND_X86_FRAMELESS_STACK_ADJUST = 0x0000E000,
52 UNWIND_X86_FRAMELESS_STACK_REG_COUNT = 0x00001C00,
53 UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF,
55 UNWIND_X86_DWARF_SECTION_OFFSET = 0x00FFFFFF,
69 UNWIND_X86_64_MODE_MASK = 0x0F000000,
70 UNWIND_X86_64_MODE_RBP_FRAME = 0x01000000,
71 UNWIND_X86_64_MODE_STACK_IMMD = 0x02000000,
72 UNWIND_X86_64_MODE_STACK_IND = 0x03000000,
73 UNWIND_X86_64_MODE_DWARF = 0x04000000,
75 UNWIND_X86_64_RBP_FRAME_REGISTERS = 0x00007FFF,
76 UNWIND_X86_64_RBP_FRAME_OFFSET = 0x00FF0000,
78 UNWIND_X86_64_FRAMELESS_STACK_SIZE = 0x00FF0000,
79 UNWIND_X86_64_FRAMELESS_STACK_ADJUST = 0x0000E000,
80 UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT = 0x00001C00,
81 UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF,
83 UNWIND_X86_64_DWARF_SECTION_OFFSET = 0x00FFFFFF,
97 UNWIND_ARM64_MODE_MASK = 0x0F000000,
98 UNWIND_ARM64_MODE_FRAMELESS = 0x02000000,
99 UNWIND_ARM64_MODE_DWARF = 0x03000000,
100 UNWIND_ARM64_MODE_FRAME = 0x04000000,
102 UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001,
103 UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002,
104 UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004,
105 UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008,
106 UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010,
107 UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100,
108 UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200,
109 UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400,
110 UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800,
112 UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK = 0x00FFF000,
113 UNWIND_ARM64_DWARF_SECTION_OFFSET = 0x00FFFFFF,
117 UNWIND_ARM_MODE_MASK = 0x0F000000,
118 UNWIND_ARM_MODE_FRAME = 0x01000000,
119 UNWIND_ARM_MODE_FRAME_D = 0x02000000,
120 UNWIND_ARM_MODE_DWARF = 0x04000000,
122 UNWIND_ARM_FRAME_STACK_ADJUST_MASK = 0x00C00000,
124 UNWIND_ARM_FRAME_FIRST_PUSH_R4 = 0x00000001,
125 UNWIND_ARM_FRAME_FIRST_PUSH_R5 = 0x00000002,
126 UNWIND_ARM_FRAME_FIRST_PUSH_R6 = 0x00000004,
128 UNWIND_ARM_FRAME_SECOND_PUSH_R8 = 0x00000008,
129 UNWIND_ARM_FRAME_SECOND_PUSH_R9 = 0x00000010,
130 UNWIND_ARM_FRAME_SECOND_PUSH_R10 = 0x00000020,
131 UNWIND_ARM_FRAME_SECOND_PUSH_R11 = 0x00000040,
132 UNWIND_ARM_FRAME_SECOND_PUSH_R12 = 0x00000080,
134 UNWIND_ARM_FRAME_D_REG_COUNT_MASK = 0x00000700,
136 UNWIND_ARM_DWARF_SECTION_OFFSET = 0x00FFFFFF,
140#ifndef UNWIND_SECOND_LEVEL_REGULAR
141#define UNWIND_SECOND_LEVEL_REGULAR 2
144#ifndef UNWIND_SECOND_LEVEL_COMPRESSED
145#define UNWIND_SECOND_LEVEL_COMPRESSED 3
148#ifndef UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET
149#define UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(entry) (entry & 0x00FFFFFF)
152#ifndef UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX
153#define UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX(entry) \
154 ((entry >> 24) & 0xFF)
157#define EXTRACT_BITS(value, mask) \
158 ((value >> llvm::countr_zero(static_cast<uint32_t>(mask))) & \
159 (((1 << llvm::popcount(static_cast<uint32_t>(mask)))) - 1))
193 arch.GetAddressByteSize());
194 LLDB_LOGF(log,
"Got compact unwind encoding 0x%x for function %s",
202 addr_t func_range_start_file_addr =
204 m_objfile.GetBaseAddress().GetFileAddress();
213 if (arch.GetTriple().getArch() == llvm::Triple::x86_64) {
217 if (arch.GetTriple().getArch() == llvm::Triple::aarch64 ||
218 arch.GetTriple().getArch() == llvm::Triple::aarch64_32) {
221 if (arch.GetTriple().getArch() == llvm::Triple::x86) {
224 if (arch.GetTriple().getArch() == llvm::Triple::arm ||
225 arch.GetTriple().getArch() == llvm::Triple::thumb) {
246 std::lock_guard<std::mutex> guard(
m_mutex);
258 log,
"Reading compact unwind first-level indexes");
264 if (process_sp.get() ==
nullptr)
267 std::make_shared<DataBufferHeap>(
m_section_sp->GetByteSize(), 0);
269 if (process_sp->ReadMemory(
270 m_section_sp->GetLoadBaseAddress(&process_sp->GetTarget()),
276 process_sp->GetTarget().GetArchitecture().GetAddressByteSize());
278 process_sp->GetTarget().GetArchitecture().GetByteOrder());
321 "Invalid offset encountered in compact unwind info, skipping");
337 bool clear_address_zeroth_bit =
false;
339 if (arch.GetTriple().getArch() == llvm::Triple::arm ||
340 arch.GetTriple().getArch() == llvm::Triple::thumb)
341 clear_address_zeroth_bit =
true;
344 offset = indexSectionOffset;
345 for (uint32_t idx = 0; idx < indexCount; idx++) {
346 uint32_t function_offset =
348 uint32_t second_level_offset =
350 uint32_t lsda_offset =
353 if (second_level_offset >
m_section_sp->GetByteSize() ||
358 if (clear_address_zeroth_bit)
359 function_offset &= ~1ull;
370 if (second_level_offset == 0) {
384 uint32_t function_offset) {
392 uint32_t high = lsda_count;
394 uint32_t mid = (low + high) / 2;
395 offset_t offset = first_entry + (mid * 8);
396 uint32_t mid_func_offset =
399 if (mid_func_offset == function_offset) {
400 return mid_lsda_offset;
402 if (mid_func_offset < function_offset) {
412 uint32_t entry_page_offset, uint32_t entry_count, uint32_t function_offset,
413 uint32_t *entry_func_start_offset, uint32_t *entry_func_end_offset) {
419 offset_t first_entry = entry_page_offset;
422 uint32_t high = entry_count;
423 uint32_t last = high - 1;
425 uint32_t mid = (low + high) / 2;
426 offset_t offset = first_entry + (mid * 8);
427 uint32_t mid_func_offset =
429 uint32_t next_func_offset = 0;
431 offset = first_entry + ((mid + 1) * 8);
434 if (mid_func_offset <= function_offset) {
435 if (mid == last || (next_func_offset > function_offset)) {
436 if (entry_func_start_offset)
437 *entry_func_start_offset = mid_func_offset;
438 if (mid != last && entry_func_end_offset)
439 *entry_func_end_offset = next_func_offset;
440 return first_entry + (mid * 8);
452 uint32_t entry_page_offset, uint32_t entry_count,
453 uint32_t function_offset_to_find, uint32_t function_offset_base,
454 uint32_t *entry_func_start_offset, uint32_t *entry_func_end_offset) {
455 offset_t first_entry = entry_page_offset;
458 uint32_t high = entry_count;
459 uint32_t last = high - 1;
461 uint32_t mid = (low + high) / 2;
462 offset_t offset = first_entry + (mid * 4);
465 mid_func_offset += function_offset_base;
466 uint32_t next_func_offset = 0;
468 offset = first_entry + ((mid + 1) * 4);
471 next_func_offset += function_offset_base;
473 if (mid_func_offset <= function_offset_to_find) {
474 if (mid == last || (next_func_offset > function_offset_to_find)) {
475 if (entry_func_start_offset)
476 *entry_func_start_offset = mid_func_offset;
477 if (mid != last && entry_func_end_offset)
478 *entry_func_end_offset = next_func_offset;
504 if (text_sect.get()) {
505 text_section_file_address = text_sect->GetFileAddress();
517 std::vector<UnwindIndex>::const_iterator it;
528 if (it->sentinal_entry) {
532 auto next_it = it + 1;
540 offset_t second_page_offset = it->second_level;
541 offset_t lsda_array_start = it->lsda_array_start;
542 offset_t lsda_array_count = (it->lsda_array_end - it->lsda_array_start) / 8;
544 offset_t offset = second_page_offset;
559 uint16_t entry_page_offset =
564 second_page_offset + entry_page_offset, entry_count, function_offset,
572 if (unwind_info.
encoding & UNWIND_HAS_LSDA) {
576 lsda_array_start, lsda_array_count, function_offset);
577 addr_t objfile_base_address =
578 m_objfile.GetBaseAddress().GetFileAddress();
580 objfile_base_address + lsda_offset, sl);
583 if (unwind_info.
encoding & UNWIND_PERSONALITY_MASK) {
584 uint32_t personality_index =
587 if (personality_index > 0) {
591 offset += 4 * personality_index;
595 addr_t objfile_base_address =
596 m_objfile.GetBaseAddress().GetFileAddress();
598 objfile_base_address + personality_offset, sl);
621 uint16_t entry_page_offset =
624 uint16_t encodings_page_offset =
626 uint16_t encodings_count =
630 second_page_offset + entry_page_offset, entry_count, function_offset,
638 uint32_t encoding = 0;
641 (encoding_index *
sizeof(uint32_t));
645 uint32_t page_specific_entry_index =
647 offset = second_page_offset + encodings_page_offset +
648 (page_specific_entry_index *
sizeof(uint32_t));
656 if (unwind_info.
encoding & UNWIND_HAS_LSDA) {
660 lsda_array_start, lsda_array_count, function_offset);
661 addr_t objfile_base_address =
662 m_objfile.GetBaseAddress().GetFileAddress();
664 objfile_base_address + lsda_offset, sl);
667 if (unwind_info.
encoding & UNWIND_PERSONALITY_MASK) {
668 uint32_t personality_index =
671 if (personality_index > 0) {
675 offset += 4 * personality_index;
679 addr_t objfile_base_address =
680 m_objfile.GetBaseAddress().GetFileAddress();
682 objfile_base_address + personality_offset, sl);
716 switch (unwind_regno) {
737 Address pc_or_function_start) {
746 const int wordsize = 8;
747 int mode = function_info.
encoding & UNWIND_X86_64_MODE_MASK;
749 case UNWIND_X86_64_MODE_RBP_FRAME: {
754 wordsize * -2,
true);
756 wordsize * -1,
true);
759 uint32_t saved_registers_offset =
762 uint32_t saved_registers_locations =
765 saved_registers_offset += 2;
767 for (
int i = 0; i < 5; i++) {
768 uint32_t regnum = saved_registers_locations & 0x7;
779 wordsize * -saved_registers_offset,
true);
782 saved_registers_offset--;
783 saved_registers_locations >>= 3;
789 case UNWIND_X86_64_MODE_STACK_IND: {
796 case UNWIND_X86_64_MODE_STACK_IMMD: {
798 UNWIND_X86_64_FRAMELESS_STACK_SIZE);
800 function_info.
encoding, UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT);
802 function_info.
encoding, UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION);
804 if (mode == UNWIND_X86_64_MODE_STACK_IND &&
807 function_info.
encoding, UNWIND_X86_64_FRAMELESS_STACK_ADJUST);
812 function_info.
encoding, UNWIND_X86_64_FRAMELESS_STACK_SIZE);
819 subl_payload_addr.
Slide(offset_to_subl_insn);
821 uint64_t large_stack_size = process_sp->ReadUnsignedIntegerFromMemory(
823 if (large_stack_size != 0 &&
error.Success()) {
825 stack_size = large_stack_size + (stack_adjust * wordsize);
837 int32_t offset = mode == UNWIND_X86_64_MODE_STACK_IND
839 : stack_size * wordsize;
843 wordsize * -1,
true);
846 if (register_count > 0) {
855 int permunreg[6] = {0, 0, 0, 0, 0, 0};
860 switch (register_count) {
862 permunreg[0] = permutation / 120;
863 permutation -= (permunreg[0] * 120);
864 permunreg[1] = permutation / 24;
865 permutation -= (permunreg[1] * 24);
866 permunreg[2] = permutation / 6;
867 permutation -= (permunreg[2] * 6);
868 permunreg[3] = permutation / 2;
869 permutation -= (permunreg[3] * 2);
870 permunreg[4] = permutation;
874 permunreg[0] = permutation / 120;
875 permutation -= (permunreg[0] * 120);
876 permunreg[1] = permutation / 24;
877 permutation -= (permunreg[1] * 24);
878 permunreg[2] = permutation / 6;
879 permutation -= (permunreg[2] * 6);
880 permunreg[3] = permutation / 2;
881 permutation -= (permunreg[3] * 2);
882 permunreg[4] = permutation;
885 permunreg[0] = permutation / 60;
886 permutation -= (permunreg[0] * 60);
887 permunreg[1] = permutation / 12;
888 permutation -= (permunreg[1] * 12);
889 permunreg[2] = permutation / 3;
890 permutation -= (permunreg[2] * 3);
891 permunreg[3] = permutation;
894 permunreg[0] = permutation / 20;
895 permutation -= (permunreg[0] * 20);
896 permunreg[1] = permutation / 4;
897 permutation -= (permunreg[1] * 4);
898 permunreg[2] = permutation;
901 permunreg[0] = permutation / 5;
902 permutation -= (permunreg[0] * 5);
903 permunreg[1] = permutation;
906 permunreg[0] = permutation;
916 bool used[7] = {
false,
false,
false,
false,
false,
false,
false};
917 for (uint32_t i = 0; i < register_count; i++) {
919 for (
int j = 1; j < 7; j++) {
921 if (renum == permunreg[i]) {
931 uint32_t saved_registers_offset = 1;
932 saved_registers_offset++;
934 for (
int i = (
sizeof(registers) /
sizeof(
int)) - 1; i >= 0; i--) {
935 switch (registers[i]) {
946 wordsize * -saved_registers_offset,
true);
947 saved_registers_offset++;
956 case UNWIND_X86_64_MODE_DWARF: {
983 switch (unwind_regno) {
1004 Address pc_or_function_start) {
1013 const int wordsize = 4;
1014 int mode = function_info.
encoding & UNWIND_X86_MODE_MASK;
1016 case UNWIND_X86_MODE_EBP_FRAME: {
1025 uint32_t saved_registers_offset =
1028 uint32_t saved_registers_locations =
1031 saved_registers_offset += 2;
1033 for (
int i = 0; i < 5; i++) {
1034 uint32_t regnum = saved_registers_locations & 0x7;
1045 wordsize * -saved_registers_offset,
true);
1048 saved_registers_offset--;
1049 saved_registers_locations >>= 3;
1055 case UNWIND_X86_MODE_STACK_IND:
1056 case UNWIND_X86_MODE_STACK_IMMD: {
1057 uint32_t stack_size =
1060 function_info.
encoding, UNWIND_X86_FRAMELESS_STACK_REG_COUNT);
1062 function_info.
encoding, UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION);
1064 if (mode == UNWIND_X86_MODE_STACK_IND &&
1067 UNWIND_X86_FRAMELESS_STACK_ADJUST);
1071 uint32_t offset_to_subl_insn =
1079 subl_payload_addr.
Slide(offset_to_subl_insn);
1081 uint64_t large_stack_size = process_sp->ReadUnsignedIntegerFromMemory(
1083 if (large_stack_size != 0 &&
error.Success()) {
1085 stack_size = large_stack_size + (stack_adjust * wordsize);
1098 mode == UNWIND_X86_MODE_STACK_IND ? stack_size : stack_size * wordsize;
1104 if (register_count > 0) {
1113 int permunreg[6] = {0, 0, 0, 0, 0, 0};
1118 switch (register_count) {
1120 permunreg[0] = permutation / 120;
1121 permutation -= (permunreg[0] * 120);
1122 permunreg[1] = permutation / 24;
1123 permutation -= (permunreg[1] * 24);
1124 permunreg[2] = permutation / 6;
1125 permutation -= (permunreg[2] * 6);
1126 permunreg[3] = permutation / 2;
1127 permutation -= (permunreg[3] * 2);
1128 permunreg[4] = permutation;
1132 permunreg[0] = permutation / 120;
1133 permutation -= (permunreg[0] * 120);
1134 permunreg[1] = permutation / 24;
1135 permutation -= (permunreg[1] * 24);
1136 permunreg[2] = permutation / 6;
1137 permutation -= (permunreg[2] * 6);
1138 permunreg[3] = permutation / 2;
1139 permutation -= (permunreg[3] * 2);
1140 permunreg[4] = permutation;
1143 permunreg[0] = permutation / 60;
1144 permutation -= (permunreg[0] * 60);
1145 permunreg[1] = permutation / 12;
1146 permutation -= (permunreg[1] * 12);
1147 permunreg[2] = permutation / 3;
1148 permutation -= (permunreg[2] * 3);
1149 permunreg[3] = permutation;
1152 permunreg[0] = permutation / 20;
1153 permutation -= (permunreg[0] * 20);
1154 permunreg[1] = permutation / 4;
1155 permutation -= (permunreg[1] * 4);
1156 permunreg[2] = permutation;
1159 permunreg[0] = permutation / 5;
1160 permutation -= (permunreg[0] * 5);
1161 permunreg[1] = permutation;
1164 permunreg[0] = permutation;
1174 bool used[7] = {
false,
false,
false,
false,
false,
false,
false};
1175 for (uint32_t i = 0; i < register_count; i++) {
1177 for (
int j = 1; j < 7; j++) {
1179 if (renum == permunreg[i]) {
1189 uint32_t saved_registers_offset = 1;
1190 saved_registers_offset++;
1192 for (
int i = (
sizeof(registers) /
sizeof(
int)) - 1; i >= 0; i--) {
1193 switch (registers[i]) {
1204 wordsize * -saved_registers_offset,
true);
1205 saved_registers_offset++;
1215 case UNWIND_X86_MODE_DWARF: {
1296 Address pc_or_function_start) {
1305 const int wordsize = 8;
1306 int mode = function_info.
encoding & UNWIND_ARM64_MODE_MASK;
1308 if (mode == UNWIND_ARM64_MODE_DWARF)
1311 if (mode == UNWIND_ARM64_MODE_FRAMELESS) {
1312 uint32_t stack_size =
1314 UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK)) *
1329 if (mode != UNWIND_ARM64_MODE_FRAME)
1341 int reg_pairs_saved_count = 1;
1343 uint32_t saved_register_bits = function_info.
encoding & 0xfff;
1345 if (saved_register_bits & UNWIND_ARM64_FRAME_X19_X20_PAIR) {
1346 int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
1347 cfa_offset -= wordsize;
1350 cfa_offset -= wordsize;
1353 reg_pairs_saved_count++;
1356 if (saved_register_bits & UNWIND_ARM64_FRAME_X21_X22_PAIR) {
1357 int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
1358 cfa_offset -= wordsize;
1361 cfa_offset -= wordsize;
1364 reg_pairs_saved_count++;
1367 if (saved_register_bits & UNWIND_ARM64_FRAME_X23_X24_PAIR) {
1368 int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
1369 cfa_offset -= wordsize;
1372 cfa_offset -= wordsize;
1375 reg_pairs_saved_count++;
1378 if (saved_register_bits & UNWIND_ARM64_FRAME_X25_X26_PAIR) {
1379 int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
1380 cfa_offset -= wordsize;
1383 cfa_offset -= wordsize;
1386 reg_pairs_saved_count++;
1389 if (saved_register_bits & UNWIND_ARM64_FRAME_X27_X28_PAIR) {
1390 int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
1391 cfa_offset -= wordsize;
1394 cfa_offset -= wordsize;
1397 reg_pairs_saved_count++;
1404 if (saved_register_bits & UNWIND_ARM64_FRAME_D8_D9_PAIR) {
1405 reg_pairs_saved_count++;
1407 if (saved_register_bits & UNWIND_ARM64_FRAME_D10_D11_PAIR) {
1408 reg_pairs_saved_count++;
1410 if (saved_register_bits & UNWIND_ARM64_FRAME_D12_D13_PAIR) {
1411 reg_pairs_saved_count++;
1413 if (saved_register_bits & UNWIND_ARM64_FRAME_D14_D15_PAIR) {
1414 reg_pairs_saved_count++;
1424 Address pc_or_function_start) {
1433 const int wordsize = 4;
1434 int mode = function_info.
encoding & UNWIND_ARM_MODE_MASK;
1436 if (mode == UNWIND_ARM_MODE_DWARF)
1440 UNWIND_ARM_FRAME_STACK_ADJUST_MASK)) *
1444 (2 * wordsize) + stack_adjust);
1446 arm_r7, (wordsize * -2) - stack_adjust,
true);
1448 arm_pc, (wordsize * -1) - stack_adjust,
true);
1451 int cfa_offset = -stack_adjust - (2 * wordsize);
1453 uint32_t saved_register_bits = function_info.
encoding & 0xff;
1455 if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R6) {
1456 cfa_offset -= wordsize;
1460 if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R5) {
1461 cfa_offset -= wordsize;
1465 if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R4) {
1466 cfa_offset -= wordsize;
1470 if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R12) {
1471 cfa_offset -= wordsize;
1475 if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R11) {
1476 cfa_offset -= wordsize;
1480 if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R10) {
1481 cfa_offset -= wordsize;
1485 if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R9) {
1486 cfa_offset -= wordsize;
1490 if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R8) {
1491 cfa_offset -= wordsize;
1495 if (mode == UNWIND_ARM_MODE_FRAME_D) {
1496 uint32_t d_reg_bits =
1498 switch (d_reg_bits) {
static llvm::raw_ostream & error(Stream &strm)
uint32_t translate_to_eh_frame_regnum_x86_64(uint32_t unwind_regno)
#define EXTRACT_BITS(value, mask)
#define UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX(entry)
#define UNWIND_SECOND_LEVEL_REGULAR
#define UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(entry)
uint32_t translate_to_eh_frame_regnum_i386(uint32_t unwind_regno)
#define UNWIND_SECOND_LEVEL_COMPRESSED
#define LLDB_LOGF(log,...)
A section + offset based address range class.
A section + offset based address class.
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
bool ResolveAddressUsingFileSections(lldb::addr_t addr, const SectionList *sections)
Resolve a file virtual address using a section list.
void Clear()
Clear the object's state.
@ DumpStyleFileAddress
Display as the file address (if any).
@ DumpStyleResolvedDescriptionNoFunctionArguments
bool Slide(int64_t offset)
bool Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style=DumpStyleInvalid, uint32_t addr_byte_size=UINT32_MAX, bool all_ranges=false, std::optional< Stream::HighlightSettings > settings=std::nullopt) const
Dump a description of this object to a Stream.
lldb::addr_t GetFileAddress() const
Get the file address.
An architecture specification class.
bool CreateUnwindPlan_arm64(Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start)
bool CreateUnwindPlan_x86_64(Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start)
uint32_t BinarySearchCompressedSecondPage(uint32_t entry_page_offset, uint32_t entry_count, uint32_t function_offset_to_find, uint32_t function_offset_base, uint32_t *entry_func_start_offset, uint32_t *entry_func_end_offset)
bool IsValid(const lldb::ProcessSP &process_sp)
uint32_t GetLSDAForFunctionOffset(uint32_t lsda_offset, uint32_t lsda_count, uint32_t function_offset)
bool CreateUnwindPlan_armv7(Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start)
LazyBool m_indexes_computed
bool GetUnwindPlan(Target &target, Address addr, UnwindPlan &unwind_plan)
lldb::SectionSP m_section_sp
DataExtractor m_unwindinfo_data
bool CreateUnwindPlan_i386(Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start)
lldb::offset_t BinarySearchRegularSecondPage(uint32_t entry_page_offset, uint32_t entry_count, uint32_t function_offset, uint32_t *entry_func_start_offset, uint32_t *entry_func_end_offset)
std::vector< UnwindIndex > m_indexes
void ScanIndex(const lldb::ProcessSP &process_sp)
CompactUnwindInfo(ObjectFile &objfile, lldb::SectionSP §ion)
bool GetCompactUnwindInfoForFunction(Target &target, Address address, FunctionInfo &unwind_info)
lldb::WritableDataBufferSP m_section_contents_if_encrypted
UnwindHeader m_unwind_header
bool m_unwindinfo_data_computed
static void ReportError(std::string message, std::optional< lldb::user_id_t > debugger_id=std::nullopt, std::once_flag *once=nullptr)
Report error events.
A plug-in interface definition class for object file parsers.
lldb::SectionSP FindSectionByType(lldb::SectionType sect_type, bool check_children, size_t start_idx=0) const
const char * GetData() const
const lldb::ProcessSP & GetProcessSP() const
void SetIsRegisterPlusOffset(uint32_t reg_num, int32_t offset)
bool SetRegisterLocationToIsCFAPlusOffset(uint32_t reg_num, int32_t offset, bool can_replace)
bool SetRegisterLocationToAtCFAPlusOffset(uint32_t reg_num, int32_t offset, bool can_replace)
const FAValue & GetCFAValue() const
bool SetRegisterLocationToRegister(uint32_t reg_num, uint32_t other_reg_num, bool can_replace)
void SetUnwindPlanForSignalTrap(lldb_private::LazyBool is_for_signal_trap)
void SetRegisterKind(lldb::RegisterKind kind)
void SetSourcedFromCompiler(lldb_private::LazyBool from_compiler)
void SetSourceName(const char *)
void SetPlanValidAddressRanges(std::vector< AddressRange > ranges)
void SetUnwindPlanValidAtAllInstructions(lldb_private::LazyBool valid_at_all_insn)
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_OFFSET
#define LLDB_INVALID_REGNUM
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::Section > SectionSP
@ eRegisterKindEHFrame
the register numbers seen in eh_frame
uint32_t valid_range_offset_start
Address personality_ptr_address
uint32_t valid_range_offset_end
uint32_t lsda_array_start