LLDB  mainline
CompactUnwindInfo.cpp
Go to the documentation of this file.
1 //===-- CompactUnwindInfo.cpp ---------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 #include "lldb/Core/Module.h"
11 #include "lldb/Core/Section.h"
12 #include "lldb/Symbol/ObjectFile.h"
13 #include "lldb/Symbol/UnwindPlan.h"
14 #include "lldb/Target/Process.h"
15 #include "lldb/Target/Target.h"
16 #include "lldb/Utility/ArchSpec.h"
18 #include "lldb/Utility/LLDBLog.h"
19 #include "lldb/Utility/Log.h"
21 
22 #include "llvm/Support/MathExtras.h"
23 
24 #include <algorithm>
25 #include <memory>
26 
27 using namespace lldb;
28 using namespace lldb_private;
29 
30 namespace lldb_private {
31 
32 // Constants from <mach-o/compact_unwind_encoding.h>
33 
35  UNWIND_IS_NOT_FUNCTION_START = 0x80000000, UNWIND_HAS_LSDA = 0x40000000,
36  UNWIND_PERSONALITY_MASK = 0x30000000,
37 };
38 
40  UNWIND_X86_MODE_MASK = 0x0F000000,
41  UNWIND_X86_MODE_EBP_FRAME = 0x01000000,
42  UNWIND_X86_MODE_STACK_IMMD = 0x02000000,
43  UNWIND_X86_MODE_STACK_IND = 0x03000000,
44  UNWIND_X86_MODE_DWARF = 0x04000000,
45 
46  UNWIND_X86_EBP_FRAME_REGISTERS = 0x00007FFF,
47  UNWIND_X86_EBP_FRAME_OFFSET = 0x00FF0000,
48 
49  UNWIND_X86_FRAMELESS_STACK_SIZE = 0x00FF0000,
50  UNWIND_X86_FRAMELESS_STACK_ADJUST = 0x0000E000,
51  UNWIND_X86_FRAMELESS_STACK_REG_COUNT = 0x00001C00,
52  UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF,
53 
54  UNWIND_X86_DWARF_SECTION_OFFSET = 0x00FFFFFF,
55 };
56 
57 enum {
65 };
66 
68  UNWIND_X86_64_MODE_MASK = 0x0F000000,
69  UNWIND_X86_64_MODE_RBP_FRAME = 0x01000000,
70  UNWIND_X86_64_MODE_STACK_IMMD = 0x02000000,
71  UNWIND_X86_64_MODE_STACK_IND = 0x03000000,
72  UNWIND_X86_64_MODE_DWARF = 0x04000000,
73 
74  UNWIND_X86_64_RBP_FRAME_REGISTERS = 0x00007FFF,
75  UNWIND_X86_64_RBP_FRAME_OFFSET = 0x00FF0000,
76 
77  UNWIND_X86_64_FRAMELESS_STACK_SIZE = 0x00FF0000,
78  UNWIND_X86_64_FRAMELESS_STACK_ADJUST = 0x0000E000,
79  UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT = 0x00001C00,
80  UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF,
81 
82  UNWIND_X86_64_DWARF_SECTION_OFFSET = 0x00FFFFFF,
83 };
84 
85 enum {
93 };
94 
96  UNWIND_ARM64_MODE_MASK = 0x0F000000,
97  UNWIND_ARM64_MODE_FRAMELESS = 0x02000000,
98  UNWIND_ARM64_MODE_DWARF = 0x03000000,
99  UNWIND_ARM64_MODE_FRAME = 0x04000000,
100 
101  UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001,
102  UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002,
103  UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004,
104  UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008,
105  UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010,
106  UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100,
107  UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200,
108  UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400,
109  UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800,
110 
111  UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK = 0x00FFF000,
112  UNWIND_ARM64_DWARF_SECTION_OFFSET = 0x00FFFFFF,
113 };
114 
116  UNWIND_ARM_MODE_MASK = 0x0F000000,
117  UNWIND_ARM_MODE_FRAME = 0x01000000,
118  UNWIND_ARM_MODE_FRAME_D = 0x02000000,
119  UNWIND_ARM_MODE_DWARF = 0x04000000,
120 
121  UNWIND_ARM_FRAME_STACK_ADJUST_MASK = 0x00C00000,
122 
123  UNWIND_ARM_FRAME_FIRST_PUSH_R4 = 0x00000001,
124  UNWIND_ARM_FRAME_FIRST_PUSH_R5 = 0x00000002,
125  UNWIND_ARM_FRAME_FIRST_PUSH_R6 = 0x00000004,
126 
127  UNWIND_ARM_FRAME_SECOND_PUSH_R8 = 0x00000008,
128  UNWIND_ARM_FRAME_SECOND_PUSH_R9 = 0x00000010,
129  UNWIND_ARM_FRAME_SECOND_PUSH_R10 = 0x00000020,
130  UNWIND_ARM_FRAME_SECOND_PUSH_R11 = 0x00000040,
131  UNWIND_ARM_FRAME_SECOND_PUSH_R12 = 0x00000080,
132 
133  UNWIND_ARM_FRAME_D_REG_COUNT_MASK = 0x00000700,
134 
135  UNWIND_ARM_DWARF_SECTION_OFFSET = 0x00FFFFFF,
136 };
137 }
138 
139 #ifndef UNWIND_SECOND_LEVEL_REGULAR
140 #define UNWIND_SECOND_LEVEL_REGULAR 2
141 #endif
142 
143 #ifndef UNWIND_SECOND_LEVEL_COMPRESSED
144 #define UNWIND_SECOND_LEVEL_COMPRESSED 3
145 #endif
146 
147 #ifndef UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET
148 #define UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(entry) (entry & 0x00FFFFFF)
149 #endif
150 
151 #ifndef UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX
152 #define UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX(entry) \
153  ((entry >> 24) & 0xFF)
154 #endif
155 
156 #define EXTRACT_BITS(value, mask) \
157  ((value >> \
158  llvm::countTrailingZeros(static_cast<uint32_t>(mask), llvm::ZB_Width)) & \
159  (((1 << llvm::countPopulation(static_cast<uint32_t>(mask)))) - 1))
160 
161 // constructor
162 
163 CompactUnwindInfo::CompactUnwindInfo(ObjectFile &objfile, SectionSP &section_sp)
164  : m_objfile(objfile), m_section_sp(section_sp),
165  m_section_contents_if_encrypted(), m_mutex(), m_indexes(),
166  m_indexes_computed(eLazyBoolCalculate), m_unwindinfo_data(),
167  m_unwindinfo_data_computed(false), m_unwind_header() {}
168 
169 // destructor
170 
172 
174  UnwindPlan &unwind_plan) {
175  if (!IsValid(target.GetProcessSP())) {
176  return false;
177  }
178  FunctionInfo function_info;
179  if (GetCompactUnwindInfoForFunction(target, addr, function_info)) {
180  // shortcut return for functions that have no compact unwind
181  if (function_info.encoding == 0)
182  return false;
183 
184  if (ArchSpec arch = m_objfile.GetArchitecture()) {
185 
186  Log *log = GetLog(LLDBLog::Unwind);
187  if (log && log->GetVerbose()) {
188  StreamString strm;
189  addr.Dump(
190  &strm, nullptr,
191  Address::DumpStyle::DumpStyleResolvedDescriptionNoFunctionArguments,
192  Address::DumpStyle::DumpStyleFileAddress,
193  arch.GetAddressByteSize());
194  LLDB_LOGF(log, "Got compact unwind encoding 0x%x for function %s",
195  function_info.encoding, strm.GetData());
196  }
197 
198  if (function_info.valid_range_offset_start != 0 &&
199  function_info.valid_range_offset_end != 0) {
201  if (sl) {
202  addr_t func_range_start_file_addr =
203  function_info.valid_range_offset_start +
205  AddressRange func_range(func_range_start_file_addr,
206  function_info.valid_range_offset_end -
207  function_info.valid_range_offset_start,
208  sl);
209  unwind_plan.SetPlanValidAddressRange(func_range);
210  }
211  }
212 
213  if (arch.GetTriple().getArch() == llvm::Triple::x86_64) {
214  return CreateUnwindPlan_x86_64(target, function_info, unwind_plan,
215  addr);
216  }
217  if (arch.GetTriple().getArch() == llvm::Triple::aarch64 ||
218  arch.GetTriple().getArch() == llvm::Triple::aarch64_32) {
219  return CreateUnwindPlan_arm64(target, function_info, unwind_plan, addr);
220  }
221  if (arch.GetTriple().getArch() == llvm::Triple::x86) {
222  return CreateUnwindPlan_i386(target, function_info, unwind_plan, addr);
223  }
224  if (arch.GetTriple().getArch() == llvm::Triple::arm ||
225  arch.GetTriple().getArch() == llvm::Triple::thumb) {
226  return CreateUnwindPlan_armv7(target, function_info, unwind_plan, addr);
227  }
228  }
229  }
230  return false;
231 }
232 
233 bool CompactUnwindInfo::IsValid(const ProcessSP &process_sp) {
234  if (m_section_sp.get() == nullptr)
235  return false;
236 
238  return true;
239 
240  ScanIndex(process_sp);
241 
243 }
244 
245 void CompactUnwindInfo::ScanIndex(const ProcessSP &process_sp) {
246  std::lock_guard<std::mutex> guard(m_mutex);
248  return;
249 
250  // We can't read the index for some reason.
252  return;
253  }
254 
255  Log *log = GetLog(LLDBLog::Unwind);
256  if (log)
257  m_objfile.GetModule()->LogMessage(
258  log, "Reading compact unwind first-level indexes");
259 
261  if (m_section_sp->IsEncrypted()) {
262  // Can't get section contents of a protected/encrypted section until we
263  // have a live process and can read them out of memory.
264  if (process_sp.get() == nullptr)
265  return;
267  std::make_shared<DataBufferHeap>(m_section_sp->GetByteSize(), 0);
268  Status error;
269  if (process_sp->ReadMemory(
270  m_section_sp->GetLoadBaseAddress(&process_sp->GetTarget()),
272  m_section_sp->GetByteSize(),
273  error) == m_section_sp->GetByteSize() &&
274  error.Success()) {
276  process_sp->GetTarget().GetArchitecture().GetAddressByteSize());
278  process_sp->GetTarget().GetArchitecture().GetByteOrder());
280  }
281  } else {
283  }
284  if (m_unwindinfo_data.GetByteSize() != m_section_sp->GetByteSize())
285  return;
287  }
288 
289  if (m_unwindinfo_data.GetByteSize() > 0) {
290  offset_t offset = 0;
291 
292  // struct unwind_info_section_header
293  // {
294  // uint32_t version; // UNWIND_SECTION_VERSION
295  // uint32_t commonEncodingsArraySectionOffset;
296  // uint32_t commonEncodingsArrayCount;
297  // uint32_t personalityArraySectionOffset;
298  // uint32_t personalityArrayCount;
299  // uint32_t indexSectionOffset;
300  // uint32_t indexCount;
301 
304  m_unwindinfo_data.GetU32(&offset);
306  m_unwindinfo_data.GetU32(&offset);
308  m_unwindinfo_data.GetU32(&offset);
310  uint32_t indexSectionOffset = m_unwindinfo_data.GetU32(&offset);
311 
312  uint32_t indexCount = m_unwindinfo_data.GetU32(&offset);
313 
318  indexSectionOffset > m_unwindinfo_data.GetByteSize() ||
319  offset > m_unwindinfo_data.GetByteSize()) {
320  Host::SystemLog(Host::eSystemLogError, "error: Invalid offset "
321  "encountered in compact unwind "
322  "info, skipping\n");
323  // don't trust anything from this compact_unwind section if it looks
324  // blatantly invalid data in the header.
326  return;
327  }
328 
329  // Parse the basic information from the indexes We wait to scan the second
330  // level page info until it's needed
331 
332  // struct unwind_info_section_header_index_entry {
333  // uint32_t functionOffset;
334  // uint32_t secondLevelPagesSectionOffset;
335  // uint32_t lsdaIndexArraySectionOffset;
336  // };
337 
338  bool clear_address_zeroth_bit = false;
339  if (ArchSpec arch = m_objfile.GetArchitecture()) {
340  if (arch.GetTriple().getArch() == llvm::Triple::arm ||
341  arch.GetTriple().getArch() == llvm::Triple::thumb)
342  clear_address_zeroth_bit = true;
343  }
344 
345  offset = indexSectionOffset;
346  for (uint32_t idx = 0; idx < indexCount; idx++) {
347  uint32_t function_offset =
348  m_unwindinfo_data.GetU32(&offset); // functionOffset
349  uint32_t second_level_offset =
350  m_unwindinfo_data.GetU32(&offset); // secondLevelPagesSectionOffset
351  uint32_t lsda_offset =
352  m_unwindinfo_data.GetU32(&offset); // lsdaIndexArraySectionOffset
353 
354  if (second_level_offset > m_section_sp->GetByteSize() ||
355  lsda_offset > m_section_sp->GetByteSize()) {
357  }
358 
359  if (clear_address_zeroth_bit)
360  function_offset &= ~1ull;
361 
362  UnwindIndex this_index;
363  this_index.function_offset = function_offset;
364  this_index.second_level = second_level_offset;
365  this_index.lsda_array_start = lsda_offset;
366 
367  if (m_indexes.size() > 0) {
368  m_indexes[m_indexes.size() - 1].lsda_array_end = lsda_offset;
369  }
370 
371  if (second_level_offset == 0) {
372  this_index.sentinal_entry = true;
373  }
374 
375  m_indexes.push_back(this_index);
376  }
378  } else {
380  }
381 }
382 
384  uint32_t lsda_count,
385  uint32_t function_offset) {
386  // struct unwind_info_section_header_lsda_index_entry {
387  // uint32_t functionOffset;
388  // uint32_t lsdaOffset;
389  // };
390 
391  offset_t first_entry = lsda_offset;
392  uint32_t low = 0;
393  uint32_t high = lsda_count;
394  while (low < high) {
395  uint32_t mid = (low + high) / 2;
396  offset_t offset = first_entry + (mid * 8);
397  uint32_t mid_func_offset =
398  m_unwindinfo_data.GetU32(&offset); // functionOffset
399  uint32_t mid_lsda_offset = m_unwindinfo_data.GetU32(&offset); // lsdaOffset
400  if (mid_func_offset == function_offset) {
401  return mid_lsda_offset;
402  }
403  if (mid_func_offset < function_offset) {
404  low = mid + 1;
405  } else {
406  high = mid;
407  }
408  }
409  return 0;
410 }
411 
413  uint32_t entry_page_offset, uint32_t entry_count, uint32_t function_offset,
414  uint32_t *entry_func_start_offset, uint32_t *entry_func_end_offset) {
415  // typedef uint32_t compact_unwind_encoding_t;
416  // struct unwind_info_regular_second_level_entry {
417  // uint32_t functionOffset;
418  // compact_unwind_encoding_t encoding;
419 
420  offset_t first_entry = entry_page_offset;
421 
422  uint32_t low = 0;
423  uint32_t high = entry_count;
424  uint32_t last = high - 1;
425  while (low < high) {
426  uint32_t mid = (low + high) / 2;
427  offset_t offset = first_entry + (mid * 8);
428  uint32_t mid_func_offset =
429  m_unwindinfo_data.GetU32(&offset); // functionOffset
430  uint32_t next_func_offset = 0;
431  if (mid < last) {
432  offset = first_entry + ((mid + 1) * 8);
433  next_func_offset = m_unwindinfo_data.GetU32(&offset); // functionOffset
434  }
435  if (mid_func_offset <= function_offset) {
436  if (mid == last || (next_func_offset > function_offset)) {
437  if (entry_func_start_offset)
438  *entry_func_start_offset = mid_func_offset;
439  if (mid != last && entry_func_end_offset)
440  *entry_func_end_offset = next_func_offset;
441  return first_entry + (mid * 8);
442  } else {
443  low = mid + 1;
444  }
445  } else {
446  high = mid;
447  }
448  }
449  return LLDB_INVALID_OFFSET;
450 }
451 
453  uint32_t entry_page_offset, uint32_t entry_count,
454  uint32_t function_offset_to_find, uint32_t function_offset_base,
455  uint32_t *entry_func_start_offset, uint32_t *entry_func_end_offset) {
456  offset_t first_entry = entry_page_offset;
457 
458  uint32_t low = 0;
459  uint32_t high = entry_count;
460  uint32_t last = high - 1;
461  while (low < high) {
462  uint32_t mid = (low + high) / 2;
463  offset_t offset = first_entry + (mid * 4);
464  uint32_t entry = m_unwindinfo_data.GetU32(&offset); // entry
465  uint32_t mid_func_offset = UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(entry);
466  mid_func_offset += function_offset_base;
467  uint32_t next_func_offset = 0;
468  if (mid < last) {
469  offset = first_entry + ((mid + 1) * 4);
470  uint32_t next_entry = m_unwindinfo_data.GetU32(&offset); // entry
471  next_func_offset = UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(next_entry);
472  next_func_offset += function_offset_base;
473  }
474  if (mid_func_offset <= function_offset_to_find) {
475  if (mid == last || (next_func_offset > function_offset_to_find)) {
476  if (entry_func_start_offset)
477  *entry_func_start_offset = mid_func_offset;
478  if (mid != last && entry_func_end_offset)
479  *entry_func_end_offset = next_func_offset;
481  } else {
482  low = mid + 1;
483  }
484  } else {
485  high = mid;
486  }
487  }
488 
489  return UINT32_MAX;
490 }
491 
493  Target &target, Address address, FunctionInfo &unwind_info) {
494  unwind_info.encoding = 0;
495  unwind_info.lsda_address.Clear();
496  unwind_info.personality_ptr_address.Clear();
497 
498  if (!IsValid(target.GetProcessSP()))
499  return false;
500 
501  addr_t text_section_file_address = LLDB_INVALID_ADDRESS;
503  if (sl) {
504  SectionSP text_sect = sl->FindSectionByType(eSectionTypeCode, true);
505  if (text_sect.get()) {
506  text_section_file_address = text_sect->GetFileAddress();
507  }
508  }
509  if (text_section_file_address == LLDB_INVALID_ADDRESS)
510  return false;
511 
512  addr_t function_offset =
514 
515  UnwindIndex key;
516  key.function_offset = function_offset;
517 
518  std::vector<UnwindIndex>::const_iterator it;
519  it = std::lower_bound(m_indexes.begin(), m_indexes.end(), key);
520  if (it == m_indexes.end()) {
521  return false;
522  }
523 
524  if (it->function_offset != key.function_offset) {
525  if (it != m_indexes.begin())
526  --it;
527  }
528 
529  if (it->sentinal_entry) {
530  return false;
531  }
532 
533  auto next_it = it + 1;
534  if (next_it != m_indexes.end()) {
535  // initialize the function offset end range to be the start of the next
536  // index offset. If we find an entry which is at the end of the index
537  // table, this will establish the range end.
538  unwind_info.valid_range_offset_end = next_it->function_offset;
539  }
540 
541  offset_t second_page_offset = it->second_level;
542  offset_t lsda_array_start = it->lsda_array_start;
543  offset_t lsda_array_count = (it->lsda_array_end - it->lsda_array_start) / 8;
544 
545  offset_t offset = second_page_offset;
547  &offset); // UNWIND_SECOND_LEVEL_REGULAR or UNWIND_SECOND_LEVEL_COMPRESSED
548 
549  if (kind == UNWIND_SECOND_LEVEL_REGULAR) {
550  // struct unwind_info_regular_second_level_page_header {
551  // uint32_t kind; // UNWIND_SECOND_LEVEL_REGULAR
552  // uint16_t entryPageOffset;
553  // uint16_t entryCount;
554 
555  // typedef uint32_t compact_unwind_encoding_t;
556  // struct unwind_info_regular_second_level_entry {
557  // uint32_t functionOffset;
558  // compact_unwind_encoding_t encoding;
559 
560  uint16_t entry_page_offset =
561  m_unwindinfo_data.GetU16(&offset); // entryPageOffset
562  uint16_t entry_count = m_unwindinfo_data.GetU16(&offset); // entryCount
563 
565  second_page_offset + entry_page_offset, entry_count, function_offset,
566  &unwind_info.valid_range_offset_start,
567  &unwind_info.valid_range_offset_end);
568  if (entry_offset == LLDB_INVALID_OFFSET) {
569  return false;
570  }
571  entry_offset += 4; // skip over functionOffset
572  unwind_info.encoding = m_unwindinfo_data.GetU32(&entry_offset); // encoding
573  if (unwind_info.encoding & UNWIND_HAS_LSDA) {
575  if (sl) {
576  uint32_t lsda_offset = GetLSDAForFunctionOffset(
577  lsda_array_start, lsda_array_count, function_offset);
578  addr_t objfile_base_address =
581  objfile_base_address + lsda_offset, sl);
582  }
583  }
584  if (unwind_info.encoding & UNWIND_PERSONALITY_MASK) {
585  uint32_t personality_index =
586  EXTRACT_BITS(unwind_info.encoding, UNWIND_PERSONALITY_MASK);
587 
588  if (personality_index > 0) {
589  personality_index--;
590  if (personality_index < m_unwind_header.personality_array_count) {
592  offset += 4 * personality_index;
594  if (sl) {
595  uint32_t personality_offset = m_unwindinfo_data.GetU32(&offset);
596  addr_t objfile_base_address =
599  objfile_base_address + personality_offset, sl);
600  }
601  }
602  }
603  }
604  return true;
605  } else if (kind == UNWIND_SECOND_LEVEL_COMPRESSED) {
606  // struct unwind_info_compressed_second_level_page_header {
607  // uint32_t kind; // UNWIND_SECOND_LEVEL_COMPRESSED
608  // uint16_t entryPageOffset; // offset from this 2nd lvl page
609  // idx to array of entries
610  // // (an entry has a function
611  // offset and index into the
612  // encodings)
613  // // NB function offset from the
614  // entry in the compressed page
615  // // must be added to the index's
616  // functionOffset value.
617  // uint16_t entryCount;
618  // uint16_t encodingsPageOffset; // offset from this 2nd lvl page
619  // idx to array of encodings
620  // uint16_t encodingsCount;
621 
622  uint16_t entry_page_offset =
623  m_unwindinfo_data.GetU16(&offset); // entryPageOffset
624  uint16_t entry_count = m_unwindinfo_data.GetU16(&offset); // entryCount
625  uint16_t encodings_page_offset =
626  m_unwindinfo_data.GetU16(&offset); // encodingsPageOffset
627  uint16_t encodings_count =
628  m_unwindinfo_data.GetU16(&offset); // encodingsCount
629 
631  second_page_offset + entry_page_offset, entry_count, function_offset,
632  it->function_offset, &unwind_info.valid_range_offset_start,
633  &unwind_info.valid_range_offset_end);
634  if (encoding_index == UINT32_MAX ||
635  encoding_index >=
636  encodings_count + m_unwind_header.common_encodings_array_count) {
637  return false;
638  }
639  uint32_t encoding = 0;
640  if (encoding_index < m_unwind_header.common_encodings_array_count) {
642  (encoding_index * sizeof(uint32_t));
643  encoding = m_unwindinfo_data.GetU32(
644  &offset); // encoding entry from the commonEncodingsArray
645  } else {
646  uint32_t page_specific_entry_index =
648  offset = second_page_offset + encodings_page_offset +
649  (page_specific_entry_index * sizeof(uint32_t));
650  encoding = m_unwindinfo_data.GetU32(
651  &offset); // encoding entry from the page-specific encoding array
652  }
653  if (encoding == 0)
654  return false;
655 
656  unwind_info.encoding = encoding;
657  if (unwind_info.encoding & UNWIND_HAS_LSDA) {
659  if (sl) {
660  uint32_t lsda_offset = GetLSDAForFunctionOffset(
661  lsda_array_start, lsda_array_count, function_offset);
662  addr_t objfile_base_address =
665  objfile_base_address + lsda_offset, sl);
666  }
667  }
668  if (unwind_info.encoding & UNWIND_PERSONALITY_MASK) {
669  uint32_t personality_index =
670  EXTRACT_BITS(unwind_info.encoding, UNWIND_PERSONALITY_MASK);
671 
672  if (personality_index > 0) {
673  personality_index--;
674  if (personality_index < m_unwind_header.personality_array_count) {
676  offset += 4 * personality_index;
678  if (sl) {
679  uint32_t personality_offset = m_unwindinfo_data.GetU32(&offset);
680  addr_t objfile_base_address =
683  objfile_base_address + personality_offset, sl);
684  }
685  }
686  }
687  }
688  return true;
689  }
690  return false;
691 }
692 
694  rax = 0,
695  rdx = 1,
696  rcx = 2,
697  rbx = 3,
698  rsi = 4,
699  rdi = 5,
700  rbp = 6,
701  rsp = 7,
702  r8 = 8,
703  r9 = 9,
704  r10 = 10,
705  r11 = 11,
706  r12 = 12,
707  r13 = 13,
708  r14 = 14,
709  r15 = 15,
710  rip = 16 // this is officially the Return Address register number, but close
711  // enough
712 };
713 
714 // Convert the compact_unwind_info.h register numbering scheme to
715 // eRegisterKindEHFrame (eh_frame) register numbering scheme.
717  switch (unwind_regno) {
719  return x86_64_eh_regnum::rbx;
721  return x86_64_eh_regnum::r12;
723  return x86_64_eh_regnum::r13;
725  return x86_64_eh_regnum::r14;
727  return x86_64_eh_regnum::r15;
729  return x86_64_eh_regnum::rbp;
730  default:
731  return LLDB_INVALID_REGNUM;
732  }
733 }
734 
736  FunctionInfo &function_info,
737  UnwindPlan &unwind_plan,
738  Address pc_or_function_start) {
739  unwind_plan.SetSourceName("compact unwind info");
744 
745  unwind_plan.SetLSDAAddress(function_info.lsda_address);
746  unwind_plan.SetPersonalityFunctionPtr(function_info.personality_ptr_address);
747 
749 
750  const int wordsize = 8;
751  int mode = function_info.encoding & UNWIND_X86_64_MODE_MASK;
752  switch (mode) {
753  case UNWIND_X86_64_MODE_RBP_FRAME: {
754  row->GetCFAValue().SetIsRegisterPlusOffset(
756  2 * wordsize);
757  row->SetOffset(0);
758  row->SetRegisterLocationToAtCFAPlusOffset(x86_64_eh_regnum::rbp,
759  wordsize * -2, true);
760  row->SetRegisterLocationToAtCFAPlusOffset(x86_64_eh_regnum::rip,
761  wordsize * -1, true);
762  row->SetRegisterLocationToIsCFAPlusOffset(x86_64_eh_regnum::rsp, 0, true);
763 
764  uint32_t saved_registers_offset =
765  EXTRACT_BITS(function_info.encoding, UNWIND_X86_64_RBP_FRAME_OFFSET);
766 
767  uint32_t saved_registers_locations =
768  EXTRACT_BITS(function_info.encoding, UNWIND_X86_64_RBP_FRAME_REGISTERS);
769 
770  saved_registers_offset += 2;
771 
772  for (int i = 0; i < 5; i++) {
773  uint32_t regnum = saved_registers_locations & 0x7;
774  switch (regnum) {
776  break;
782  row->SetRegisterLocationToAtCFAPlusOffset(
784  wordsize * -saved_registers_offset, true);
785  break;
786  }
787  saved_registers_offset--;
788  saved_registers_locations >>= 3;
789  }
790  unwind_plan.AppendRow(row);
791  return true;
792  } break;
793 
794  case UNWIND_X86_64_MODE_STACK_IND: {
795  // The clang in Xcode 6 is emitting incorrect compact unwind encodings for
796  // this style of unwind. It was fixed in llvm r217020. The clang in Xcode
797  // 7 has this fixed.
798  return false;
799  } break;
800 
801  case UNWIND_X86_64_MODE_STACK_IMMD: {
802  uint32_t stack_size = EXTRACT_BITS(function_info.encoding,
803  UNWIND_X86_64_FRAMELESS_STACK_SIZE);
804  uint32_t register_count = EXTRACT_BITS(
805  function_info.encoding, UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT);
806  uint32_t permutation = EXTRACT_BITS(
807  function_info.encoding, UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION);
808 
809  if (mode == UNWIND_X86_64_MODE_STACK_IND &&
810  function_info.valid_range_offset_start != 0) {
811  uint32_t stack_adjust = EXTRACT_BITS(
812  function_info.encoding, UNWIND_X86_64_FRAMELESS_STACK_ADJUST);
813 
814  // offset into the function instructions; 0 == beginning of first
815  // instruction
816  uint32_t offset_to_subl_insn = EXTRACT_BITS(
817  function_info.encoding, UNWIND_X86_64_FRAMELESS_STACK_SIZE);
818 
820  if (sl) {
821  ProcessSP process_sp = target.GetProcessSP();
822  if (process_sp) {
823  Address subl_payload_addr(function_info.valid_range_offset_start, sl);
824  subl_payload_addr.Slide(offset_to_subl_insn);
825  Status error;
826  uint64_t large_stack_size = process_sp->ReadUnsignedIntegerFromMemory(
827  subl_payload_addr.GetLoadAddress(&target), 4, 0, error);
828  if (large_stack_size != 0 && error.Success()) {
829  // Got the large stack frame size correctly - use it
830  stack_size = large_stack_size + (stack_adjust * wordsize);
831  } else {
832  return false;
833  }
834  } else {
835  return false;
836  }
837  } else {
838  return false;
839  }
840  }
841 
842  int32_t offset = mode == UNWIND_X86_64_MODE_STACK_IND
843  ? stack_size
844  : stack_size * wordsize;
845  row->GetCFAValue().SetIsRegisterPlusOffset(x86_64_eh_regnum::rsp, offset);
846 
847  row->SetOffset(0);
848  row->SetRegisterLocationToAtCFAPlusOffset(x86_64_eh_regnum::rip,
849  wordsize * -1, true);
850  row->SetRegisterLocationToIsCFAPlusOffset(x86_64_eh_regnum::rsp, 0, true);
851 
852  if (register_count > 0) {
853 
854  // We need to include (up to) 6 registers in 10 bits. That would be 18
855  // bits if we just used 3 bits per reg to indicate the order they're
856  // saved on the stack.
857  //
858  // This is done with Lehmer code permutation, e.g. see
859  // http://stackoverflow.com/questions/1506078/fast-permutation-number-
860  // permutation-mapping-algorithms
861  int permunreg[6] = {0, 0, 0, 0, 0, 0};
862 
863  // This decodes the variable-base number in the 10 bits and gives us the
864  // Lehmer code sequence which can then be decoded.
865 
866  switch (register_count) {
867  case 6:
868  permunreg[0] = permutation / 120; // 120 == 5!
869  permutation -= (permunreg[0] * 120);
870  permunreg[1] = permutation / 24; // 24 == 4!
871  permutation -= (permunreg[1] * 24);
872  permunreg[2] = permutation / 6; // 6 == 3!
873  permutation -= (permunreg[2] * 6);
874  permunreg[3] = permutation / 2; // 2 == 2!
875  permutation -= (permunreg[3] * 2);
876  permunreg[4] = permutation; // 1 == 1!
877  permunreg[5] = 0;
878  break;
879  case 5:
880  permunreg[0] = permutation / 120;
881  permutation -= (permunreg[0] * 120);
882  permunreg[1] = permutation / 24;
883  permutation -= (permunreg[1] * 24);
884  permunreg[2] = permutation / 6;
885  permutation -= (permunreg[2] * 6);
886  permunreg[3] = permutation / 2;
887  permutation -= (permunreg[3] * 2);
888  permunreg[4] = permutation;
889  break;
890  case 4:
891  permunreg[0] = permutation / 60;
892  permutation -= (permunreg[0] * 60);
893  permunreg[1] = permutation / 12;
894  permutation -= (permunreg[1] * 12);
895  permunreg[2] = permutation / 3;
896  permutation -= (permunreg[2] * 3);
897  permunreg[3] = permutation;
898  break;
899  case 3:
900  permunreg[0] = permutation / 20;
901  permutation -= (permunreg[0] * 20);
902  permunreg[1] = permutation / 4;
903  permutation -= (permunreg[1] * 4);
904  permunreg[2] = permutation;
905  break;
906  case 2:
907  permunreg[0] = permutation / 5;
908  permutation -= (permunreg[0] * 5);
909  permunreg[1] = permutation;
910  break;
911  case 1:
912  permunreg[0] = permutation;
913  break;
914  }
915 
916  // Decode the Lehmer code for this permutation of the registers v.
917  // http://en.wikipedia.org/wiki/Lehmer_code
918 
919  int registers[6] = {UNWIND_X86_64_REG_NONE, UNWIND_X86_64_REG_NONE,
922  bool used[7] = {false, false, false, false, false, false, false};
923  for (uint32_t i = 0; i < register_count; i++) {
924  int renum = 0;
925  for (int j = 1; j < 7; j++) {
926  if (!used[j]) {
927  if (renum == permunreg[i]) {
928  registers[i] = j;
929  used[j] = true;
930  break;
931  }
932  renum++;
933  }
934  }
935  }
936 
937  uint32_t saved_registers_offset = 1;
938  saved_registers_offset++;
939 
940  for (int i = (sizeof(registers) / sizeof(int)) - 1; i >= 0; i--) {
941  switch (registers[i]) {
943  break;
950  row->SetRegisterLocationToAtCFAPlusOffset(
952  wordsize * -saved_registers_offset, true);
953  saved_registers_offset++;
954  break;
955  }
956  }
957  }
958  unwind_plan.AppendRow(row);
959  return true;
960  } break;
961 
962  case UNWIND_X86_64_MODE_DWARF: {
963  return false;
964  } break;
965 
966  case 0: {
967  return false;
968  } break;
969  }
970  return false;
971 }
972 
974  eax = 0,
975  ecx = 1,
976  edx = 2,
977  ebx = 3,
978  ebp = 4,
979  esp = 5,
980  esi = 6,
981  edi = 7,
982  eip = 8 // this is officially the Return Address register number, but close
983  // enough
984 };
985 
986 // Convert the compact_unwind_info.h register numbering scheme to
987 // eRegisterKindEHFrame (eh_frame) register numbering scheme.
989  switch (unwind_regno) {
990  case UNWIND_X86_REG_EBX:
991  return i386_eh_regnum::ebx;
992  case UNWIND_X86_REG_ECX:
993  return i386_eh_regnum::ecx;
994  case UNWIND_X86_REG_EDX:
995  return i386_eh_regnum::edx;
996  case UNWIND_X86_REG_EDI:
997  return i386_eh_regnum::edi;
998  case UNWIND_X86_REG_ESI:
999  return i386_eh_regnum::esi;
1000  case UNWIND_X86_REG_EBP:
1001  return i386_eh_regnum::ebp;
1002  default:
1003  return LLDB_INVALID_REGNUM;
1004  }
1005 }
1006 
1008  FunctionInfo &function_info,
1009  UnwindPlan &unwind_plan,
1010  Address pc_or_function_start) {
1011  unwind_plan.SetSourceName("compact unwind info");
1012  unwind_plan.SetSourcedFromCompiler(eLazyBoolYes);
1016 
1017  unwind_plan.SetLSDAAddress(function_info.lsda_address);
1018  unwind_plan.SetPersonalityFunctionPtr(function_info.personality_ptr_address);
1019 
1021 
1022  const int wordsize = 4;
1023  int mode = function_info.encoding & UNWIND_X86_MODE_MASK;
1024  switch (mode) {
1025  case UNWIND_X86_MODE_EBP_FRAME: {
1026  row->GetCFAValue().SetIsRegisterPlusOffset(
1028  row->SetOffset(0);
1029  row->SetRegisterLocationToAtCFAPlusOffset(i386_eh_regnum::ebp,
1030  wordsize * -2, true);
1031  row->SetRegisterLocationToAtCFAPlusOffset(i386_eh_regnum::eip,
1032  wordsize * -1, true);
1033  row->SetRegisterLocationToIsCFAPlusOffset(i386_eh_regnum::esp, 0, true);
1034 
1035  uint32_t saved_registers_offset =
1036  EXTRACT_BITS(function_info.encoding, UNWIND_X86_EBP_FRAME_OFFSET);
1037 
1038  uint32_t saved_registers_locations =
1039  EXTRACT_BITS(function_info.encoding, UNWIND_X86_EBP_FRAME_REGISTERS);
1040 
1041  saved_registers_offset += 2;
1042 
1043  for (int i = 0; i < 5; i++) {
1044  uint32_t regnum = saved_registers_locations & 0x7;
1045  switch (regnum) {
1046  case UNWIND_X86_REG_NONE:
1047  break;
1048  case UNWIND_X86_REG_EBX:
1049  case UNWIND_X86_REG_ECX:
1050  case UNWIND_X86_REG_EDX:
1051  case UNWIND_X86_REG_EDI:
1052  case UNWIND_X86_REG_ESI:
1053  row->SetRegisterLocationToAtCFAPlusOffset(
1055  wordsize * -saved_registers_offset, true);
1056  break;
1057  }
1058  saved_registers_offset--;
1059  saved_registers_locations >>= 3;
1060  }
1061  unwind_plan.AppendRow(row);
1062  return true;
1063  } break;
1064 
1065  case UNWIND_X86_MODE_STACK_IND:
1066  case UNWIND_X86_MODE_STACK_IMMD: {
1067  uint32_t stack_size =
1068  EXTRACT_BITS(function_info.encoding, UNWIND_X86_FRAMELESS_STACK_SIZE);
1069  uint32_t register_count = EXTRACT_BITS(
1070  function_info.encoding, UNWIND_X86_FRAMELESS_STACK_REG_COUNT);
1071  uint32_t permutation = EXTRACT_BITS(
1072  function_info.encoding, UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION);
1073 
1074  if (mode == UNWIND_X86_MODE_STACK_IND &&
1075  function_info.valid_range_offset_start != 0) {
1076  uint32_t stack_adjust = EXTRACT_BITS(function_info.encoding,
1077  UNWIND_X86_FRAMELESS_STACK_ADJUST);
1078 
1079  // offset into the function instructions; 0 == beginning of first
1080  // instruction
1081  uint32_t offset_to_subl_insn =
1082  EXTRACT_BITS(function_info.encoding, UNWIND_X86_FRAMELESS_STACK_SIZE);
1083 
1085  if (sl) {
1086  ProcessSP process_sp = target.GetProcessSP();
1087  if (process_sp) {
1088  Address subl_payload_addr(function_info.valid_range_offset_start, sl);
1089  subl_payload_addr.Slide(offset_to_subl_insn);
1090  Status error;
1091  uint64_t large_stack_size = process_sp->ReadUnsignedIntegerFromMemory(
1092  subl_payload_addr.GetLoadAddress(&target), 4, 0, error);
1093  if (large_stack_size != 0 && error.Success()) {
1094  // Got the large stack frame size correctly - use it
1095  stack_size = large_stack_size + (stack_adjust * wordsize);
1096  } else {
1097  return false;
1098  }
1099  } else {
1100  return false;
1101  }
1102  } else {
1103  return false;
1104  }
1105  }
1106 
1107  int32_t offset =
1108  mode == UNWIND_X86_MODE_STACK_IND ? stack_size : stack_size * wordsize;
1109  row->GetCFAValue().SetIsRegisterPlusOffset(i386_eh_regnum::esp, offset);
1110  row->SetOffset(0);
1111  row->SetRegisterLocationToAtCFAPlusOffset(i386_eh_regnum::eip,
1112  wordsize * -1, true);
1113  row->SetRegisterLocationToIsCFAPlusOffset(i386_eh_regnum::esp, 0, true);
1114 
1115  if (register_count > 0) {
1116 
1117  // We need to include (up to) 6 registers in 10 bits. That would be 18
1118  // bits if we just used 3 bits per reg to indicate the order they're
1119  // saved on the stack.
1120  //
1121  // This is done with Lehmer code permutation, e.g. see
1122  // http://stackoverflow.com/questions/1506078/fast-permutation-number-
1123  // permutation-mapping-algorithms
1124  int permunreg[6] = {0, 0, 0, 0, 0, 0};
1125 
1126  // This decodes the variable-base number in the 10 bits and gives us the
1127  // Lehmer code sequence which can then be decoded.
1128 
1129  switch (register_count) {
1130  case 6:
1131  permunreg[0] = permutation / 120; // 120 == 5!
1132  permutation -= (permunreg[0] * 120);
1133  permunreg[1] = permutation / 24; // 24 == 4!
1134  permutation -= (permunreg[1] * 24);
1135  permunreg[2] = permutation / 6; // 6 == 3!
1136  permutation -= (permunreg[2] * 6);
1137  permunreg[3] = permutation / 2; // 2 == 2!
1138  permutation -= (permunreg[3] * 2);
1139  permunreg[4] = permutation; // 1 == 1!
1140  permunreg[5] = 0;
1141  break;
1142  case 5:
1143  permunreg[0] = permutation / 120;
1144  permutation -= (permunreg[0] * 120);
1145  permunreg[1] = permutation / 24;
1146  permutation -= (permunreg[1] * 24);
1147  permunreg[2] = permutation / 6;
1148  permutation -= (permunreg[2] * 6);
1149  permunreg[3] = permutation / 2;
1150  permutation -= (permunreg[3] * 2);
1151  permunreg[4] = permutation;
1152  break;
1153  case 4:
1154  permunreg[0] = permutation / 60;
1155  permutation -= (permunreg[0] * 60);
1156  permunreg[1] = permutation / 12;
1157  permutation -= (permunreg[1] * 12);
1158  permunreg[2] = permutation / 3;
1159  permutation -= (permunreg[2] * 3);
1160  permunreg[3] = permutation;
1161  break;
1162  case 3:
1163  permunreg[0] = permutation / 20;
1164  permutation -= (permunreg[0] * 20);
1165  permunreg[1] = permutation / 4;
1166  permutation -= (permunreg[1] * 4);
1167  permunreg[2] = permutation;
1168  break;
1169  case 2:
1170  permunreg[0] = permutation / 5;
1171  permutation -= (permunreg[0] * 5);
1172  permunreg[1] = permutation;
1173  break;
1174  case 1:
1175  permunreg[0] = permutation;
1176  break;
1177  }
1178 
1179  // Decode the Lehmer code for this permutation of the registers v.
1180  // http://en.wikipedia.org/wiki/Lehmer_code
1181 
1182  int registers[6] = {UNWIND_X86_REG_NONE, UNWIND_X86_REG_NONE,
1185  bool used[7] = {false, false, false, false, false, false, false};
1186  for (uint32_t i = 0; i < register_count; i++) {
1187  int renum = 0;
1188  for (int j = 1; j < 7; j++) {
1189  if (!used[j]) {
1190  if (renum == permunreg[i]) {
1191  registers[i] = j;
1192  used[j] = true;
1193  break;
1194  }
1195  renum++;
1196  }
1197  }
1198  }
1199 
1200  uint32_t saved_registers_offset = 1;
1201  saved_registers_offset++;
1202 
1203  for (int i = (sizeof(registers) / sizeof(int)) - 1; i >= 0; i--) {
1204  switch (registers[i]) {
1205  case UNWIND_X86_REG_NONE:
1206  break;
1207  case UNWIND_X86_REG_EBX:
1208  case UNWIND_X86_REG_ECX:
1209  case UNWIND_X86_REG_EDX:
1210  case UNWIND_X86_REG_EDI:
1211  case UNWIND_X86_REG_ESI:
1212  case UNWIND_X86_REG_EBP:
1213  row->SetRegisterLocationToAtCFAPlusOffset(
1214  translate_to_eh_frame_regnum_i386(registers[i]),
1215  wordsize * -saved_registers_offset, true);
1216  saved_registers_offset++;
1217  break;
1218  }
1219  }
1220  }
1221 
1222  unwind_plan.AppendRow(row);
1223  return true;
1224  } break;
1225 
1226  case UNWIND_X86_MODE_DWARF: {
1227  return false;
1228  } break;
1229  }
1230  return false;
1231 }
1232 
1233 // DWARF register numbers from "DWARF for the ARM 64-bit Architecture (AArch64)"
1234 // doc by ARM
1235 
1237  x19 = 19,
1238  x20 = 20,
1239  x21 = 21,
1240  x22 = 22,
1241  x23 = 23,
1242  x24 = 24,
1243  x25 = 25,
1244  x26 = 26,
1245  x27 = 27,
1246  x28 = 28,
1247 
1248  fp = 29,
1249  ra = 30,
1250  sp = 31,
1251  pc = 32,
1252 
1253  // Compact unwind encodes d8-d15 but we don't have eh_frame / dwarf reg #'s
1254  // for the 64-bit fp regs. Normally in DWARF it's context sensitive - so it
1255  // knows it is fetching a 32- or 64-bit quantity from reg v8 to indicate s0
1256  // or d0 - but the unwinder is operating at a lower level and we'd try to
1257  // fetch 128 bits if we were told that v8 were stored on the stack...
1258  v8 = 72,
1259  v9 = 73,
1260  v10 = 74,
1261  v11 = 75,
1262  v12 = 76,
1263  v13 = 77,
1264  v14 = 78,
1265  v15 = 79,
1266 };
1267 
1269  arm_r0 = 0,
1270  arm_r1 = 1,
1271  arm_r2 = 2,
1272  arm_r3 = 3,
1273  arm_r4 = 4,
1274  arm_r5 = 5,
1275  arm_r6 = 6,
1276  arm_r7 = 7,
1277  arm_r8 = 8,
1278  arm_r9 = 9,
1279  arm_r10 = 10,
1280  arm_r11 = 11,
1281  arm_r12 = 12,
1282 
1283  arm_sp = 13,
1284  arm_lr = 14,
1285  arm_pc = 15,
1286 
1287  arm_d0 = 256,
1288  arm_d1 = 257,
1289  arm_d2 = 258,
1290  arm_d3 = 259,
1291  arm_d4 = 260,
1292  arm_d5 = 261,
1293  arm_d6 = 262,
1294  arm_d7 = 263,
1295  arm_d8 = 264,
1296  arm_d9 = 265,
1297  arm_d10 = 266,
1298  arm_d11 = 267,
1299  arm_d12 = 268,
1300  arm_d13 = 269,
1301  arm_d14 = 270,
1302 };
1303 
1305  FunctionInfo &function_info,
1306  UnwindPlan &unwind_plan,
1307  Address pc_or_function_start) {
1308  unwind_plan.SetSourceName("compact unwind info");
1309  unwind_plan.SetSourcedFromCompiler(eLazyBoolYes);
1313 
1314  unwind_plan.SetLSDAAddress(function_info.lsda_address);
1315  unwind_plan.SetPersonalityFunctionPtr(function_info.personality_ptr_address);
1316 
1318 
1319  const int wordsize = 8;
1320  int mode = function_info.encoding & UNWIND_ARM64_MODE_MASK;
1321 
1322  if (mode == UNWIND_ARM64_MODE_DWARF)
1323  return false;
1324 
1325  if (mode == UNWIND_ARM64_MODE_FRAMELESS) {
1326  row->SetOffset(0);
1327 
1328  uint32_t stack_size =
1329  (EXTRACT_BITS(function_info.encoding,
1330  UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK)) *
1331  16;
1332 
1333  // Our previous Call Frame Address is the stack pointer plus the stack size
1334  row->GetCFAValue().SetIsRegisterPlusOffset(arm64_eh_regnum::sp, stack_size);
1335 
1336  // Our previous PC is in the LR
1337  row->SetRegisterLocationToRegister(arm64_eh_regnum::pc, arm64_eh_regnum::ra,
1338  true);
1339 
1340  unwind_plan.AppendRow(row);
1341  return true;
1342  }
1343 
1344  // Should not be possible
1345  if (mode != UNWIND_ARM64_MODE_FRAME)
1346  return false;
1347 
1348  // mode == UNWIND_ARM64_MODE_FRAME
1349 
1350  row->GetCFAValue().SetIsRegisterPlusOffset(arm64_eh_regnum::fp, 2 * wordsize);
1351  row->SetOffset(0);
1352  row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::fp, wordsize * -2,
1353  true);
1354  row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::pc, wordsize * -1,
1355  true);
1356  row->SetRegisterLocationToIsCFAPlusOffset(arm64_eh_regnum::sp, 0, true);
1357 
1358  int reg_pairs_saved_count = 1;
1359 
1360  uint32_t saved_register_bits = function_info.encoding & 0xfff;
1361 
1362  if (saved_register_bits & UNWIND_ARM64_FRAME_X19_X20_PAIR) {
1363  int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
1364  cfa_offset -= wordsize;
1365  row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x19, cfa_offset,
1366  true);
1367  cfa_offset -= wordsize;
1368  row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x20, cfa_offset,
1369  true);
1370  reg_pairs_saved_count++;
1371  }
1372 
1373  if (saved_register_bits & UNWIND_ARM64_FRAME_X21_X22_PAIR) {
1374  int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
1375  cfa_offset -= wordsize;
1376  row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x21, cfa_offset,
1377  true);
1378  cfa_offset -= wordsize;
1379  row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x22, cfa_offset,
1380  true);
1381  reg_pairs_saved_count++;
1382  }
1383 
1384  if (saved_register_bits & UNWIND_ARM64_FRAME_X23_X24_PAIR) {
1385  int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
1386  cfa_offset -= wordsize;
1387  row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x23, cfa_offset,
1388  true);
1389  cfa_offset -= wordsize;
1390  row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x24, cfa_offset,
1391  true);
1392  reg_pairs_saved_count++;
1393  }
1394 
1395  if (saved_register_bits & UNWIND_ARM64_FRAME_X25_X26_PAIR) {
1396  int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
1397  cfa_offset -= wordsize;
1398  row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x25, cfa_offset,
1399  true);
1400  cfa_offset -= wordsize;
1401  row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x26, cfa_offset,
1402  true);
1403  reg_pairs_saved_count++;
1404  }
1405 
1406  if (saved_register_bits & UNWIND_ARM64_FRAME_X27_X28_PAIR) {
1407  int cfa_offset = reg_pairs_saved_count * -2 * wordsize;
1408  cfa_offset -= wordsize;
1409  row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x27, cfa_offset,
1410  true);
1411  cfa_offset -= wordsize;
1412  row->SetRegisterLocationToAtCFAPlusOffset(arm64_eh_regnum::x28, cfa_offset,
1413  true);
1414  reg_pairs_saved_count++;
1415  }
1416 
1417  // If we use the v8-v15 regnums here, the unwinder will try to grab 128 bits
1418  // off the stack;
1419  // not sure if we have a good way to represent the 64-bitness of these saves.
1420 
1421  if (saved_register_bits & UNWIND_ARM64_FRAME_D8_D9_PAIR) {
1422  reg_pairs_saved_count++;
1423  }
1424  if (saved_register_bits & UNWIND_ARM64_FRAME_D10_D11_PAIR) {
1425  reg_pairs_saved_count++;
1426  }
1427  if (saved_register_bits & UNWIND_ARM64_FRAME_D12_D13_PAIR) {
1428  reg_pairs_saved_count++;
1429  }
1430  if (saved_register_bits & UNWIND_ARM64_FRAME_D14_D15_PAIR) {
1431  reg_pairs_saved_count++;
1432  }
1433 
1434  unwind_plan.AppendRow(row);
1435  return true;
1436 }
1437 
1439  FunctionInfo &function_info,
1440  UnwindPlan &unwind_plan,
1441  Address pc_or_function_start) {
1442  unwind_plan.SetSourceName("compact unwind info");
1443  unwind_plan.SetSourcedFromCompiler(eLazyBoolYes);
1447 
1448  unwind_plan.SetLSDAAddress(function_info.lsda_address);
1449  unwind_plan.SetPersonalityFunctionPtr(function_info.personality_ptr_address);
1450 
1452 
1453  const int wordsize = 4;
1454  int mode = function_info.encoding & UNWIND_ARM_MODE_MASK;
1455 
1456  if (mode == UNWIND_ARM_MODE_DWARF)
1457  return false;
1458 
1459  uint32_t stack_adjust = (EXTRACT_BITS(function_info.encoding,
1460  UNWIND_ARM_FRAME_STACK_ADJUST_MASK)) *
1461  wordsize;
1462 
1463  row->GetCFAValue().SetIsRegisterPlusOffset(arm_r7,
1464  (2 * wordsize) + stack_adjust);
1465  row->SetOffset(0);
1466  row->SetRegisterLocationToAtCFAPlusOffset(
1467  arm_r7, (wordsize * -2) - stack_adjust, true);
1468  row->SetRegisterLocationToAtCFAPlusOffset(
1469  arm_pc, (wordsize * -1) - stack_adjust, true);
1470  row->SetRegisterLocationToIsCFAPlusOffset(arm_sp, 0, true);
1471 
1472  int cfa_offset = -stack_adjust - (2 * wordsize);
1473 
1474  uint32_t saved_register_bits = function_info.encoding & 0xff;
1475 
1476  if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R6) {
1477  cfa_offset -= wordsize;
1478  row->SetRegisterLocationToAtCFAPlusOffset(arm_r6, cfa_offset, true);
1479  }
1480 
1481  if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R5) {
1482  cfa_offset -= wordsize;
1483  row->SetRegisterLocationToAtCFAPlusOffset(arm_r5, cfa_offset, true);
1484  }
1485 
1486  if (saved_register_bits & UNWIND_ARM_FRAME_FIRST_PUSH_R4) {
1487  cfa_offset -= wordsize;
1488  row->SetRegisterLocationToAtCFAPlusOffset(arm_r4, cfa_offset, true);
1489  }
1490 
1491  if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R12) {
1492  cfa_offset -= wordsize;
1493  row->SetRegisterLocationToAtCFAPlusOffset(arm_r12, cfa_offset, true);
1494  }
1495 
1496  if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R11) {
1497  cfa_offset -= wordsize;
1498  row->SetRegisterLocationToAtCFAPlusOffset(arm_r11, cfa_offset, true);
1499  }
1500 
1501  if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R10) {
1502  cfa_offset -= wordsize;
1503  row->SetRegisterLocationToAtCFAPlusOffset(arm_r10, cfa_offset, true);
1504  }
1505 
1506  if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R9) {
1507  cfa_offset -= wordsize;
1508  row->SetRegisterLocationToAtCFAPlusOffset(arm_r9, cfa_offset, true);
1509  }
1510 
1511  if (saved_register_bits & UNWIND_ARM_FRAME_SECOND_PUSH_R8) {
1512  cfa_offset -= wordsize;
1513  row->SetRegisterLocationToAtCFAPlusOffset(arm_r8, cfa_offset, true);
1514  }
1515 
1516  if (mode == UNWIND_ARM_MODE_FRAME_D) {
1517  uint32_t d_reg_bits =
1518  EXTRACT_BITS(function_info.encoding, UNWIND_ARM_FRAME_D_REG_COUNT_MASK);
1519  switch (d_reg_bits) {
1520  case 0:
1521  // vpush {d8}
1522  cfa_offset -= 8;
1523  row->SetRegisterLocationToAtCFAPlusOffset(arm_d8, cfa_offset, true);
1524  break;
1525  case 1:
1526  // vpush {d10}
1527  // vpush {d8}
1528  cfa_offset -= 8;
1529  row->SetRegisterLocationToAtCFAPlusOffset(arm_d10, cfa_offset, true);
1530  cfa_offset -= 8;
1531  row->SetRegisterLocationToAtCFAPlusOffset(arm_d8, cfa_offset, true);
1532  break;
1533  case 2:
1534  // vpush {d12}
1535  // vpush {d10}
1536  // vpush {d8}
1537  cfa_offset -= 8;
1538  row->SetRegisterLocationToAtCFAPlusOffset(arm_d12, cfa_offset, true);
1539  cfa_offset -= 8;
1540  row->SetRegisterLocationToAtCFAPlusOffset(arm_d10, cfa_offset, true);
1541  cfa_offset -= 8;
1542  row->SetRegisterLocationToAtCFAPlusOffset(arm_d8, cfa_offset, true);
1543  break;
1544  case 3:
1545  // vpush {d14}
1546  // vpush {d12}
1547  // vpush {d10}
1548  // vpush {d8}
1549  cfa_offset -= 8;
1550  row->SetRegisterLocationToAtCFAPlusOffset(arm_d14, cfa_offset, true);
1551  cfa_offset -= 8;
1552  row->SetRegisterLocationToAtCFAPlusOffset(arm_d12, cfa_offset, true);
1553  cfa_offset -= 8;
1554  row->SetRegisterLocationToAtCFAPlusOffset(arm_d10, cfa_offset, true);
1555  cfa_offset -= 8;
1556  row->SetRegisterLocationToAtCFAPlusOffset(arm_d8, cfa_offset, true);
1557  break;
1558  case 4:
1559  // vpush {d14}
1560  // vpush {d12}
1561  // sp = (sp - 24) & (-16);
1562  // vst {d8, d9, d10}
1563  cfa_offset -= 8;
1564  row->SetRegisterLocationToAtCFAPlusOffset(arm_d14, cfa_offset, true);
1565  cfa_offset -= 8;
1566  row->SetRegisterLocationToAtCFAPlusOffset(arm_d12, cfa_offset, true);
1567 
1568  // FIXME we don't have a way to represent reg saves at an specific
1569  // alignment short of
1570  // coming up with some DWARF location description.
1571 
1572  break;
1573  case 5:
1574  // vpush {d14}
1575  // sp = (sp - 40) & (-16);
1576  // vst {d8, d9, d10, d11}
1577  // vst {d12}
1578 
1579  cfa_offset -= 8;
1580  row->SetRegisterLocationToAtCFAPlusOffset(arm_d14, cfa_offset, true);
1581 
1582  // FIXME we don't have a way to represent reg saves at an specific
1583  // alignment short of
1584  // coming up with some DWARF location description.
1585 
1586  break;
1587  case 6:
1588  // sp = (sp - 56) & (-16);
1589  // vst {d8, d9, d10, d11}
1590  // vst {d12, d13, d14}
1591 
1592  // FIXME we don't have a way to represent reg saves at an specific
1593  // alignment short of
1594  // coming up with some DWARF location description.
1595 
1596  break;
1597  case 7:
1598  // sp = (sp - 64) & (-16);
1599  // vst {d8, d9, d10, d11}
1600  // vst {d12, d13, d14, d15}
1601 
1602  // FIXME we don't have a way to represent reg saves at an specific
1603  // alignment short of
1604  // coming up with some DWARF location description.
1605 
1606  break;
1607  }
1608  }
1609 
1610  unwind_plan.AppendRow(row);
1611  return true;
1612 }
lldb_private::ObjectFile::GetArchitecture
virtual ArchSpec GetArchitecture()=0
Get the ArchSpec for this object file.
x27
@ x27
Definition: CompactUnwindInfo.cpp:1245
v12
@ v12
Definition: CompactUnwindInfo.cpp:1262
arm_r7
@ arm_r7
Definition: CompactUnwindInfo.cpp:1276
lldb_private::CompactUnwindInfo::UnwindIndex::second_level
uint32_t second_level
Definition: CompactUnwindInfo.h:55
r12
@ r12
Definition: CompactUnwindInfo.cpp:706
arm_r9
@ arm_r9
Definition: CompactUnwindInfo.cpp:1278
lldb_private::UnwindPlan::AppendRow
void AppendRow(const RowSP &row_sp)
Definition: UnwindPlan.cpp:362
lldb_private::UNWIND_X86_REG_EBP
@ UNWIND_X86_REG_EBP
Definition: CompactUnwindInfo.cpp:64
lldb_private::Stream::GetAddressByteSize
uint32_t GetAddressByteSize() const
Get the address size in bytes.
Definition: Stream.cpp:179
lldb_private::ArchSpec
Definition: ArchSpec.h:33
arm_d5
@ arm_d5
Definition: CompactUnwindInfo.cpp:1292
rax
@ rax
Definition: CompactUnwindInfo.cpp:694
x20
@ x20
Definition: CompactUnwindInfo.cpp:1238
lldb_private::Log::GetVerbose
bool GetVerbose() const
Definition: Log.cpp:268
LLDB_INVALID_REGNUM
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:79
lldb_private::Address::Clear
void Clear()
Clear the object's state.
Definition: Address.h:178
v10
@ v10
Definition: CompactUnwindInfo.cpp:1260
arm_d1
@ arm_d1
Definition: CompactUnwindInfo.cpp:1288
lldb_private::CompactUnwindInfo::CreateUnwindPlan_i386
bool CreateUnwindPlan_i386(Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start)
Definition: CompactUnwindInfo.cpp:1007
lldb_private::UnwindPlan::SetRegisterKind
void SetRegisterKind(lldb::RegisterKind kind)
Definition: UnwindPlan.h:437
esp
@ esp
Definition: CompactUnwindInfo.cpp:979
lldb_private::CompactUnwindInfo::m_indexes_computed
LazyBool m_indexes_computed
Definition: CompactUnwindInfo.h:149
arm_d10
@ arm_d10
Definition: CompactUnwindInfo.cpp:1297
lldb_private::CompactUnwindInfo::IsValid
bool IsValid(const lldb::ProcessSP &process_sp)
Definition: CompactUnwindInfo.cpp:233
arm_d9
@ arm_d9
Definition: CompactUnwindInfo.cpp:1296
x19
@ x19
Definition: CompactUnwindInfo.cpp:1237
r10
@ r10
Definition: CompactUnwindInfo.cpp:704
lldb_private::UnwindPlan::SetUnwindPlanValidAtAllInstructions
void SetUnwindPlanValidAtAllInstructions(lldb_private::LazyBool valid_at_all_insn)
Definition: UnwindPlan.h:490
lldb_private::CompactUnwindInfo::m_indexes
std::vector< UnwindIndex > m_indexes
Definition: CompactUnwindInfo.h:147
lldb_private::eLazyBoolYes
@ eLazyBoolYes
Definition: lldb-private-enumerations.h:115
LLDB_LOGF
#define LLDB_LOGF(log,...)
Definition: Log.h:270
arm_d7
@ arm_d7
Definition: CompactUnwindInfo.cpp:1294
Module.h
lldb_private::CompactUnwindInfo::UnwindHeader::common_encodings_array_offset
uint32_t common_encodings_array_offset
Definition: CompactUnwindInfo.h:94
lldb_private::UNWIND_X86_REG_ESI
@ UNWIND_X86_REG_ESI
Definition: CompactUnwindInfo.cpp:63
lldb_private::ObjectFile::ReadSectionData
virtual size_t ReadSectionData(Section *section, lldb::offset_t section_offset, void *dst, size_t dst_len)
Definition: ObjectFile.cpp:474
ebp
@ ebp
Definition: CompactUnwindInfo.cpp:978
lldb_private::SectionList
Definition: Section.h:34
lldb_private::UnwindPlan::SetUnwindPlanForSignalTrap
void SetUnwindPlanForSignalTrap(lldb_private::LazyBool is_for_signal_trap)
Definition: UnwindPlan.h:502
lldb::offset_t
uint64_t offset_t
Definition: lldb-types.h:87
lldb_private::CompactUnwindInfo::GetCompactUnwindInfoForFunction
bool GetCompactUnwindInfoForFunction(Target &target, Address address, FunctionInfo &unwind_info)
Definition: CompactUnwindInfo.cpp:492
ebx
@ ebx
Definition: CompactUnwindInfo.cpp:977
rdi
@ rdi
Definition: CompactUnwindInfo.cpp:699
v9
@ v9
Definition: CompactUnwindInfo.cpp:1259
ra
@ ra
Definition: CompactUnwindInfo.cpp:1249
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
pc
@ pc
Definition: CompactUnwindInfo.cpp:1251
arm_r6
@ arm_r6
Definition: CompactUnwindInfo.cpp:1275
edx
@ edx
Definition: CompactUnwindInfo.cpp:976
lldb_private::UNWIND_X86_64_REG_R15
@ UNWIND_X86_64_REG_R15
Definition: CompactUnwindInfo.cpp:91
arm_lr
@ arm_lr
Definition: CompactUnwindInfo.cpp:1284
lldb_private::Target
Definition: Target.h:464
lldb_private::UnwindPlan::SetSourceName
void SetSourceName(const char *)
Definition: UnwindPlan.cpp:564
Section.h
lldb_private::CompactUnwindInfo::CreateUnwindPlan_arm64
bool CreateUnwindPlan_arm64(Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start)
Definition: CompactUnwindInfo.cpp:1304
lldb_private::DataExtractor::SetData
lldb::offset_t SetData(const void *bytes, lldb::offset_t length, lldb::ByteOrder byte_order)
Set data with a buffer that is caller owned.
Definition: DataExtractor.cpp:223
translate_to_eh_frame_regnum_x86_64
uint32_t translate_to_eh_frame_regnum_x86_64(uint32_t unwind_regno)
Definition: CompactUnwindInfo.cpp:716
lldb_private::UNWIND_X86_REG_EBX
@ UNWIND_X86_REG_EBX
Definition: CompactUnwindInfo.cpp:59
arm_r4
@ arm_r4
Definition: CompactUnwindInfo.cpp:1273
arm_d6
@ arm_d6
Definition: CompactUnwindInfo.cpp:1293
Process.h
lldb_private::CompactUnwindInfo::GetUnwindPlan
bool GetUnwindPlan(Target &target, Address addr, UnwindPlan &unwind_plan)
Definition: CompactUnwindInfo.cpp:173
lldb_private::UNWIND_X86_64_REG_R14
@ UNWIND_X86_64_REG_R14
Definition: CompactUnwindInfo.cpp:90
arm_pc
@ arm_pc
Definition: CompactUnwindInfo.cpp:1285
arm_r3
@ arm_r3
Definition: CompactUnwindInfo.cpp:1272
Target.h
lldb_private::DataExtractor::SetByteOrder
void SetByteOrder(lldb::ByteOrder byte_order)
Set the byte_order value.
Definition: DataExtractor.h:931
lldb::eRegisterKindEHFrame
@ eRegisterKindEHFrame
the register numbers seen in eh_frame
Definition: lldb-enumerations.h:228
UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX
#define UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX(entry)
Definition: CompactUnwindInfo.cpp:152
lldb_private::CompactUnwindInfo::m_unwindinfo_data_computed
bool m_unwindinfo_data_computed
Definition: CompactUnwindInfo.h:155
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
lldb_private::UNWIND_X86_REG_EDI
@ UNWIND_X86_REG_EDI
Definition: CompactUnwindInfo.cpp:62
lldb_private::ObjectFile::GetSectionList
virtual SectionList * GetSectionList(bool update_module_section_list=true)
Gets the section list for the currently selected architecture (and object for archives).
Definition: ObjectFile.cpp:588
lldb_private::UNWIND_X86_REG_ECX
@ UNWIND_X86_REG_ECX
Definition: CompactUnwindInfo.cpp:60
CompactUnwindInfo.h
lldb_private::CompactUnwindInfo::m_section_sp
lldb::SectionSP m_section_sp
Definition: CompactUnwindInfo.h:140
r8
@ r8
Definition: CompactUnwindInfo.cpp:702
lldb_private::UnwindPlan::SetPlanValidAddressRange
void SetPlanValidAddressRange(const AddressRange &range)
Definition: UnwindPlan.cpp:431
lldb_private::LLDBLog::Unwind
@ Unwind
x26
@ x26
Definition: CompactUnwindInfo.cpp:1244
rcx
@ rcx
Definition: CompactUnwindInfo.cpp:696
lldb_private::CompactUnwindInfo::UnwindHeader::personality_array_offset
uint32_t personality_array_offset
Definition: CompactUnwindInfo.h:96
arm_r1
@ arm_r1
Definition: CompactUnwindInfo.cpp:1270
lldb_private::CompactUnwindInfo::BinarySearchRegularSecondPage
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)
Definition: CompactUnwindInfo.cpp:412
LLDB_INVALID_OFFSET
#define LLDB_INVALID_OFFSET
Definition: lldb-defines.h:85
lldb_private::CompactUnwindInfo::FunctionInfo
Definition: CompactUnwindInfo.h:79
Log.h
v13
@ v13
Definition: CompactUnwindInfo.cpp:1263
UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET
#define UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(entry)
Definition: CompactUnwindInfo.cpp:148
lldb_private::CompactUnwindInfo::UnwindHeader::version
uint32_t version
Definition: CompactUnwindInfo.h:93
x24
@ x24
Definition: CompactUnwindInfo.cpp:1242
arm_d0
@ arm_d0
Definition: CompactUnwindInfo.cpp:1287
lldb_private::UNWIND_X86_64_REG_R12
@ UNWIND_X86_64_REG_R12
Definition: CompactUnwindInfo.cpp:88
lldb_private::StreamString::GetData
const char * GetData() const
Definition: StreamString.h:43
lldb_private::ObjectFile::GetBaseAddress
virtual lldb_private::Address GetBaseAddress()
Returns base address of this object file.
Definition: ObjectFile.h:497
lldb_private::DataExtractor::SetAddressByteSize
void SetAddressByteSize(uint32_t addr_size)
Set the address byte size.
Definition: DataExtractor.h:845
StreamString.h
lldb_private::Address::GetFileAddress
lldb::addr_t GetFileAddress() const
Get the file address.
Definition: Address.cpp:291
rbx
@ rbx
Definition: CompactUnwindInfo.cpp:697
arm64_eh_regnum
arm64_eh_regnum
Definition: CompactUnwindInfo.cpp:1236
arm_r5
@ arm_r5
Definition: CompactUnwindInfo.cpp:1274
r11
@ r11
Definition: CompactUnwindInfo.cpp:705
lldb_private::UNWIND_X86_64_REG_RBX
@ UNWIND_X86_64_REG_RBX
Definition: CompactUnwindInfo.cpp:87
r14
@ r14
Definition: CompactUnwindInfo.cpp:708
lldb_private::UnwindPlan::SetSourcedFromCompiler
void SetSourcedFromCompiler(lldb_private::LazyBool from_compiler)
Definition: UnwindPlan.h:478
lldb_private::CompactUnwindInfo::CreateUnwindPlan_x86_64
bool CreateUnwindPlan_x86_64(Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start)
Definition: CompactUnwindInfo.cpp:735
lldb_private::StreamString
Definition: StreamString.h:23
lldb_private::AddressRange
Definition: AddressRange.h:25
lldb_private::Host::SystemLog
static void SystemLog(SystemLogType type, const char *format,...) __attribute__((format(printf
Definition: common/Host.cpp:230
i386_eh_regnum
i386_eh_regnum
Definition: CompactUnwindInfo.cpp:973
arm_d2
@ arm_d2
Definition: CompactUnwindInfo.cpp:1289
arm_d4
@ arm_d4
Definition: CompactUnwindInfo.cpp:1291
x86_64_eh_regnum
x86_64_eh_regnum
Definition: CompactUnwindInfo.cpp:693
lldb_private::UNWIND_X86_64_REG_NONE
@ UNWIND_X86_64_REG_NONE
Definition: CompactUnwindInfo.cpp:86
lldb_private::CompactUnwindInfo::m_section_contents_if_encrypted
lldb::WritableDataBufferSP m_section_contents_if_encrypted
Definition: CompactUnwindInfo.h:142
arm_r12
@ arm_r12
Definition: CompactUnwindInfo.cpp:1281
lldb_private::CompactUnwindInfo::UnwindIndex::sentinal_entry
bool sentinal_entry
Definition: CompactUnwindInfo.h:62
sp
@ sp
Definition: CompactUnwindInfo.cpp:1250
lldb_private::UnwindPlan::SetLSDAAddress
void SetLSDAAddress(Address lsda_addr)
Definition: UnwindPlan.h:524
v15
@ v15
Definition: CompactUnwindInfo.cpp:1265
FLAGS_ANONYMOUS_ENUM
#define FLAGS_ANONYMOUS_ENUM()
Definition: lldb-enumerations.h:64
arm_r2
@ arm_r2
Definition: CompactUnwindInfo.cpp:1271
lldb_private::CompactUnwindInfo::UnwindIndex::function_offset
uint32_t function_offset
Definition: CompactUnwindInfo.h:53
lldb_private::CompactUnwindInfo::m_unwindinfo_data
DataExtractor m_unwindinfo_data
Definition: CompactUnwindInfo.h:154
UnwindPlan.h
x22
@ x22
Definition: CompactUnwindInfo.cpp:1240
lldb_private::CompactUnwindInfo::FunctionInfo::personality_ptr_address
Address personality_ptr_address
Definition: CompactUnwindInfo.h:82
lldb_private::UNWIND_X86_REG_NONE
@ UNWIND_X86_REG_NONE
Definition: CompactUnwindInfo.cpp:58
lldb_private::CompactUnwindInfo::~CompactUnwindInfo
~CompactUnwindInfo()
ObjectFile.h
arm_r11
@ arm_r11
Definition: CompactUnwindInfo.cpp:1280
arm_d8
@ arm_d8
Definition: CompactUnwindInfo.cpp:1295
v8
@ v8
Definition: CompactUnwindInfo.cpp:1258
lldb_private::CompactUnwindInfo::BinarySearchCompressedSecondPage
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)
Definition: CompactUnwindInfo.cpp:452
lldb_private::UnwindPlan::RowSP
std::shared_ptr< Row > RowSP
Definition: UnwindPlan.h:395
x23
@ x23
Definition: CompactUnwindInfo.cpp:1241
EXTRACT_BITS
#define EXTRACT_BITS(value, mask)
Definition: CompactUnwindInfo.cpp:156
lldb::eSectionTypeCode
@ eSectionTypeCode
Definition: lldb-enumerations.h:648
lldb_private::CompactUnwindInfo::UnwindHeader::common_encodings_array_count
uint32_t common_encodings_array_count
Definition: CompactUnwindInfo.h:95
lldb_private::Target::GetProcessSP
const lldb::ProcessSP & GetProcessSP() const
Definition: Target.cpp:214
v11
@ v11
Definition: CompactUnwindInfo.cpp:1261
lldb_private::SectionList::FindSectionByType
lldb::SectionSP FindSectionByType(lldb::SectionType sect_type, bool check_children, size_t start_idx=0) const
Definition: Section.cpp:586
lldb_private::UnwindPlan::SetPersonalityFunctionPtr
void SetPersonalityFunctionPtr(Address presonality_func_ptr)
Definition: UnwindPlan.h:528
ecx
@ ecx
Definition: CompactUnwindInfo.cpp:975
lldb_private::CompactUnwindInfo::m_unwind_header
UnwindHeader m_unwind_header
Definition: CompactUnwindInfo.h:158
lldb_private::CompactUnwindInfo::CreateUnwindPlan_armv7
bool CreateUnwindPlan_armv7(Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start)
Definition: CompactUnwindInfo.cpp:1438
lldb_private::Status
Definition: Status.h:44
rdx
@ rdx
Definition: CompactUnwindInfo.cpp:695
lldb_private::Address::Dump
bool Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style=DumpStyleInvalid, uint32_t addr_byte_size=UINT32_MAX, bool all_ranges=false) const
Dump a description of this object to a Stream.
Definition: Address.cpp:406
lldb_private::CompactUnwindInfo::FunctionInfo::valid_range_offset_start
uint32_t valid_range_offset_start
Definition: CompactUnwindInfo.h:85
lldb_private::UnwindPlan::Row
Definition: UnwindPlan.h:55
uint32_t
lldb_private::eLazyBoolNo
@ eLazyBoolNo
Definition: lldb-private-enumerations.h:115
lldb_private::UNWIND_X86_REG_EDX
@ UNWIND_X86_REG_EDX
Definition: CompactUnwindInfo.cpp:61
x28
@ x28
Definition: CompactUnwindInfo.cpp:1246
lldb_private::CompactUnwindInfo::FunctionInfo::valid_range_offset_end
uint32_t valid_range_offset_end
Definition: CompactUnwindInfo.h:87
lldb_private::Address
Definition: Address.h:59
UNWIND_SECOND_LEVEL_REGULAR
#define UNWIND_SECOND_LEVEL_REGULAR
Definition: CompactUnwindInfo.cpp:140
edi
@ edi
Definition: CompactUnwindInfo.cpp:981
arm_eh_regnum
arm_eh_regnum
Definition: CompactUnwindInfo.cpp:1268
lldb_private::Address::GetLoadAddress
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
Definition: Address.cpp:311
lldb_private::CompactUnwindInfo::m_objfile
ObjectFile & m_objfile
Definition: CompactUnwindInfo.h:139
lldb_private::Address::ResolveAddressUsingFileSections
bool ResolveAddressUsingFileSections(lldb::addr_t addr, const SectionList *sections)
Resolve a file virtual address using a section list.
Definition: Address.cpp:248
ArchSpec.h
UINT32_MAX
#define UINT32_MAX
Definition: lldb-defines.h:19
eax
@ eax
Definition: CompactUnwindInfo.cpp:974
lldb_private::ModuleChild::GetModule
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
Definition: ModuleChild.cpp:24
lldb_private::CompactUnwindInfo::FunctionInfo::encoding
uint32_t encoding
Definition: CompactUnwindInfo.h:80
uint16_t
lldb_private::CompactUnwindInfo::UnwindHeader::personality_array_count
uint32_t personality_array_count
Definition: CompactUnwindInfo.h:97
lldb_private::DataExtractor::GetU32
uint32_t GetU32(lldb::offset_t *offset_ptr) const
Extract a uint32_t value from *offset_ptr.
Definition: DataExtractor.cpp:425
rip
@ rip
Definition: CompactUnwindInfo.cpp:710
LLDB_INVALID_ADDRESS
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:74
arm_r0
@ arm_r0
Definition: CompactUnwindInfo.cpp:1269
x25
@ x25
Definition: CompactUnwindInfo.cpp:1243
UNWIND_SECOND_LEVEL_COMPRESSED
#define UNWIND_SECOND_LEVEL_COMPRESSED
Definition: CompactUnwindInfo.cpp:144
lldb_private::CompactUnwindInfo::UnwindIndex::lsda_array_start
uint32_t lsda_array_start
Definition: CompactUnwindInfo.h:58
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::DataExtractor::GetU16
uint16_t GetU16(lldb::offset_t *offset_ptr) const
Extract a uint16_t value from *offset_ptr.
Definition: DataExtractor.cpp:347
lldb_private::eLazyBoolCalculate
@ eLazyBoolCalculate
Definition: lldb-private-enumerations.h:115
arm_d13
@ arm_d13
Definition: CompactUnwindInfo.cpp:1300
translate_to_eh_frame_regnum_i386
uint32_t translate_to_eh_frame_regnum_i386(uint32_t unwind_regno)
Definition: CompactUnwindInfo.cpp:988
lldb_private::CompactUnwindInfo::m_mutex
std::mutex m_mutex
Definition: CompactUnwindInfo.h:146
r15
@ r15
Definition: CompactUnwindInfo.cpp:709
arm_r8
@ arm_r8
Definition: CompactUnwindInfo.cpp:1277
lldb_private::CompactUnwindInfo::ScanIndex
void ScanIndex(const lldb::ProcessSP &process_sp)
Definition: CompactUnwindInfo.cpp:245
arm_d14
@ arm_d14
Definition: CompactUnwindInfo.cpp:1301
lldb_private::Host::eSystemLogError
@ eSystemLogError
Definition: Host.h:89
lldb_private::CompactUnwindInfo::FunctionInfo::lsda_address
Address lsda_address
Definition: CompactUnwindInfo.h:81
lldb_private::CompactUnwindInfo::UnwindIndex
Definition: CompactUnwindInfo.h:52
lldb_private::Log
Definition: Log.h:48
arm_d11
@ arm_d11
Definition: CompactUnwindInfo.cpp:1298
arm_d3
@ arm_d3
Definition: CompactUnwindInfo.cpp:1290
arm_d12
@ arm_d12
Definition: CompactUnwindInfo.cpp:1299
esi
@ esi
Definition: CompactUnwindInfo.cpp:980
x21
@ x21
Definition: CompactUnwindInfo.cpp:1239
lldb_private::GetLog
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:235
fp
@ fp
Definition: CompactUnwindInfo.cpp:1248
lldb_private::DataExtractor::GetByteSize
uint64_t GetByteSize() const
Get the number of bytes contained in this object.
Definition: DataExtractor.h:270
rsi
@ rsi
Definition: CompactUnwindInfo.cpp:698
r9
@ r9
Definition: CompactUnwindInfo.cpp:703
lldb_private::Address::Slide
bool Slide(int64_t offset)
Definition: Address.h:449
lldb_private::UnwindPlan
Definition: UnwindPlan.h:53
lldb
Definition: SBAddress.h:15
v14
@ v14
Definition: CompactUnwindInfo.cpp:1264
arm_sp
@ arm_sp
Definition: CompactUnwindInfo.cpp:1283
LLDBLog.h
rbp
@ rbp
Definition: CompactUnwindInfo.cpp:700
lldb_private::ObjectFile
Definition: ObjectFile.h:60
DataBufferHeap.h
lldb_private::UNWIND_X86_64_REG_RBP
@ UNWIND_X86_64_REG_RBP
Definition: CompactUnwindInfo.cpp:92
lldb_private::CompactUnwindInfo::GetLSDAForFunctionOffset
uint32_t GetLSDAForFunctionOffset(uint32_t lsda_offset, uint32_t lsda_count, uint32_t function_offset)
Definition: CompactUnwindInfo.cpp:383
lldb_private::UNWIND_X86_64_REG_R13
@ UNWIND_X86_64_REG_R13
Definition: CompactUnwindInfo.cpp:89
arm_r10
@ arm_r10
Definition: CompactUnwindInfo.cpp:1279
rsp
@ rsp
Definition: CompactUnwindInfo.cpp:701
r13
@ r13
Definition: CompactUnwindInfo.cpp:707
eip
@ eip
Definition: CompactUnwindInfo.cpp:982