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