1 //===-- DWARFCallFrameInfo.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/DWARFCallFrameInfo.h"
10 #include "lldb/Core/Module.h"
11 #include "lldb/Core/Section.h"
12 #include "lldb/Core/dwarf.h"
13 #include "lldb/Host/Host.h"
14 #include "lldb/Symbol/ObjectFile.h"
15 #include "lldb/Symbol/UnwindPlan.h"
16 #include "lldb/Target/RegisterContext.h"
17 #include "lldb/Target/Thread.h"
18 #include "lldb/Utility/ArchSpec.h"
19 #include "lldb/Utility/LLDBLog.h"
20 #include "lldb/Utility/Log.h"
21 #include "lldb/Utility/Timer.h"
22 #include <cstring>
23 #include <list>
24 
25 using namespace lldb;
26 using namespace lldb_private;
27 using namespace lldb_private::dwarf;
28 
29 // GetDwarfEHPtr
30 //
31 // Used for calls when the value type is specified by a DWARF EH Frame pointer
32 // encoding.
33 static uint64_t
34 GetGNUEHPointer(const DataExtractor &DE, offset_t *offset_ptr,
35                 uint32_t eh_ptr_enc, addr_t pc_rel_addr, addr_t text_addr,
36                 addr_t data_addr) //, BSDRelocs *data_relocs) const
37 {
38   if (eh_ptr_enc == DW_EH_PE_omit)
39     return ULLONG_MAX; // Value isn't in the buffer...
40 
41   uint64_t baseAddress = 0;
42   uint64_t addressValue = 0;
43   const uint32_t addr_size = DE.GetAddressByteSize();
44   assert(addr_size == 4 || addr_size == 8);
45 
46   bool signExtendValue = false;
47   // Decode the base part or adjust our offset
48   switch (eh_ptr_enc & 0x70) {
49   case DW_EH_PE_pcrel:
50     signExtendValue = true;
51     baseAddress = *offset_ptr;
52     if (pc_rel_addr != LLDB_INVALID_ADDRESS)
53       baseAddress += pc_rel_addr;
54     //      else
55     //          Log::GlobalWarning ("PC relative pointer encoding found with
56     //          invalid pc relative address.");
57     break;
58 
59   case DW_EH_PE_textrel:
60     signExtendValue = true;
61     if (text_addr != LLDB_INVALID_ADDRESS)
62       baseAddress = text_addr;
63     //      else
64     //          Log::GlobalWarning ("text relative pointer encoding being
65     //          decoded with invalid text section address, setting base address
66     //          to zero.");
67     break;
68 
69   case DW_EH_PE_datarel:
70     signExtendValue = true;
71     if (data_addr != LLDB_INVALID_ADDRESS)
72       baseAddress = data_addr;
73     //      else
74     //          Log::GlobalWarning ("data relative pointer encoding being
75     //          decoded with invalid data section address, setting base address
76     //          to zero.");
77     break;
78 
79   case DW_EH_PE_funcrel:
80     signExtendValue = true;
81     break;
82 
83   case DW_EH_PE_aligned: {
84     // SetPointerSize should be called prior to extracting these so the pointer
85     // size is cached
86     assert(addr_size != 0);
87     if (addr_size) {
88       // Align to a address size boundary first
89       uint32_t alignOffset = *offset_ptr % addr_size;
90       if (alignOffset)
91         offset_ptr += addr_size - alignOffset;
92     }
93   } break;
94 
95   default:
96     break;
97   }
98 
99   // Decode the value part
100   switch (eh_ptr_enc & DW_EH_PE_MASK_ENCODING) {
101   case DW_EH_PE_absptr: {
102     addressValue = DE.GetAddress(offset_ptr);
103     //          if (data_relocs)
104     //              addressValue = data_relocs->Relocate(*offset_ptr -
105     //              addr_size, *this, addressValue);
106   } break;
107   case DW_EH_PE_uleb128:
108     addressValue = DE.GetULEB128(offset_ptr);
109     break;
110   case DW_EH_PE_udata2:
111     addressValue = DE.GetU16(offset_ptr);
112     break;
113   case DW_EH_PE_udata4:
114     addressValue = DE.GetU32(offset_ptr);
115     break;
116   case DW_EH_PE_udata8:
117     addressValue = DE.GetU64(offset_ptr);
118     break;
119   case DW_EH_PE_sleb128:
120     addressValue = DE.GetSLEB128(offset_ptr);
121     break;
122   case DW_EH_PE_sdata2:
123     addressValue = (int16_t)DE.GetU16(offset_ptr);
124     break;
125   case DW_EH_PE_sdata4:
126     addressValue = (int32_t)DE.GetU32(offset_ptr);
127     break;
128   case DW_EH_PE_sdata8:
129     addressValue = (int64_t)DE.GetU64(offset_ptr);
130     break;
131   default:
132     // Unhandled encoding type
133     assert(eh_ptr_enc);
134     break;
135   }
136 
137   // Since we promote everything to 64 bit, we may need to sign extend
138   if (signExtendValue && addr_size < sizeof(baseAddress)) {
139     uint64_t sign_bit = 1ull << ((addr_size * 8ull) - 1ull);
140     if (sign_bit & addressValue) {
141       uint64_t mask = ~sign_bit + 1;
142       addressValue |= mask;
143     }
144   }
145   return baseAddress + addressValue;
146 }
147 
148 DWARFCallFrameInfo::DWARFCallFrameInfo(ObjectFile &objfile,
149                                        SectionSP &section_sp, Type type)
150     : m_objfile(objfile), m_section_sp(section_sp), m_type(type) {}
151 
152 bool DWARFCallFrameInfo::GetUnwindPlan(const Address &addr,
153                                        UnwindPlan &unwind_plan) {
154   return GetUnwindPlan(AddressRange(addr, 1), unwind_plan);
155 }
156 
157 bool DWARFCallFrameInfo::GetUnwindPlan(const AddressRange &range,
158                                        UnwindPlan &unwind_plan) {
159   FDEEntryMap::Entry fde_entry;
160   Address addr = range.GetBaseAddress();
161 
162   // Make sure that the Address we're searching for is the same object file as
163   // this DWARFCallFrameInfo, we only store File offsets in m_fde_index.
164   ModuleSP module_sp = addr.GetModule();
165   if (module_sp.get() == nullptr || module_sp->GetObjectFile() == nullptr ||
166       module_sp->GetObjectFile() != &m_objfile)
167     return false;
168 
169   if (llvm::Optional<FDEEntryMap::Entry> entry = GetFirstFDEEntryInRange(range))
170     return FDEToUnwindPlan(entry->data, addr, unwind_plan);
171   return false;
172 }
173 
174 bool DWARFCallFrameInfo::GetAddressRange(Address addr, AddressRange &range) {
175 
176   // Make sure that the Address we're searching for is the same object file as
177   // this DWARFCallFrameInfo, we only store File offsets in m_fde_index.
178   ModuleSP module_sp = addr.GetModule();
179   if (module_sp.get() == nullptr || module_sp->GetObjectFile() == nullptr ||
180       module_sp->GetObjectFile() != &m_objfile)
181     return false;
182 
183   if (m_section_sp.get() == nullptr || m_section_sp->IsEncrypted())
184     return false;
185   GetFDEIndex();
186   FDEEntryMap::Entry *fde_entry =
187       m_fde_index.FindEntryThatContains(addr.GetFileAddress());
188   if (!fde_entry)
189     return false;
190 
191   range = AddressRange(fde_entry->base, fde_entry->size,
192                        m_objfile.GetSectionList());
193   return true;
194 }
195 
196 llvm::Optional<DWARFCallFrameInfo::FDEEntryMap::Entry>
197 DWARFCallFrameInfo::GetFirstFDEEntryInRange(const AddressRange &range) {
198   if (!m_section_sp || m_section_sp->IsEncrypted())
199     return llvm::None;
200 
201   GetFDEIndex();
202 
203   addr_t start_file_addr = range.GetBaseAddress().GetFileAddress();
204   const FDEEntryMap::Entry *fde =
205       m_fde_index.FindEntryThatContainsOrFollows(start_file_addr);
206   if (fde && fde->DoesIntersect(
207                  FDEEntryMap::Range(start_file_addr, range.GetByteSize())))
208     return *fde;
209 
210   return llvm::None;
211 }
212 
213 void DWARFCallFrameInfo::GetFunctionAddressAndSizeVector(
214     FunctionAddressAndSizeVector &function_info) {
215   GetFDEIndex();
216   const size_t count = m_fde_index.GetSize();
217   function_info.Clear();
218   if (count > 0)
219     function_info.Reserve(count);
220   for (size_t i = 0; i < count; ++i) {
221     const FDEEntryMap::Entry *func_offset_data_entry =
222         m_fde_index.GetEntryAtIndex(i);
223     if (func_offset_data_entry) {
224       FunctionAddressAndSizeVector::Entry function_offset_entry(
225           func_offset_data_entry->base, func_offset_data_entry->size);
226       function_info.Append(function_offset_entry);
227     }
228   }
229 }
230 
231 const DWARFCallFrameInfo::CIE *
232 DWARFCallFrameInfo::GetCIE(dw_offset_t cie_offset) {
233   cie_map_t::iterator pos = m_cie_map.find(cie_offset);
234 
235   if (pos != m_cie_map.end()) {
236     // Parse and cache the CIE
237     if (pos->second == nullptr)
238       pos->second = ParseCIE(cie_offset);
239 
240     return pos->second.get();
241   }
242   return nullptr;
243 }
244 
245 DWARFCallFrameInfo::CIESP
246 DWARFCallFrameInfo::ParseCIE(const dw_offset_t cie_offset) {
247   CIESP cie_sp(new CIE(cie_offset));
248   lldb::offset_t offset = cie_offset;
249   if (!m_cfi_data_initialized)
250     GetCFIData();
251   uint32_t length = m_cfi_data.GetU32(&offset);
252   dw_offset_t cie_id, end_offset;
253   bool is_64bit = (length == UINT32_MAX);
254   if (is_64bit) {
255     length = m_cfi_data.GetU64(&offset);
256     cie_id = m_cfi_data.GetU64(&offset);
257     end_offset = cie_offset + length + 12;
258   } else {
259     cie_id = m_cfi_data.GetU32(&offset);
260     end_offset = cie_offset + length + 4;
261   }
262   if (length > 0 && ((m_type == DWARF && cie_id == UINT32_MAX) ||
263                      (m_type == EH && cie_id == 0ul))) {
264     size_t i;
265     //    cie.offset = cie_offset;
266     //    cie.length = length;
267     //    cie.cieID = cieID;
268     cie_sp->ptr_encoding = DW_EH_PE_absptr; // default
269     cie_sp->version = m_cfi_data.GetU8(&offset);
270     if (cie_sp->version > CFI_VERSION4) {
271       Host::SystemLog(Host::eSystemLogError,
272                       "CIE parse error: CFI version %d is not supported\n",
273                       cie_sp->version);
274       return nullptr;
275     }
276 
277     for (i = 0; i < CFI_AUG_MAX_SIZE; ++i) {
278       cie_sp->augmentation[i] = m_cfi_data.GetU8(&offset);
279       if (cie_sp->augmentation[i] == '\0') {
280         // Zero out remaining bytes in augmentation string
281         for (size_t j = i + 1; j < CFI_AUG_MAX_SIZE; ++j)
282           cie_sp->augmentation[j] = '\0';
283 
284         break;
285       }
286     }
287 
288     if (i == CFI_AUG_MAX_SIZE &&
289         cie_sp->augmentation[CFI_AUG_MAX_SIZE - 1] != '\0') {
290       Host::SystemLog(Host::eSystemLogError,
291                       "CIE parse error: CIE augmentation string was too large "
292                       "for the fixed sized buffer of %d bytes.\n",
293                       CFI_AUG_MAX_SIZE);
294       return nullptr;
295     }
296 
297     // m_cfi_data uses address size from target architecture of the process may
298     // ignore these fields?
299     if (m_type == DWARF && cie_sp->version >= CFI_VERSION4) {
300       cie_sp->address_size = m_cfi_data.GetU8(&offset);
301       cie_sp->segment_size = m_cfi_data.GetU8(&offset);
302     }
303 
304     cie_sp->code_align = (uint32_t)m_cfi_data.GetULEB128(&offset);
305     cie_sp->data_align = (int32_t)m_cfi_data.GetSLEB128(&offset);
306 
307     cie_sp->return_addr_reg_num =
308         m_type == DWARF && cie_sp->version >= CFI_VERSION3
309             ? static_cast<uint32_t>(m_cfi_data.GetULEB128(&offset))
310             : m_cfi_data.GetU8(&offset);
311 
312     if (cie_sp->augmentation[0]) {
313       // Get the length of the eh_frame augmentation data which starts with a
314       // ULEB128 length in bytes
315       const size_t aug_data_len = (size_t)m_cfi_data.GetULEB128(&offset);
316       const size_t aug_data_end = offset + aug_data_len;
317       const size_t aug_str_len = strlen(cie_sp->augmentation);
318       // A 'z' may be present as the first character of the string.
319       // If present, the Augmentation Data field shall be present. The contents
320       // of the Augmentation Data shall be interpreted according to other
321       // characters in the Augmentation String.
322       if (cie_sp->augmentation[0] == 'z') {
323         // Extract the Augmentation Data
324         size_t aug_str_idx = 0;
325         for (aug_str_idx = 1; aug_str_idx < aug_str_len; aug_str_idx++) {
326           char aug = cie_sp->augmentation[aug_str_idx];
327           switch (aug) {
328           case 'L':
329             // Indicates the presence of one argument in the Augmentation Data
330             // of the CIE, and a corresponding argument in the Augmentation
331             // Data of the FDE. The argument in the Augmentation Data of the
332             // CIE is 1-byte and represents the pointer encoding used for the
333             // argument in the Augmentation Data of the FDE, which is the
334             // address of a language-specific data area (LSDA). The size of the
335             // LSDA pointer is specified by the pointer encoding used.
336             cie_sp->lsda_addr_encoding = m_cfi_data.GetU8(&offset);
337             break;
338 
339           case 'P':
340             // Indicates the presence of two arguments in the Augmentation Data
341             // of the CIE. The first argument is 1-byte and represents the
342             // pointer encoding used for the second argument, which is the
343             // address of a personality routine handler. The size of the
344             // personality routine pointer is specified by the pointer encoding
345             // used.
346             //
347             // The address of the personality function will be stored at this
348             // location.  Pre-execution, it will be all zero's so don't read it
349             // until we're trying to do an unwind & the reloc has been
350             // resolved.
351             {
352               uint8_t arg_ptr_encoding = m_cfi_data.GetU8(&offset);
353               const lldb::addr_t pc_rel_addr = m_section_sp->GetFileAddress();
354               cie_sp->personality_loc = GetGNUEHPointer(
355                   m_cfi_data, &offset, arg_ptr_encoding, pc_rel_addr,
356                   LLDB_INVALID_ADDRESS, LLDB_INVALID_ADDRESS);
357             }
358             break;
359 
360           case 'R':
361             // A 'R' may be present at any position after the
362             // first character of the string. The Augmentation Data shall
363             // include a 1 byte argument that represents the pointer encoding
364             // for the address pointers used in the FDE. Example: 0x1B ==
365             // DW_EH_PE_pcrel | DW_EH_PE_sdata4
366             cie_sp->ptr_encoding = m_cfi_data.GetU8(&offset);
367             break;
368           }
369         }
370       } else if (strcmp(cie_sp->augmentation, "eh") == 0) {
371         // If the Augmentation string has the value "eh", then the EH Data
372         // field shall be present
373       }
374 
375       // Set the offset to be the end of the augmentation data just in case we
376       // didn't understand any of the data.
377       offset = (uint32_t)aug_data_end;
378     }
379 
380     if (end_offset > offset) {
381       cie_sp->inst_offset = offset;
382       cie_sp->inst_length = end_offset - offset;
383     }
384     while (offset < end_offset) {
385       uint8_t inst = m_cfi_data.GetU8(&offset);
386       uint8_t primary_opcode = inst & 0xC0;
387       uint8_t extended_opcode = inst & 0x3F;
388 
389       if (!HandleCommonDwarfOpcode(primary_opcode, extended_opcode,
390                                    cie_sp->data_align, offset,
391                                    cie_sp->initial_row))
392         break; // Stop if we hit an unrecognized opcode
393     }
394   }
395 
396   return cie_sp;
397 }
398 
399 void DWARFCallFrameInfo::GetCFIData() {
400   if (!m_cfi_data_initialized) {
401     Log *log = GetLog(LLDBLog::Unwind);
402     if (log)
403       m_objfile.GetModule()->LogMessage(log, "Reading EH frame info");
404     m_objfile.ReadSectionData(m_section_sp.get(), m_cfi_data);
405     m_cfi_data_initialized = true;
406   }
407 }
408 // Scan through the eh_frame or debug_frame section looking for FDEs and noting
409 // the start/end addresses of the functions and a pointer back to the
410 // function's FDE for later expansion. Internalize CIEs as we come across them.
411 
412 void DWARFCallFrameInfo::GetFDEIndex() {
413   if (m_section_sp.get() == nullptr || m_section_sp->IsEncrypted())
414     return;
415 
416   if (m_fde_index_initialized)
417     return;
418 
419   std::lock_guard<std::mutex> guard(m_fde_index_mutex);
420 
421   if (m_fde_index_initialized) // if two threads hit the locker
422     return;
423 
424   LLDB_SCOPED_TIMERF("%s - %s", LLVM_PRETTY_FUNCTION,
425                      m_objfile.GetFileSpec().GetFilename().AsCString(""));
426 
427   bool clear_address_zeroth_bit = false;
428   if (ArchSpec arch = m_objfile.GetArchitecture()) {
429     if (arch.GetTriple().getArch() == llvm::Triple::arm ||
430         arch.GetTriple().getArch() == llvm::Triple::thumb)
431       clear_address_zeroth_bit = true;
432   }
433 
434   lldb::offset_t offset = 0;
435   if (!m_cfi_data_initialized)
436     GetCFIData();
437   while (m_cfi_data.ValidOffsetForDataOfSize(offset, 8)) {
438     const dw_offset_t current_entry = offset;
439     dw_offset_t cie_id, next_entry, cie_offset;
440     uint32_t len = m_cfi_data.GetU32(&offset);
441     bool is_64bit = (len == UINT32_MAX);
442     if (is_64bit) {
443       len = m_cfi_data.GetU64(&offset);
444       cie_id = m_cfi_data.GetU64(&offset);
445       next_entry = current_entry + len + 12;
446       cie_offset = current_entry + 12 - cie_id;
447     } else {
448       cie_id = m_cfi_data.GetU32(&offset);
449       next_entry = current_entry + len + 4;
450       cie_offset = current_entry + 4 - cie_id;
451     }
452 
453     if (next_entry > m_cfi_data.GetByteSize() + 1) {
454       Host::SystemLog(Host::eSystemLogError, "error: Invalid fde/cie next "
455                                              "entry offset of 0x%x found in "
456                                              "cie/fde at 0x%x\n",
457                       next_entry, current_entry);
458       // Don't trust anything in this eh_frame section if we find blatantly
459       // invalid data.
460       m_fde_index.Clear();
461       m_fde_index_initialized = true;
462       return;
463     }
464 
465     // An FDE entry contains CIE_pointer in debug_frame in same place as cie_id
466     // in eh_frame. CIE_pointer is an offset into the .debug_frame section. So,
467     // variable cie_offset should be equal to cie_id for debug_frame.
468     // FDE entries with cie_id == 0 shouldn't be ignored for it.
469     if ((cie_id == 0 && m_type == EH) || cie_id == UINT32_MAX || len == 0) {
470       auto cie_sp = ParseCIE(current_entry);
471       if (!cie_sp) {
472         // Cannot parse, the reason is already logged
473         m_fde_index.Clear();
474         m_fde_index_initialized = true;
475         return;
476       }
477 
478       m_cie_map[current_entry] = std::move(cie_sp);
479       offset = next_entry;
480       continue;
481     }
482 
483     if (m_type == DWARF)
484       cie_offset = cie_id;
485 
486     if (cie_offset > m_cfi_data.GetByteSize()) {
487       Host::SystemLog(Host::eSystemLogError,
488                       "error: Invalid cie offset of 0x%x "
489                       "found in cie/fde at 0x%x\n",
490                       cie_offset, current_entry);
491       // Don't trust anything in this eh_frame section if we find blatantly
492       // invalid data.
493       m_fde_index.Clear();
494       m_fde_index_initialized = true;
495       return;
496     }
497 
498     const CIE *cie = GetCIE(cie_offset);
499     if (cie) {
500       const lldb::addr_t pc_rel_addr = m_section_sp->GetFileAddress();
501       const lldb::addr_t text_addr = LLDB_INVALID_ADDRESS;
502       const lldb::addr_t data_addr = LLDB_INVALID_ADDRESS;
503 
504       lldb::addr_t addr =
505           GetGNUEHPointer(m_cfi_data, &offset, cie->ptr_encoding, pc_rel_addr,
506                           text_addr, data_addr);
507       if (clear_address_zeroth_bit)
508         addr &= ~1ull;
509 
510       lldb::addr_t length = GetGNUEHPointer(
511           m_cfi_data, &offset, cie->ptr_encoding & DW_EH_PE_MASK_ENCODING,
512           pc_rel_addr, text_addr, data_addr);
513       FDEEntryMap::Entry fde(addr, length, current_entry);
514       m_fde_index.Append(fde);
515     } else {
516       Host::SystemLog(Host::eSystemLogError, "error: unable to find CIE at "
517                                              "0x%8.8x for cie_id = 0x%8.8x for "
518                                              "entry at 0x%8.8x.\n",
519                       cie_offset, cie_id, current_entry);
520     }
521     offset = next_entry;
522   }
523   m_fde_index.Sort();
524   m_fde_index_initialized = true;
525 }
526 
527 bool DWARFCallFrameInfo::FDEToUnwindPlan(dw_offset_t dwarf_offset,
528                                          Address startaddr,
529                                          UnwindPlan &unwind_plan) {
530   Log *log = GetLog(LLDBLog::Unwind);
531   lldb::offset_t offset = dwarf_offset;
532   lldb::offset_t current_entry = offset;
533 
534   if (m_section_sp.get() == nullptr || m_section_sp->IsEncrypted())
535     return false;
536 
537   if (!m_cfi_data_initialized)
538     GetCFIData();
539 
540   uint32_t length = m_cfi_data.GetU32(&offset);
541   dw_offset_t cie_offset;
542   bool is_64bit = (length == UINT32_MAX);
543   if (is_64bit) {
544     length = m_cfi_data.GetU64(&offset);
545     cie_offset = m_cfi_data.GetU64(&offset);
546   } else {
547     cie_offset = m_cfi_data.GetU32(&offset);
548   }
549 
550   // FDE entries with zeroth cie_offset may occur for debug_frame.
551   assert(!(m_type == EH && 0 == cie_offset) && cie_offset != UINT32_MAX);
552 
553   // Translate the CIE_id from the eh_frame format, which is relative to the
554   // FDE offset, into a __eh_frame section offset
555   if (m_type == EH) {
556     unwind_plan.SetSourceName("eh_frame CFI");
557     cie_offset = current_entry + (is_64bit ? 12 : 4) - cie_offset;
558     unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
559   } else {
560     unwind_plan.SetSourceName("DWARF CFI");
561     // In theory the debug_frame info should be valid at all call sites
562     // ("asynchronous unwind info" as it is sometimes called) but in practice
563     // gcc et al all emit call frame info for the prologue and call sites, but
564     // not for the epilogue or all the other locations during the function
565     // reliably.
566     unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo);
567   }
568   unwind_plan.SetSourcedFromCompiler(eLazyBoolYes);
569 
570   const CIE *cie = GetCIE(cie_offset);
571   assert(cie != nullptr);
572 
573   const dw_offset_t end_offset = current_entry + length + (is_64bit ? 12 : 4);
574 
575   const lldb::addr_t pc_rel_addr = m_section_sp->GetFileAddress();
576   const lldb::addr_t text_addr = LLDB_INVALID_ADDRESS;
577   const lldb::addr_t data_addr = LLDB_INVALID_ADDRESS;
578   lldb::addr_t range_base =
579       GetGNUEHPointer(m_cfi_data, &offset, cie->ptr_encoding, pc_rel_addr,
580                       text_addr, data_addr);
581   lldb::addr_t range_len = GetGNUEHPointer(
582       m_cfi_data, &offset, cie->ptr_encoding & DW_EH_PE_MASK_ENCODING,
583       pc_rel_addr, text_addr, data_addr);
584   AddressRange range(range_base, m_objfile.GetAddressByteSize(),
585                      m_objfile.GetSectionList());
586   range.SetByteSize(range_len);
587 
588   addr_t lsda_data_file_address = LLDB_INVALID_ADDRESS;
589 
590   if (cie->augmentation[0] == 'z') {
591     uint32_t aug_data_len = (uint32_t)m_cfi_data.GetULEB128(&offset);
592     if (aug_data_len != 0 && cie->lsda_addr_encoding != DW_EH_PE_omit) {
593       offset_t saved_offset = offset;
594       lsda_data_file_address =
595           GetGNUEHPointer(m_cfi_data, &offset, cie->lsda_addr_encoding,
596                           pc_rel_addr, text_addr, data_addr);
597       if (offset - saved_offset != aug_data_len) {
598         // There is more in the augmentation region than we know how to process;
599         // don't read anything.
600         lsda_data_file_address = LLDB_INVALID_ADDRESS;
601       }
602       offset = saved_offset;
603     }
604     offset += aug_data_len;
605   }
606   unwind_plan.SetUnwindPlanForSignalTrap(
607     strchr(cie->augmentation, 'S') ? eLazyBoolYes : eLazyBoolNo);
608 
609   Address lsda_data;
610   Address personality_function_ptr;
611 
612   if (lsda_data_file_address != LLDB_INVALID_ADDRESS &&
613       cie->personality_loc != LLDB_INVALID_ADDRESS) {
614     m_objfile.GetModule()->ResolveFileAddress(lsda_data_file_address,
615                                               lsda_data);
616     m_objfile.GetModule()->ResolveFileAddress(cie->personality_loc,
617                                               personality_function_ptr);
618   }
619 
620   if (lsda_data.IsValid() && personality_function_ptr.IsValid()) {
621     unwind_plan.SetLSDAAddress(lsda_data);
622     unwind_plan.SetPersonalityFunctionPtr(personality_function_ptr);
623   }
624 
625   uint32_t code_align = cie->code_align;
626   int32_t data_align = cie->data_align;
627 
628   unwind_plan.SetPlanValidAddressRange(range);
629   UnwindPlan::Row *cie_initial_row = new UnwindPlan::Row;
630   *cie_initial_row = cie->initial_row;
631   UnwindPlan::RowSP row(cie_initial_row);
632 
633   unwind_plan.SetRegisterKind(GetRegisterKind());
634   unwind_plan.SetReturnAddressRegister(cie->return_addr_reg_num);
635 
636   std::vector<UnwindPlan::RowSP> stack;
637 
638   UnwindPlan::Row::RegisterLocation reg_location;
639   while (m_cfi_data.ValidOffset(offset) && offset < end_offset) {
640     uint8_t inst = m_cfi_data.GetU8(&offset);
641     uint8_t primary_opcode = inst & 0xC0;
642     uint8_t extended_opcode = inst & 0x3F;
643 
644     if (!HandleCommonDwarfOpcode(primary_opcode, extended_opcode, data_align,
645                                  offset, *row)) {
646       if (primary_opcode) {
647         switch (primary_opcode) {
648         case DW_CFA_advance_loc: // (Row Creation Instruction)
649         { // 0x40 - high 2 bits are 0x1, lower 6 bits are delta
650           // takes a single argument that represents a constant delta. The
651           // required action is to create a new table row with a location value
652           // that is computed by taking the current entry's location value and
653           // adding (delta * code_align). All other values in the new row are
654           // initially identical to the current row.
655           unwind_plan.AppendRow(row);
656           UnwindPlan::Row *newrow = new UnwindPlan::Row;
657           *newrow = *row.get();
658           row.reset(newrow);
659           row->SlideOffset(extended_opcode * code_align);
660           break;
661         }
662 
663         case DW_CFA_restore: { // 0xC0 - high 2 bits are 0x3, lower 6 bits are
664                                // register
665           // takes a single argument that represents a register number. The
666           // required action is to change the rule for the indicated register
667           // to the rule assigned it by the initial_instructions in the CIE.
668           uint32_t reg_num = extended_opcode;
669           // We only keep enough register locations around to unwind what is in
670           // our thread, and these are organized by the register index in that
671           // state, so we need to convert our eh_frame register number from the
672           // EH frame info, to a register index
673 
674           if (unwind_plan.IsValidRowIndex(0) &&
675               unwind_plan.GetRowAtIndex(0)->GetRegisterInfo(reg_num,
676                                                             reg_location))
677             row->SetRegisterInfo(reg_num, reg_location);
678           break;
679         }
680         }
681       } else {
682         switch (extended_opcode) {
683         case DW_CFA_set_loc: // 0x1 (Row Creation Instruction)
684         {
685           // DW_CFA_set_loc takes a single argument that represents an address.
686           // The required action is to create a new table row using the
687           // specified address as the location. All other values in the new row
688           // are initially identical to the current row. The new location value
689           // should always be greater than the current one.
690           unwind_plan.AppendRow(row);
691           UnwindPlan::Row *newrow = new UnwindPlan::Row;
692           *newrow = *row.get();
693           row.reset(newrow);
694           row->SetOffset(m_cfi_data.GetAddress(&offset) -
695                          startaddr.GetFileAddress());
696           break;
697         }
698 
699         case DW_CFA_advance_loc1: // 0x2 (Row Creation Instruction)
700         {
701           // takes a single uword argument that represents a constant delta.
702           // This instruction is identical to DW_CFA_advance_loc except for the
703           // encoding and size of the delta argument.
704           unwind_plan.AppendRow(row);
705           UnwindPlan::Row *newrow = new UnwindPlan::Row;
706           *newrow = *row.get();
707           row.reset(newrow);
708           row->SlideOffset(m_cfi_data.GetU8(&offset) * code_align);
709           break;
710         }
711 
712         case DW_CFA_advance_loc2: // 0x3 (Row Creation Instruction)
713         {
714           // takes a single uword argument that represents a constant delta.
715           // This instruction is identical to DW_CFA_advance_loc except for the
716           // encoding and size of the delta argument.
717           unwind_plan.AppendRow(row);
718           UnwindPlan::Row *newrow = new UnwindPlan::Row;
719           *newrow = *row.get();
720           row.reset(newrow);
721           row->SlideOffset(m_cfi_data.GetU16(&offset) * code_align);
722           break;
723         }
724 
725         case DW_CFA_advance_loc4: // 0x4 (Row Creation Instruction)
726         {
727           // takes a single uword argument that represents a constant delta.
728           // This instruction is identical to DW_CFA_advance_loc except for the
729           // encoding and size of the delta argument.
730           unwind_plan.AppendRow(row);
731           UnwindPlan::Row *newrow = new UnwindPlan::Row;
732           *newrow = *row.get();
733           row.reset(newrow);
734           row->SlideOffset(m_cfi_data.GetU32(&offset) * code_align);
735           break;
736         }
737 
738         case DW_CFA_restore_extended: // 0x6
739         {
740           // takes a single unsigned LEB128 argument that represents a register
741           // number. This instruction is identical to DW_CFA_restore except for
742           // the encoding and size of the register argument.
743           uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
744           if (unwind_plan.IsValidRowIndex(0) &&
745               unwind_plan.GetRowAtIndex(0)->GetRegisterInfo(reg_num,
746                                                             reg_location))
747             row->SetRegisterInfo(reg_num, reg_location);
748           break;
749         }
750 
751         case DW_CFA_remember_state: // 0xA
752         {
753           // These instructions define a stack of information. Encountering the
754           // DW_CFA_remember_state instruction means to save the rules for
755           // every register on the current row on the stack. Encountering the
756           // DW_CFA_restore_state instruction means to pop the set of rules off
757           // the stack and place them in the current row. (This operation is
758           // useful for compilers that move epilogue code into the body of a
759           // function.)
760           stack.push_back(row);
761           UnwindPlan::Row *newrow = new UnwindPlan::Row;
762           *newrow = *row.get();
763           row.reset(newrow);
764           break;
765         }
766 
767         case DW_CFA_restore_state: // 0xB
768         {
769           // These instructions define a stack of information. Encountering the
770           // DW_CFA_remember_state instruction means to save the rules for
771           // every register on the current row on the stack. Encountering the
772           // DW_CFA_restore_state instruction means to pop the set of rules off
773           // the stack and place them in the current row. (This operation is
774           // useful for compilers that move epilogue code into the body of a
775           // function.)
776           if (stack.empty()) {
777             LLDB_LOGF(log,
778                       "DWARFCallFrameInfo::%s(dwarf_offset: %" PRIx32
779                       ", startaddr: %" PRIx64
780                       " encountered DW_CFA_restore_state but state stack "
781                       "is empty. Corrupt unwind info?",
782                       __FUNCTION__, dwarf_offset, startaddr.GetFileAddress());
783             break;
784           }
785           lldb::addr_t offset = row->GetOffset();
786           row = stack.back();
787           stack.pop_back();
788           row->SetOffset(offset);
789           break;
790         }
791 
792         case DW_CFA_GNU_args_size: // 0x2e
793         {
794           // The DW_CFA_GNU_args_size instruction takes an unsigned LEB128
795           // operand representing an argument size. This instruction specifies
796           // the total of the size of the arguments which have been pushed onto
797           // the stack.
798 
799           // TODO: Figure out how we should handle this.
800           m_cfi_data.GetULEB128(&offset);
801           break;
802         }
803 
804         case DW_CFA_val_offset:    // 0x14
805         case DW_CFA_val_offset_sf: // 0x15
806         default:
807           break;
808         }
809       }
810     }
811   }
812   unwind_plan.AppendRow(row);
813 
814   return true;
815 }
816 
817 bool DWARFCallFrameInfo::HandleCommonDwarfOpcode(uint8_t primary_opcode,
818                                                  uint8_t extended_opcode,
819                                                  int32_t data_align,
820                                                  lldb::offset_t &offset,
821                                                  UnwindPlan::Row &row) {
822   UnwindPlan::Row::RegisterLocation reg_location;
823 
824   if (primary_opcode) {
825     switch (primary_opcode) {
826     case DW_CFA_offset: { // 0x80 - high 2 bits are 0x2, lower 6 bits are
827                           // register
828       // takes two arguments: an unsigned LEB128 constant representing a
829       // factored offset and a register number. The required action is to
830       // change the rule for the register indicated by the register number to
831       // be an offset(N) rule with a value of (N = factored offset *
832       // data_align).
833       uint8_t reg_num = extended_opcode;
834       int32_t op_offset = (int32_t)m_cfi_data.GetULEB128(&offset) * data_align;
835       reg_location.SetAtCFAPlusOffset(op_offset);
836       row.SetRegisterInfo(reg_num, reg_location);
837       return true;
838     }
839     }
840   } else {
841     switch (extended_opcode) {
842     case DW_CFA_nop: // 0x0
843       return true;
844 
845     case DW_CFA_offset_extended: // 0x5
846     {
847       // takes two unsigned LEB128 arguments representing a register number and
848       // a factored offset. This instruction is identical to DW_CFA_offset
849       // except for the encoding and size of the register argument.
850       uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
851       int32_t op_offset = (int32_t)m_cfi_data.GetULEB128(&offset) * data_align;
852       UnwindPlan::Row::RegisterLocation reg_location;
853       reg_location.SetAtCFAPlusOffset(op_offset);
854       row.SetRegisterInfo(reg_num, reg_location);
855       return true;
856     }
857 
858     case DW_CFA_undefined: // 0x7
859     {
860       // takes a single unsigned LEB128 argument that represents a register
861       // number. The required action is to set the rule for the specified
862       // register to undefined.
863       uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
864       UnwindPlan::Row::RegisterLocation reg_location;
865       reg_location.SetUndefined();
866       row.SetRegisterInfo(reg_num, reg_location);
867       return true;
868     }
869 
870     case DW_CFA_same_value: // 0x8
871     {
872       // takes a single unsigned LEB128 argument that represents a register
873       // number. The required action is to set the rule for the specified
874       // register to same value.
875       uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
876       UnwindPlan::Row::RegisterLocation reg_location;
877       reg_location.SetSame();
878       row.SetRegisterInfo(reg_num, reg_location);
879       return true;
880     }
881 
882     case DW_CFA_register: // 0x9
883     {
884       // takes two unsigned LEB128 arguments representing register numbers. The
885       // required action is to set the rule for the first register to be the
886       // second register.
887       uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
888       uint32_t other_reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
889       UnwindPlan::Row::RegisterLocation reg_location;
890       reg_location.SetInRegister(other_reg_num);
891       row.SetRegisterInfo(reg_num, reg_location);
892       return true;
893     }
894 
895     case DW_CFA_def_cfa: // 0xC    (CFA Definition Instruction)
896     {
897       // Takes two unsigned LEB128 operands representing a register number and
898       // a (non-factored) offset. The required action is to define the current
899       // CFA rule to use the provided register and offset.
900       uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
901       int32_t op_offset = (int32_t)m_cfi_data.GetULEB128(&offset);
902       row.GetCFAValue().SetIsRegisterPlusOffset(reg_num, op_offset);
903       return true;
904     }
905 
906     case DW_CFA_def_cfa_register: // 0xD    (CFA Definition Instruction)
907     {
908       // takes a single unsigned LEB128 argument representing a register
909       // number. The required action is to define the current CFA rule to use
910       // the provided register (but to keep the old offset).
911       uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
912       row.GetCFAValue().SetIsRegisterPlusOffset(reg_num,
913                                                 row.GetCFAValue().GetOffset());
914       return true;
915     }
916 
917     case DW_CFA_def_cfa_offset: // 0xE    (CFA Definition Instruction)
918     {
919       // Takes a single unsigned LEB128 operand representing a (non-factored)
920       // offset. The required action is to define the current CFA rule to use
921       // the provided offset (but to keep the old register).
922       int32_t op_offset = (int32_t)m_cfi_data.GetULEB128(&offset);
923       row.GetCFAValue().SetIsRegisterPlusOffset(
924           row.GetCFAValue().GetRegisterNumber(), op_offset);
925       return true;
926     }
927 
928     case DW_CFA_def_cfa_expression: // 0xF    (CFA Definition Instruction)
929     {
930       size_t block_len = (size_t)m_cfi_data.GetULEB128(&offset);
931       const uint8_t *block_data =
932           static_cast<const uint8_t *>(m_cfi_data.GetData(&offset, block_len));
933       row.GetCFAValue().SetIsDWARFExpression(block_data, block_len);
934       return true;
935     }
936 
937     case DW_CFA_expression: // 0x10
938     {
939       // Takes two operands: an unsigned LEB128 value representing a register
940       // number, and a DW_FORM_block value representing a DWARF expression. The
941       // required action is to change the rule for the register indicated by
942       // the register number to be an expression(E) rule where E is the DWARF
943       // expression. That is, the DWARF expression computes the address. The
944       // value of the CFA is pushed on the DWARF evaluation stack prior to
945       // execution of the DWARF expression.
946       uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
947       uint32_t block_len = (uint32_t)m_cfi_data.GetULEB128(&offset);
948       const uint8_t *block_data =
949           static_cast<const uint8_t *>(m_cfi_data.GetData(&offset, block_len));
950       UnwindPlan::Row::RegisterLocation reg_location;
951       reg_location.SetAtDWARFExpression(block_data, block_len);
952       row.SetRegisterInfo(reg_num, reg_location);
953       return true;
954     }
955 
956     case DW_CFA_offset_extended_sf: // 0x11
957     {
958       // takes two operands: an unsigned LEB128 value representing a register
959       // number and a signed LEB128 factored offset. This instruction is
960       // identical to DW_CFA_offset_extended except that the second operand is
961       // signed and factored.
962       uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
963       int32_t op_offset = (int32_t)m_cfi_data.GetSLEB128(&offset) * data_align;
964       UnwindPlan::Row::RegisterLocation reg_location;
965       reg_location.SetAtCFAPlusOffset(op_offset);
966       row.SetRegisterInfo(reg_num, reg_location);
967       return true;
968     }
969 
970     case DW_CFA_def_cfa_sf: // 0x12   (CFA Definition Instruction)
971     {
972       // Takes two operands: an unsigned LEB128 value representing a register
973       // number and a signed LEB128 factored offset. This instruction is
974       // identical to DW_CFA_def_cfa except that the second operand is signed
975       // and factored.
976       uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
977       int32_t op_offset = (int32_t)m_cfi_data.GetSLEB128(&offset) * data_align;
978       row.GetCFAValue().SetIsRegisterPlusOffset(reg_num, op_offset);
979       return true;
980     }
981 
982     case DW_CFA_def_cfa_offset_sf: // 0x13   (CFA Definition Instruction)
983     {
984       // takes a signed LEB128 operand representing a factored offset. This
985       // instruction is identical to  DW_CFA_def_cfa_offset except that the
986       // operand is signed and factored.
987       int32_t op_offset = (int32_t)m_cfi_data.GetSLEB128(&offset) * data_align;
988       uint32_t cfa_regnum = row.GetCFAValue().GetRegisterNumber();
989       row.GetCFAValue().SetIsRegisterPlusOffset(cfa_regnum, op_offset);
990       return true;
991     }
992 
993     case DW_CFA_val_expression: // 0x16
994     {
995       // takes two operands: an unsigned LEB128 value representing a register
996       // number, and a DW_FORM_block value representing a DWARF expression. The
997       // required action is to change the rule for the register indicated by
998       // the register number to be a val_expression(E) rule where E is the
999       // DWARF expression. That is, the DWARF expression computes the value of
1000       // the given register. The value of the CFA is pushed on the DWARF
1001       // evaluation stack prior to execution of the DWARF expression.
1002       uint32_t reg_num = (uint32_t)m_cfi_data.GetULEB128(&offset);
1003       uint32_t block_len = (uint32_t)m_cfi_data.GetULEB128(&offset);
1004       const uint8_t *block_data =
1005           (const uint8_t *)m_cfi_data.GetData(&offset, block_len);
1006       reg_location.SetIsDWARFExpression(block_data, block_len);
1007       row.SetRegisterInfo(reg_num, reg_location);
1008       return true;
1009     }
1010     }
1011   }
1012   return false;
1013 }
1014 
1015 void DWARFCallFrameInfo::ForEachFDEEntries(
1016     const std::function<bool(lldb::addr_t, uint32_t, dw_offset_t)> &callback) {
1017   GetFDEIndex();
1018 
1019   for (size_t i = 0, c = m_fde_index.GetSize(); i < c; ++i) {
1020     const FDEEntryMap::Entry &entry = m_fde_index.GetEntryRef(i);
1021     if (!callback(entry.base, entry.size, entry.data))
1022       break;
1023   }
1024 }
1025