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))
164 : m_objfile(objfile), m_section_sp(section_sp),
165 m_section_contents_if_encrypted(), m_mutex(), m_indexes(),
167 m_unwindinfo_data_computed(false), m_unwind_header() {}
193 arch.GetAddressByteSize());
194 LLDB_LOGF(log,
"Got compact unwind encoding 0x%x for function %s",
202 addr_t func_range_start_file_addr =
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 =
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 =
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 =
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 =
682 objfile_base_address + personality_offset, sl);
716 switch (unwind_regno) {
718 return x86_64_eh_regnum::rbx;
720 return x86_64_eh_regnum::r12;
722 return x86_64_eh_regnum::r13;
724 return x86_64_eh_regnum::r14;
726 return x86_64_eh_regnum::r15;
728 return x86_64_eh_regnum::rbp;
737 Address pc_or_function_start) {
749 const int wordsize = 8;
750 int mode = function_info.
encoding & UNWIND_X86_64_MODE_MASK;
752 case UNWIND_X86_64_MODE_RBP_FRAME: {
753 row->GetCFAValue().SetIsRegisterPlusOffset(
757 row->SetRegisterLocationToAtCFAPlusOffset(x86_64_eh_regnum::rbp,
758 wordsize * -2,
true);
759 row->SetRegisterLocationToAtCFAPlusOffset(x86_64_eh_regnum::rip,
760 wordsize * -1,
true);
761 row->SetRegisterLocationToIsCFAPlusOffset(x86_64_eh_regnum::rsp, 0,
true);
763 uint32_t saved_registers_offset =
766 uint32_t saved_registers_locations =
769 saved_registers_offset += 2;
771 for (
int i = 0; i < 5; i++) {
772 uint32_t regnum = saved_registers_locations & 0x7;
781 row->SetRegisterLocationToAtCFAPlusOffset(
783 wordsize * -saved_registers_offset,
true);
786 saved_registers_offset--;
787 saved_registers_locations >>= 3;
793 case UNWIND_X86_64_MODE_STACK_IND: {
800 case UNWIND_X86_64_MODE_STACK_IMMD: {
802 UNWIND_X86_64_FRAMELESS_STACK_SIZE);
804 function_info.
encoding, UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT);
806 function_info.
encoding, UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION);
808 if (mode == UNWIND_X86_64_MODE_STACK_IND &&
811 function_info.
encoding, UNWIND_X86_64_FRAMELESS_STACK_ADJUST);
816 function_info.
encoding, UNWIND_X86_64_FRAMELESS_STACK_SIZE);
823 subl_payload_addr.
Slide(offset_to_subl_insn);
825 uint64_t large_stack_size = process_sp->ReadUnsignedIntegerFromMemory(
827 if (large_stack_size != 0 &&
error.Success()) {
829 stack_size = large_stack_size + (stack_adjust * wordsize);
841 int32_t offset = mode == UNWIND_X86_64_MODE_STACK_IND
843 : stack_size * wordsize;
844 row->GetCFAValue().SetIsRegisterPlusOffset(x86_64_eh_regnum::rsp, offset);
847 row->SetRegisterLocationToAtCFAPlusOffset(x86_64_eh_regnum::rip,
848 wordsize * -1,
true);
849 row->SetRegisterLocationToIsCFAPlusOffset(x86_64_eh_regnum::rsp, 0,
true);
851 if (register_count > 0) {
860 int permunreg[6] = {0, 0, 0, 0, 0, 0};
865 switch (register_count) {
867 permunreg[0] = permutation / 120;
868 permutation -= (permunreg[0] * 120);
869 permunreg[1] = permutation / 24;
870 permutation -= (permunreg[1] * 24);
871 permunreg[2] = permutation / 6;
872 permutation -= (permunreg[2] * 6);
873 permunreg[3] = permutation / 2;
874 permutation -= (permunreg[3] * 2);
875 permunreg[4] = permutation;
879 permunreg[0] = permutation / 120;
880 permutation -= (permunreg[0] * 120);
881 permunreg[1] = permutation / 24;
882 permutation -= (permunreg[1] * 24);
883 permunreg[2] = permutation / 6;
884 permutation -= (permunreg[2] * 6);
885 permunreg[3] = permutation / 2;
886 permutation -= (permunreg[3] * 2);
887 permunreg[4] = permutation;
890 permunreg[0] = permutation / 60;
891 permutation -= (permunreg[0] * 60);
892 permunreg[1] = permutation / 12;
893 permutation -= (permunreg[1] * 12);
894 permunreg[2] = permutation / 3;
895 permutation -= (permunreg[2] * 3);
896 permunreg[3] = permutation;
899 permunreg[0] = permutation / 20;
900 permutation -= (permunreg[0] * 20);
901 permunreg[1] = permutation / 4;
902 permutation -= (permunreg[1] * 4);
903 permunreg[2] = permutation;
906 permunreg[0] = permutation / 5;
907 permutation -= (permunreg[0] * 5);
908 permunreg[1] = permutation;
911 permunreg[0] = permutation;
921 bool used[7] = {
false,
false,
false,
false,
false,
false,
false};
922 for (uint32_t i = 0; i < register_count; i++) {
924 for (
int j = 1; j < 7; j++) {
926 if (renum == permunreg[i]) {
936 uint32_t saved_registers_offset = 1;
937 saved_registers_offset++;
939 for (
int i = (
sizeof(registers) /
sizeof(int)) - 1; i >= 0; i--) {
940 switch (registers[i]) {
949 row->SetRegisterLocationToAtCFAPlusOffset(
951 wordsize * -saved_registers_offset,
true);
952 saved_registers_offset++;
961 case UNWIND_X86_64_MODE_DWARF: {
988 switch (unwind_regno) {
990 return i386_eh_regnum::ebx;
992 return i386_eh_regnum::ecx;
994 return i386_eh_regnum::edx;
996 return i386_eh_regnum::edi;
998 return i386_eh_regnum::esi;
1000 return i386_eh_regnum::ebp;
1009 Address pc_or_function_start) {
1021 const int wordsize = 4;
1022 int mode = function_info.
encoding & UNWIND_X86_MODE_MASK;
1024 case UNWIND_X86_MODE_EBP_FRAME: {
1025 row->GetCFAValue().SetIsRegisterPlusOffset(
1028 row->SetRegisterLocationToAtCFAPlusOffset(i386_eh_regnum::ebp,
1029 wordsize * -2,
true);
1030 row->SetRegisterLocationToAtCFAPlusOffset(i386_eh_regnum::eip,
1031 wordsize * -1,
true);
1032 row->SetRegisterLocationToIsCFAPlusOffset(i386_eh_regnum::esp, 0,
true);
1034 uint32_t saved_registers_offset =
1037 uint32_t saved_registers_locations =
1040 saved_registers_offset += 2;
1042 for (
int i = 0; i < 5; i++) {
1043 uint32_t regnum = saved_registers_locations & 0x7;
1052 row->SetRegisterLocationToAtCFAPlusOffset(
1054 wordsize * -saved_registers_offset,
true);
1057 saved_registers_offset--;
1058 saved_registers_locations >>= 3;
1064 case UNWIND_X86_MODE_STACK_IND:
1065 case UNWIND_X86_MODE_STACK_IMMD: {
1066 uint32_t stack_size =
1069 function_info.
encoding, UNWIND_X86_FRAMELESS_STACK_REG_COUNT);
1071 function_info.
encoding, UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION);
1073 if (mode == UNWIND_X86_MODE_STACK_IND &&
1076 UNWIND_X86_FRAMELESS_STACK_ADJUST);
1080 uint32_t offset_to_subl_insn =
1088 subl_payload_addr.
Slide(offset_to_subl_insn);
1090 uint64_t large_stack_size = process_sp->ReadUnsignedIntegerFromMemory(
1092 if (large_stack_size != 0 &&
error.Success()) {
1094 stack_size = large_stack_size + (stack_adjust * wordsize);
1107 mode == UNWIND_X86_MODE_STACK_IND ? stack_size : stack_size * wordsize;
1108 row->GetCFAValue().SetIsRegisterPlusOffset(i386_eh_regnum::esp, offset);
1110 row->SetRegisterLocationToAtCFAPlusOffset(i386_eh_regnum::eip,
1111 wordsize * -1,
true);
1112 row->SetRegisterLocationToIsCFAPlusOffset(i386_eh_regnum::esp, 0,
true);
1114 if (register_count > 0) {
1123 int permunreg[6] = {0, 0, 0, 0, 0, 0};
1128 switch (register_count) {
1130 permunreg[0] = permutation / 120;
1131 permutation -= (permunreg[0] * 120);
1132 permunreg[1] = permutation / 24;
1133 permutation -= (permunreg[1] * 24);
1134 permunreg[2] = permutation / 6;
1135 permutation -= (permunreg[2] * 6);
1136 permunreg[3] = permutation / 2;
1137 permutation -= (permunreg[3] * 2);
1138 permunreg[4] = permutation;
1142 permunreg[0] = permutation / 120;
1143 permutation -= (permunreg[0] * 120);
1144 permunreg[1] = permutation / 24;
1145 permutation -= (permunreg[1] * 24);
1146 permunreg[2] = permutation / 6;
1147 permutation -= (permunreg[2] * 6);
1148 permunreg[3] = permutation / 2;
1149 permutation -= (permunreg[3] * 2);
1150 permunreg[4] = permutation;
1153 permunreg[0] = permutation / 60;
1154 permutation -= (permunreg[0] * 60);
1155 permunreg[1] = permutation / 12;
1156 permutation -= (permunreg[1] * 12);
1157 permunreg[2] = permutation / 3;
1158 permutation -= (permunreg[2] * 3);
1159 permunreg[3] = permutation;
1162 permunreg[0] = permutation / 20;
1163 permutation -= (permunreg[0] * 20);
1164 permunreg[1] = permutation / 4;
1165 permutation -= (permunreg[1] * 4);
1166 permunreg[2] = permutation;
1169 permunreg[0] = permutation / 5;
1170 permutation -= (permunreg[0] * 5);
1171 permunreg[1] = permutation;
1174 permunreg[0] = permutation;
1184 bool used[7] = {
false,
false,
false,
false,
false,
false,
false};
1185 for (uint32_t i = 0; i < register_count; i++) {
1187 for (
int j = 1; j < 7; j++) {
1189 if (renum == permunreg[i]) {
1199 uint32_t saved_registers_offset = 1;
1200 saved_registers_offset++;
1202 for (
int i = (
sizeof(registers) /
sizeof(int)) - 1; i >= 0; i--) {
1203 switch (registers[i]) {
1212 row->SetRegisterLocationToAtCFAPlusOffset(
1214 wordsize * -saved_registers_offset,
true);
1215 saved_registers_offset++;
1225 case UNWIND_X86_MODE_DWARF: {
1306 Address pc_or_function_start) {
1318 const int wordsize = 8;
1319 int mode = function_info.
encoding & UNWIND_ARM64_MODE_MASK;
1321 if (mode == UNWIND_ARM64_MODE_DWARF)
1324 if (mode == UNWIND_ARM64_MODE_FRAMELESS) {
1327 uint32_t stack_size =
1329 UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK)) *
1333 row->GetCFAValue().SetIsRegisterPlusOffset(arm64_eh_regnum::sp, stack_size);
1336 row->SetRegisterLocationToRegister(arm64_eh_regnum::pc, arm64_eh_regnum::ra,
1344 if (mode != UNWIND_ARM64_MODE_FRAME)
1349 row->GetCFAValue().SetIsRegisterPlusOffset(arm64_eh_regnum::fp, 2 * wordsize);
1351 row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::fp, wordsize * -2,
1353 row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::pc, wordsize * -1,
1355 row->SetRegisterLocationToIsCFAPlusOffset(arm64_eh_regnum::sp, 0,
true);
1357 int reg_pairs_saved_count = 1;
1359 uint32_t saved_register_bits = function_info.
encoding & 0xfff;
1361 if (saved_register_bits & UNWIND_ARM64_FRAME_X19_X20_PAIR) {
1362 int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
1363 cfa_offset -= wordsize;
1364 row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x19, cfa_offset,
1366 cfa_offset -= wordsize;
1367 row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x20, cfa_offset,
1369 reg_pairs_saved_count++;
1372 if (saved_register_bits & UNWIND_ARM64_FRAME_X21_X22_PAIR) {
1373 int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
1374 cfa_offset -= wordsize;
1375 row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x21, cfa_offset,
1377 cfa_offset -= wordsize;
1378 row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x22, cfa_offset,
1380 reg_pairs_saved_count++;
1383 if (saved_register_bits & UNWIND_ARM64_FRAME_X23_X24_PAIR) {
1384 int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
1385 cfa_offset -= wordsize;
1386 row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x23, cfa_offset,
1388 cfa_offset -= wordsize;
1389 row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x24, cfa_offset,
1391 reg_pairs_saved_count++;
1394 if (saved_register_bits & UNWIND_ARM64_FRAME_X25_X26_PAIR) {
1395 int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
1396 cfa_offset -= wordsize;
1397 row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x25, cfa_offset,
1399 cfa_offset -= wordsize;
1400 row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x26, cfa_offset,
1402 reg_pairs_saved_count++;
1405 if (saved_register_bits & UNWIND_ARM64_FRAME_X27_X28_PAIR) {
1406 int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
1407 cfa_offset -= wordsize;
1408 row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x27, cfa_offset,
1410 cfa_offset -= wordsize;
1411 row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x28, cfa_offset,
1413 reg_pairs_saved_count++;
1420 if (saved_register_bits & UNWIND_ARM64_FRAME_D8_D9_PAIR) {
1421 reg_pairs_saved_count++;
1423 if (saved_register_bits & UNWIND_ARM64_FRAME_D10_D11_PAIR) {
1424 reg_pairs_saved_count++;
1426 if (saved_register_bits & UNWIND_ARM64_FRAME_D12_D13_PAIR) {
1427 reg_pairs_saved_count++;
1429 if (saved_register_bits & UNWIND_ARM64_FRAME_D14_D15_PAIR) {
1430 reg_pairs_saved_count++;
1440 Address pc_or_function_start) {
1452 const int wordsize = 4;
1453 int mode = function_info.
encoding & UNWIND_ARM_MODE_MASK;
1455 if (mode == UNWIND_ARM_MODE_DWARF)
1459 UNWIND_ARM_FRAME_STACK_ADJUST_MASK)) *
1462 row->GetCFAValue().SetIsRegisterPlusOffset(
arm_r7,
1463 (2 * wordsize) + stack_adjust);
1465 row->SetRegisterLocationToAtCFAPlusOffset(
1466 arm_r7, (wordsize * -2) - stack_adjust,
true);
1467 row->SetRegisterLocationToAtCFAPlusOffset(
1468 arm_pc, (wordsize * -1) - stack_adjust,
true);
1469 row->SetRegisterLocationToIsCFAPlusOffset(
arm_sp, 0,
true);
1471 int cfa_offset = -stack_adjust - (2 * wordsize);
1473 uint32_t saved_register_bits = function_info.
encoding & 0xff;
1475 if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R6) {
1476 cfa_offset -= wordsize;
1477 row->SetRegisterLocationToAtCFAPlusOffset(
arm_r6, cfa_offset,
true);
1480 if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R5) {
1481 cfa_offset -= wordsize;
1482 row->SetRegisterLocationToAtCFAPlusOffset(
arm_r5, cfa_offset,
true);
1485 if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R4) {
1486 cfa_offset -= wordsize;
1487 row->SetRegisterLocationToAtCFAPlusOffset(
arm_r4, cfa_offset,
true);
1490 if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R12) {
1491 cfa_offset -= wordsize;
1492 row->SetRegisterLocationToAtCFAPlusOffset(
arm_r12, cfa_offset,
true);
1495 if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R11) {
1496 cfa_offset -= wordsize;
1497 row->SetRegisterLocationToAtCFAPlusOffset(
arm_r11, cfa_offset,
true);
1500 if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R10) {
1501 cfa_offset -= wordsize;
1502 row->SetRegisterLocationToAtCFAPlusOffset(
arm_r10, cfa_offset,
true);
1505 if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R9) {
1506 cfa_offset -= wordsize;
1507 row->SetRegisterLocationToAtCFAPlusOffset(
arm_r9, cfa_offset,
true);
1510 if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R8) {
1511 cfa_offset -= wordsize;
1512 row->SetRegisterLocationToAtCFAPlusOffset(
arm_r8, cfa_offset,
true);
1515 if (mode == UNWIND_ARM_MODE_FRAME_D) {
1516 uint32_t d_reg_bits =
1518 switch (d_reg_bits) {
1522 row->SetRegisterLocationToAtCFAPlusOffset(
arm_d8, cfa_offset,
true);
1528 row->SetRegisterLocationToAtCFAPlusOffset(
arm_d10, cfa_offset,
true);
1530 row->SetRegisterLocationToAtCFAPlusOffset(
arm_d8, cfa_offset,
true);
1537 row->SetRegisterLocationToAtCFAPlusOffset(
arm_d12, cfa_offset,
true);
1539 row->SetRegisterLocationToAtCFAPlusOffset(
arm_d10, cfa_offset,
true);
1541 row->SetRegisterLocationToAtCFAPlusOffset(
arm_d8, cfa_offset,
true);
1549 row->SetRegisterLocationToAtCFAPlusOffset(
arm_d14, cfa_offset,
true);
1551 row->SetRegisterLocationToAtCFAPlusOffset(
arm_d12, cfa_offset,
true);
1553 row->SetRegisterLocationToAtCFAPlusOffset(
arm_d10, cfa_offset,
true);
1555 row->SetRegisterLocationToAtCFAPlusOffset(
arm_d8, cfa_offset,
true);
1563 row->SetRegisterLocationToAtCFAPlusOffset(
arm_d14, cfa_offset,
true);
1565 row->SetRegisterLocationToAtCFAPlusOffset(
arm_d12, cfa_offset,
true);
1579 row->SetRegisterLocationToAtCFAPlusOffset(
arm_d14, cfa_offset,
true);
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.
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
A plug-in interface definition class for object file parsers.
virtual SectionList * GetSectionList(bool update_module_section_list=true)
Gets the section list for the currently selected architecture (and object for archives).
virtual size_t ReadSectionData(Section *section, lldb::offset_t section_offset, void *dst, size_t dst_len)
virtual lldb_private::Address GetBaseAddress()
Returns base address of this object file.
virtual ArchSpec GetArchitecture()=0
Get the ArchSpec for this object file.
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 SetUnwindPlanForSignalTrap(lldb_private::LazyBool is_for_signal_trap)
void SetRegisterKind(lldb::RegisterKind kind)
void SetPlanValidAddressRange(const AddressRange &range)
void SetPersonalityFunctionPtr(Address presonality_func_ptr)
void AppendRow(const RowSP &row_sp)
std::shared_ptr< Row > RowSP
void SetLSDAAddress(Address lsda_addr)
void SetSourcedFromCompiler(lldb_private::LazyBool from_compiler)
void SetSourceName(const char *)
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