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 
9 #include "lldb/Symbol/CompactUnwindInfo.h"
10 #include "lldb/Core/Debugger.h"
11 #include "lldb/Core/Module.h"
12 #include "lldb/Core/Section.h"
13 #include "lldb/Symbol/ObjectFile.h"
14 #include "lldb/Symbol/UnwindPlan.h"
15 #include "lldb/Target/Process.h"
16 #include "lldb/Target/Target.h"
17 #include "lldb/Utility/ArchSpec.h"
18 #include "lldb/Utility/DataBufferHeap.h"
19 #include "lldb/Utility/LLDBLog.h"
20 #include "lldb/Utility/Log.h"
21 #include "lldb/Utility/StreamString.h"
22 
23 #include "llvm/Support/MathExtras.h"
24 
25 #include <algorithm>
26 #include <memory>
27 
28 using namespace lldb;
29 using namespace lldb_private;
30 
31 namespace lldb_private {
32 
33 // Constants from <mach-o/compact_unwind_encoding.h>
34 
35 FLAGS_ANONYMOUS_ENUM(){
36     UNWIND_IS_NOT_FUNCTION_START = 0x80000000, UNWIND_HAS_LSDA = 0x40000000,
37     UNWIND_PERSONALITY_MASK = 0x30000000,
38 };
39 
40 FLAGS_ANONYMOUS_ENUM(){
41     UNWIND_X86_MODE_MASK = 0x0F000000,
42     UNWIND_X86_MODE_EBP_FRAME = 0x01000000,
43     UNWIND_X86_MODE_STACK_IMMD = 0x02000000,
44     UNWIND_X86_MODE_STACK_IND = 0x03000000,
45     UNWIND_X86_MODE_DWARF = 0x04000000,
46 
47     UNWIND_X86_EBP_FRAME_REGISTERS = 0x00007FFF,
48     UNWIND_X86_EBP_FRAME_OFFSET = 0x00FF0000,
49 
50     UNWIND_X86_FRAMELESS_STACK_SIZE = 0x00FF0000,
51     UNWIND_X86_FRAMELESS_STACK_ADJUST = 0x0000E000,
52     UNWIND_X86_FRAMELESS_STACK_REG_COUNT = 0x00001C00,
53     UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF,
54 
55     UNWIND_X86_DWARF_SECTION_OFFSET = 0x00FFFFFF,
56 };
57 
58 enum {
59   UNWIND_X86_REG_NONE = 0,
60   UNWIND_X86_REG_EBX = 1,
61   UNWIND_X86_REG_ECX = 2,
62   UNWIND_X86_REG_EDX = 3,
63   UNWIND_X86_REG_EDI = 4,
64   UNWIND_X86_REG_ESI = 5,
65   UNWIND_X86_REG_EBP = 6,
66 };
67 
68 FLAGS_ANONYMOUS_ENUM(){
69     UNWIND_X86_64_MODE_MASK = 0x0F000000,
70     UNWIND_X86_64_MODE_RBP_FRAME = 0x01000000,
71     UNWIND_X86_64_MODE_STACK_IMMD = 0x02000000,
72     UNWIND_X86_64_MODE_STACK_IND = 0x03000000,
73     UNWIND_X86_64_MODE_DWARF = 0x04000000,
74 
75     UNWIND_X86_64_RBP_FRAME_REGISTERS = 0x00007FFF,
76     UNWIND_X86_64_RBP_FRAME_OFFSET = 0x00FF0000,
77 
78     UNWIND_X86_64_FRAMELESS_STACK_SIZE = 0x00FF0000,
79     UNWIND_X86_64_FRAMELESS_STACK_ADJUST = 0x0000E000,
80     UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT = 0x00001C00,
81     UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF,
82 
83     UNWIND_X86_64_DWARF_SECTION_OFFSET = 0x00FFFFFF,
84 };
85 
86 enum {
87   UNWIND_X86_64_REG_NONE = 0,
88   UNWIND_X86_64_REG_RBX = 1,
89   UNWIND_X86_64_REG_R12 = 2,
90   UNWIND_X86_64_REG_R13 = 3,
91   UNWIND_X86_64_REG_R14 = 4,
92   UNWIND_X86_64_REG_R15 = 5,
93   UNWIND_X86_64_REG_RBP = 6,
94 };
95 
96 FLAGS_ANONYMOUS_ENUM(){
97     UNWIND_ARM64_MODE_MASK = 0x0F000000,
98     UNWIND_ARM64_MODE_FRAMELESS = 0x02000000,
99     UNWIND_ARM64_MODE_DWARF = 0x03000000,
100     UNWIND_ARM64_MODE_FRAME = 0x04000000,
101 
102     UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001,
103     UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002,
104     UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004,
105     UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008,
106     UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010,
107     UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100,
108     UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200,
109     UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400,
110     UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800,
111 
112     UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK = 0x00FFF000,
113     UNWIND_ARM64_DWARF_SECTION_OFFSET = 0x00FFFFFF,
114 };
115 
116 FLAGS_ANONYMOUS_ENUM(){
117     UNWIND_ARM_MODE_MASK = 0x0F000000,
118     UNWIND_ARM_MODE_FRAME = 0x01000000,
119     UNWIND_ARM_MODE_FRAME_D = 0x02000000,
120     UNWIND_ARM_MODE_DWARF = 0x04000000,
121 
122     UNWIND_ARM_FRAME_STACK_ADJUST_MASK = 0x00C00000,
123 
124     UNWIND_ARM_FRAME_FIRST_PUSH_R4 = 0x00000001,
125     UNWIND_ARM_FRAME_FIRST_PUSH_R5 = 0x00000002,
126     UNWIND_ARM_FRAME_FIRST_PUSH_R6 = 0x00000004,
127 
128     UNWIND_ARM_FRAME_SECOND_PUSH_R8 = 0x00000008,
129     UNWIND_ARM_FRAME_SECOND_PUSH_R9 = 0x00000010,
130     UNWIND_ARM_FRAME_SECOND_PUSH_R10 = 0x00000020,
131     UNWIND_ARM_FRAME_SECOND_PUSH_R11 = 0x00000040,
132     UNWIND_ARM_FRAME_SECOND_PUSH_R12 = 0x00000080,
133 
134     UNWIND_ARM_FRAME_D_REG_COUNT_MASK = 0x00000700,
135 
136     UNWIND_ARM_DWARF_SECTION_OFFSET = 0x00FFFFFF,
137 };
138 }
139 
140 #ifndef UNWIND_SECOND_LEVEL_REGULAR
141 #define UNWIND_SECOND_LEVEL_REGULAR 2
142 #endif
143 
144 #ifndef UNWIND_SECOND_LEVEL_COMPRESSED
145 #define UNWIND_SECOND_LEVEL_COMPRESSED 3
146 #endif
147 
148 #ifndef UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET
149 #define UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(entry) (entry & 0x00FFFFFF)
150 #endif
151 
152 #ifndef UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX
153 #define UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX(entry)                     \
154   ((entry >> 24) & 0xFF)
155 #endif
156 
157 #define EXTRACT_BITS(value, mask)                                              \
158   ((value >>                                                                   \
159     llvm::countTrailingZeros(static_cast<uint32_t>(mask), llvm::ZB_Width)) &   \
160    (((1 << llvm::countPopulation(static_cast<uint32_t>(mask)))) - 1))
161 
162 // constructor
163 
164 CompactUnwindInfo::CompactUnwindInfo(ObjectFile &objfile, SectionSP &section_sp)
165     : m_objfile(objfile), m_section_sp(section_sp),
166       m_section_contents_if_encrypted(), m_mutex(), m_indexes(),
167       m_indexes_computed(eLazyBoolCalculate), m_unwindinfo_data(),
168       m_unwindinfo_data_computed(false), m_unwind_header() {}
169 
170 // destructor
171 
172 CompactUnwindInfo::~CompactUnwindInfo() = default;
173 
174 bool CompactUnwindInfo::GetUnwindPlan(Target &target, Address addr,
175                                       UnwindPlan &unwind_plan) {
176   if (!IsValid(target.GetProcessSP())) {
177     return false;
178   }
179   FunctionInfo function_info;
180   if (GetCompactUnwindInfoForFunction(target, addr, function_info)) {
181     // shortcut return for functions that have no compact unwind
182     if (function_info.encoding == 0)
183       return false;
184 
185     if (ArchSpec arch = m_objfile.GetArchitecture()) {
186 
187       Log *log = GetLog(LLDBLog::Unwind);
188       if (log && log->GetVerbose()) {
189         StreamString strm;
190         addr.Dump(
191             &strm, nullptr,
192             Address::DumpStyle::DumpStyleResolvedDescriptionNoFunctionArguments,
193             Address::DumpStyle::DumpStyleFileAddress,
194             arch.GetAddressByteSize());
195         LLDB_LOGF(log, "Got compact unwind encoding 0x%x for function %s",
196                   function_info.encoding, strm.GetData());
197       }
198 
199       if (function_info.valid_range_offset_start != 0 &&
200           function_info.valid_range_offset_end != 0) {
201         SectionList *sl = m_objfile.GetSectionList();
202         if (sl) {
203           addr_t func_range_start_file_addr =
204               function_info.valid_range_offset_start +
205               m_objfile.GetBaseAddress().GetFileAddress();
206           AddressRange func_range(func_range_start_file_addr,
207                                   function_info.valid_range_offset_end -
208                                       function_info.valid_range_offset_start,
209                                   sl);
210           unwind_plan.SetPlanValidAddressRange(func_range);
211         }
212       }
213 
214       if (arch.GetTriple().getArch() == llvm::Triple::x86_64) {
215         return CreateUnwindPlan_x86_64(target, function_info, unwind_plan,
216                                        addr);
217       }
218       if (arch.GetTriple().getArch() == llvm::Triple::aarch64 ||
219           arch.GetTriple().getArch() == llvm::Triple::aarch64_32) {
220         return CreateUnwindPlan_arm64(target, function_info, unwind_plan, addr);
221       }
222       if (arch.GetTriple().getArch() == llvm::Triple::x86) {
223         return CreateUnwindPlan_i386(target, function_info, unwind_plan, addr);
224       }
225       if (arch.GetTriple().getArch() == llvm::Triple::arm ||
226           arch.GetTriple().getArch() == llvm::Triple::thumb) {
227         return CreateUnwindPlan_armv7(target, function_info, unwind_plan, addr);
228       }
229     }
230   }
231   return false;
232 }
233 
234 bool CompactUnwindInfo::IsValid(const ProcessSP &process_sp) {
235   if (m_section_sp.get() == nullptr)
236     return false;
237 
238   if (m_indexes_computed == eLazyBoolYes && m_unwindinfo_data_computed)
239     return true;
240 
241   ScanIndex(process_sp);
242 
243   return m_indexes_computed == eLazyBoolYes && m_unwindinfo_data_computed;
244 }
245 
246 void CompactUnwindInfo::ScanIndex(const ProcessSP &process_sp) {
247   std::lock_guard<std::mutex> guard(m_mutex);
248   if (m_indexes_computed == eLazyBoolYes && m_unwindinfo_data_computed)
249     return;
250 
251   // We can't read the index for some reason.
252   if (m_indexes_computed == eLazyBoolNo) {
253     return;
254   }
255 
256   Log *log = GetLog(LLDBLog::Unwind);
257   if (log)
258     m_objfile.GetModule()->LogMessage(
259         log, "Reading compact unwind first-level indexes");
260 
261   if (!m_unwindinfo_data_computed) {
262     if (m_section_sp->IsEncrypted()) {
263       // Can't get section contents of a protected/encrypted section until we
264       // have a live process and can read them out of memory.
265       if (process_sp.get() == nullptr)
266         return;
267       m_section_contents_if_encrypted =
268           std::make_shared<DataBufferHeap>(m_section_sp->GetByteSize(), 0);
269       Status error;
270       if (process_sp->ReadMemory(
271               m_section_sp->GetLoadBaseAddress(&process_sp->GetTarget()),
272               m_section_contents_if_encrypted->GetBytes(),
273               m_section_sp->GetByteSize(),
274               error) == m_section_sp->GetByteSize() &&
275           error.Success()) {
276         m_unwindinfo_data.SetAddressByteSize(
277             process_sp->GetTarget().GetArchitecture().GetAddressByteSize());
278         m_unwindinfo_data.SetByteOrder(
279             process_sp->GetTarget().GetArchitecture().GetByteOrder());
280         m_unwindinfo_data.SetData(m_section_contents_if_encrypted, 0);
281       }
282     } else {
283       m_objfile.ReadSectionData(m_section_sp.get(), m_unwindinfo_data);
284     }
285     if (m_unwindinfo_data.GetByteSize() != m_section_sp->GetByteSize())
286       return;
287     m_unwindinfo_data_computed = true;
288   }
289 
290   if (m_unwindinfo_data.GetByteSize() > 0) {
291     offset_t offset = 0;
292 
293     // struct unwind_info_section_header
294     // {
295     // uint32_t    version;            // UNWIND_SECTION_VERSION
296     // uint32_t    commonEncodingsArraySectionOffset;
297     // uint32_t    commonEncodingsArrayCount;
298     // uint32_t    personalityArraySectionOffset;
299     // uint32_t    personalityArrayCount;
300     // uint32_t    indexSectionOffset;
301     // uint32_t    indexCount;
302 
303     m_unwind_header.version = m_unwindinfo_data.GetU32(&offset);
304     m_unwind_header.common_encodings_array_offset =
305         m_unwindinfo_data.GetU32(&offset);
306     m_unwind_header.common_encodings_array_count =
307         m_unwindinfo_data.GetU32(&offset);
308     m_unwind_header.personality_array_offset =
309         m_unwindinfo_data.GetU32(&offset);
310     m_unwind_header.personality_array_count = m_unwindinfo_data.GetU32(&offset);
311     uint32_t indexSectionOffset = m_unwindinfo_data.GetU32(&offset);
312 
313     uint32_t indexCount = m_unwindinfo_data.GetU32(&offset);
314 
315     if (m_unwind_header.common_encodings_array_offset >
316             m_unwindinfo_data.GetByteSize() ||
317         m_unwind_header.personality_array_offset >
318             m_unwindinfo_data.GetByteSize() ||
319         indexSectionOffset > m_unwindinfo_data.GetByteSize() ||
320         offset > m_unwindinfo_data.GetByteSize()) {
321       Debugger::ReportError(
322           "Invalid offset encountered in compact unwind info, skipping");
323       // don't trust anything from this compact_unwind section if it looks
324       // blatantly invalid data in the header.
325       m_indexes_computed = eLazyBoolNo;
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()) {
356         m_indexes_computed = eLazyBoolNo;
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     }
377     m_indexes_computed = eLazyBoolYes;
378   } else {
379     m_indexes_computed = eLazyBoolNo;
380   }
381 }
382 
383 uint32_t CompactUnwindInfo::GetLSDAForFunctionOffset(uint32_t lsda_offset,
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 
412 lldb::offset_t CompactUnwindInfo::BinarySearchRegularSecondPage(
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 
452 uint32_t CompactUnwindInfo::BinarySearchCompressedSecondPage(
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;
480         return UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX(entry);
481       } else {
482         low = mid + 1;
483       }
484     } else {
485       high = mid;
486     }
487   }
488 
489   return UINT32_MAX;
490 }
491 
492 bool CompactUnwindInfo::GetCompactUnwindInfoForFunction(
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;
502   SectionList *sl = m_objfile.GetSectionList();
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 =
513       address.GetFileAddress() - m_objfile.GetBaseAddress().GetFileAddress();
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;
546   uint32_t kind = m_unwindinfo_data.GetU32(
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 
564     offset_t entry_offset = BinarySearchRegularSecondPage(
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) {
574       SectionList *sl = m_objfile.GetSectionList();
575       if (sl) {
576         uint32_t lsda_offset = GetLSDAForFunctionOffset(
577             lsda_array_start, lsda_array_count, function_offset);
578         addr_t objfile_base_address =
579             m_objfile.GetBaseAddress().GetFileAddress();
580         unwind_info.lsda_address.ResolveAddressUsingFileSections(
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) {
591           offset_t offset = m_unwind_header.personality_array_offset;
592           offset += 4 * personality_index;
593           SectionList *sl = m_objfile.GetSectionList();
594           if (sl) {
595             uint32_t personality_offset = m_unwindinfo_data.GetU32(&offset);
596             addr_t objfile_base_address =
597                 m_objfile.GetBaseAddress().GetFileAddress();
598             unwind_info.personality_ptr_address.ResolveAddressUsingFileSections(
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 
630     uint32_t encoding_index = BinarySearchCompressedSecondPage(
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) {
641       offset = m_unwind_header.common_encodings_array_offset +
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 =
647           encoding_index - m_unwind_header.common_encodings_array_count;
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) {
658       SectionList *sl = m_objfile.GetSectionList();
659       if (sl) {
660         uint32_t lsda_offset = GetLSDAForFunctionOffset(
661             lsda_array_start, lsda_array_count, function_offset);
662         addr_t objfile_base_address =
663             m_objfile.GetBaseAddress().GetFileAddress();
664         unwind_info.lsda_address.ResolveAddressUsingFileSections(
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) {
675           offset_t offset = m_unwind_header.personality_array_offset;
676           offset += 4 * personality_index;
677           SectionList *sl = m_objfile.GetSectionList();
678           if (sl) {
679             uint32_t personality_offset = m_unwindinfo_data.GetU32(&offset);
680             addr_t objfile_base_address =
681                 m_objfile.GetBaseAddress().GetFileAddress();
682             unwind_info.personality_ptr_address.ResolveAddressUsingFileSections(
683                 objfile_base_address + personality_offset, sl);
684           }
685         }
686       }
687     }
688     return true;
689   }
690   return false;
691 }
692 
693 enum x86_64_eh_regnum {
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.
716 uint32_t translate_to_eh_frame_regnum_x86_64(uint32_t unwind_regno) {
717   switch (unwind_regno) {
718   case UNWIND_X86_64_REG_RBX:
719     return x86_64_eh_regnum::rbx;
720   case UNWIND_X86_64_REG_R12:
721     return x86_64_eh_regnum::r12;
722   case UNWIND_X86_64_REG_R13:
723     return x86_64_eh_regnum::r13;
724   case UNWIND_X86_64_REG_R14:
725     return x86_64_eh_regnum::r14;
726   case UNWIND_X86_64_REG_R15:
727     return x86_64_eh_regnum::r15;
728   case UNWIND_X86_64_REG_RBP:
729     return x86_64_eh_regnum::rbp;
730   default:
731     return LLDB_INVALID_REGNUM;
732   }
733 }
734 
735 bool CompactUnwindInfo::CreateUnwindPlan_x86_64(Target &target,
736                                                 FunctionInfo &function_info,
737                                                 UnwindPlan &unwind_plan,
738                                                 Address pc_or_function_start) {
739   unwind_plan.SetSourceName("compact unwind info");
740   unwind_plan.SetSourcedFromCompiler(eLazyBoolYes);
741   unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
742   unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
743   unwind_plan.SetRegisterKind(eRegisterKindEHFrame);
744 
745   unwind_plan.SetLSDAAddress(function_info.lsda_address);
746   unwind_plan.SetPersonalityFunctionPtr(function_info.personality_ptr_address);
747 
748   UnwindPlan::RowSP row(new UnwindPlan::Row);
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(
755         translate_to_eh_frame_regnum_x86_64(UNWIND_X86_64_REG_RBP),
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) {
775       case UNWIND_X86_64_REG_NONE:
776         break;
777       case UNWIND_X86_64_REG_RBX:
778       case UNWIND_X86_64_REG_R12:
779       case UNWIND_X86_64_REG_R13:
780       case UNWIND_X86_64_REG_R14:
781       case UNWIND_X86_64_REG_R15:
782         row->SetRegisterLocationToAtCFAPlusOffset(
783             translate_to_eh_frame_regnum_x86_64(regnum),
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 
819       SectionList *sl = m_objfile.GetSectionList();
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,
920                           UNWIND_X86_64_REG_NONE, UNWIND_X86_64_REG_NONE,
921                           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]) {
942         case UNWIND_X86_64_REG_NONE:
943           break;
944         case UNWIND_X86_64_REG_RBX:
945         case UNWIND_X86_64_REG_R12:
946         case UNWIND_X86_64_REG_R13:
947         case UNWIND_X86_64_REG_R14:
948         case UNWIND_X86_64_REG_R15:
949         case UNWIND_X86_64_REG_RBP:
950           row->SetRegisterLocationToAtCFAPlusOffset(
951               translate_to_eh_frame_regnum_x86_64(registers[i]),
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 
973 enum i386_eh_regnum {
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.
988 uint32_t translate_to_eh_frame_regnum_i386(uint32_t unwind_regno) {
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 
1007 bool CompactUnwindInfo::CreateUnwindPlan_i386(Target &target,
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);
1013   unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1014   unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
1015   unwind_plan.SetRegisterKind(eRegisterKindEHFrame);
1016 
1017   unwind_plan.SetLSDAAddress(function_info.lsda_address);
1018   unwind_plan.SetPersonalityFunctionPtr(function_info.personality_ptr_address);
1019 
1020   UnwindPlan::RowSP row(new UnwindPlan::Row);
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(
1027         translate_to_eh_frame_regnum_i386(UNWIND_X86_REG_EBP), 2 * wordsize);
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(
1054             translate_to_eh_frame_regnum_i386(regnum),
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 
1084       SectionList *sl = m_objfile.GetSectionList();
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,
1183                           UNWIND_X86_REG_NONE, UNWIND_X86_REG_NONE,
1184                           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 
1236 enum arm64_eh_regnum {
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 
1268 enum arm_eh_regnum {
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 
1304 bool CompactUnwindInfo::CreateUnwindPlan_arm64(Target &target,
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);
1310   unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1311   unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
1312   unwind_plan.SetRegisterKind(eRegisterKindEHFrame);
1313 
1314   unwind_plan.SetLSDAAddress(function_info.lsda_address);
1315   unwind_plan.SetPersonalityFunctionPtr(function_info.personality_ptr_address);
1316 
1317   UnwindPlan::RowSP row(new UnwindPlan::Row);
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 
1438 bool CompactUnwindInfo::CreateUnwindPlan_armv7(Target &target,
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);
1444   unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
1445   unwind_plan.SetUnwindPlanForSignalTrap(eLazyBoolNo);
1446   unwind_plan.SetRegisterKind(eRegisterKindEHFrame);
1447 
1448   unwind_plan.SetLSDAAddress(function_info.lsda_address);
1449   unwind_plan.SetPersonalityFunctionPtr(function_info.personality_ptr_address);
1450 
1451   UnwindPlan::RowSP row(new UnwindPlan::Row);
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 }
1613