1 //===-- Address.cpp ---------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/Core/Address.h"
11 
12 #include "lldb/Core/ArchSpec.h" // for ArchSpec
13 #include "lldb/Core/DumpDataExtractor.h"
14 #include "lldb/Core/Module.h"
15 #include "lldb/Core/ModuleList.h" // for ModuleList
16 #include "lldb/Core/Section.h"
17 #include "lldb/Symbol/Block.h"
18 #include "lldb/Symbol/Declaration.h" // for Declaration
19 #include "lldb/Symbol/LineEntry.h"   // for LineEntry
20 #include "lldb/Symbol/ObjectFile.h"
21 #include "lldb/Symbol/Symbol.h"        // for Symbol
22 #include "lldb/Symbol/SymbolContext.h" // for SymbolContext
23 #include "lldb/Symbol/SymbolVendor.h"
24 #include "lldb/Symbol/Symtab.h" // for Symtab
25 #include "lldb/Symbol/Type.h"   // for Type
26 #include "lldb/Symbol/Variable.h"
27 #include "lldb/Symbol/VariableList.h"
28 #include "lldb/Target/ExecutionContext.h"
29 #include "lldb/Target/ExecutionContextScope.h" // for ExecutionContextScope
30 #include "lldb/Target/Process.h"
31 #include "lldb/Target/SectionLoadList.h"
32 #include "lldb/Target/Target.h"
33 #include "lldb/Utility/ConstString.h"   // for ConstString
34 #include "lldb/Utility/DataExtractor.h" // for DataExtractor
35 #include "lldb/Utility/Endian.h"        // for InlHostByteOrder
36 #include "lldb/Utility/Error.h"         // for Error
37 #include "lldb/Utility/FileSpec.h"      // for FileSpec
38 #include "lldb/Utility/Stream.h"        // for Stream
39 #include "lldb/Utility/StreamString.h"  // for StreamString
40 
41 #include "llvm/ADT/StringRef.h" // for StringRef
42 #include "llvm/ADT/Triple.h"
43 #include "llvm/Support/Compiler.h" // for LLVM_FALLTHROUGH
44 
45 #include <cstdint> // for uint8_t, uint32_t
46 #include <memory>  // for shared_ptr, operator!=
47 #include <vector>  // for vector
48 
49 #include <assert.h>   // for assert
50 #include <inttypes.h> // for PRIu64, PRIx64
51 #include <string.h>   // for size_t, strlen
52 
53 namespace lldb_private {
54 class CompileUnit;
55 }
56 namespace lldb_private {
57 class Function;
58 }
59 
60 using namespace lldb;
61 using namespace lldb_private;
62 
63 static size_t ReadBytes(ExecutionContextScope *exe_scope,
64                         const Address &address, void *dst, size_t dst_len) {
65   if (exe_scope == nullptr)
66     return 0;
67 
68   TargetSP target_sp(exe_scope->CalculateTarget());
69   if (target_sp) {
70     Error error;
71     bool prefer_file_cache = false;
72     return target_sp->ReadMemory(address, prefer_file_cache, dst, dst_len,
73                                  error);
74   }
75   return 0;
76 }
77 
78 static bool GetByteOrderAndAddressSize(ExecutionContextScope *exe_scope,
79                                        const Address &address,
80                                        ByteOrder &byte_order,
81                                        uint32_t &addr_size) {
82   byte_order = eByteOrderInvalid;
83   addr_size = 0;
84   if (exe_scope == nullptr)
85     return false;
86 
87   TargetSP target_sp(exe_scope->CalculateTarget());
88   if (target_sp) {
89     byte_order = target_sp->GetArchitecture().GetByteOrder();
90     addr_size = target_sp->GetArchitecture().GetAddressByteSize();
91   }
92 
93   if (byte_order == eByteOrderInvalid || addr_size == 0) {
94     ModuleSP module_sp(address.GetModule());
95     if (module_sp) {
96       byte_order = module_sp->GetArchitecture().GetByteOrder();
97       addr_size = module_sp->GetArchitecture().GetAddressByteSize();
98     }
99   }
100   return byte_order != eByteOrderInvalid && addr_size != 0;
101 }
102 
103 static uint64_t ReadUIntMax64(ExecutionContextScope *exe_scope,
104                               const Address &address, uint32_t byte_size,
105                               bool &success) {
106   uint64_t uval64 = 0;
107   if (exe_scope == nullptr || byte_size > sizeof(uint64_t)) {
108     success = false;
109     return 0;
110   }
111   uint64_t buf = 0;
112 
113   success = ReadBytes(exe_scope, address, &buf, byte_size) == byte_size;
114   if (success) {
115     ByteOrder byte_order = eByteOrderInvalid;
116     uint32_t addr_size = 0;
117     if (GetByteOrderAndAddressSize(exe_scope, address, byte_order, addr_size)) {
118       DataExtractor data(&buf, sizeof(buf), byte_order, addr_size);
119       lldb::offset_t offset = 0;
120       uval64 = data.GetU64(&offset);
121     } else
122       success = false;
123   }
124   return uval64;
125 }
126 
127 static bool ReadAddress(ExecutionContextScope *exe_scope,
128                         const Address &address, uint32_t pointer_size,
129                         Address &deref_so_addr) {
130   if (exe_scope == nullptr)
131     return false;
132 
133   bool success = false;
134   addr_t deref_addr = ReadUIntMax64(exe_scope, address, pointer_size, success);
135   if (success) {
136     ExecutionContext exe_ctx;
137     exe_scope->CalculateExecutionContext(exe_ctx);
138     // If we have any sections that are loaded, try and resolve using the
139     // section load list
140     Target *target = exe_ctx.GetTargetPtr();
141     if (target && !target->GetSectionLoadList().IsEmpty()) {
142       if (target->GetSectionLoadList().ResolveLoadAddress(deref_addr,
143                                                           deref_so_addr))
144         return true;
145     } else {
146       // If we were not running, yet able to read an integer, we must
147       // have a module
148       ModuleSP module_sp(address.GetModule());
149 
150       assert(module_sp);
151       if (module_sp->ResolveFileAddress(deref_addr, deref_so_addr))
152         return true;
153     }
154 
155     // We couldn't make "deref_addr" into a section offset value, but we were
156     // able to read the address, so we return a section offset address with
157     // no section and "deref_addr" as the offset (address).
158     deref_so_addr.SetRawAddress(deref_addr);
159     return true;
160   }
161   return false;
162 }
163 
164 static bool DumpUInt(ExecutionContextScope *exe_scope, const Address &address,
165                      uint32_t byte_size, Stream *strm) {
166   if (exe_scope == nullptr || byte_size == 0)
167     return 0;
168   std::vector<uint8_t> buf(byte_size, 0);
169 
170   if (ReadBytes(exe_scope, address, &buf[0], buf.size()) == buf.size()) {
171     ByteOrder byte_order = eByteOrderInvalid;
172     uint32_t addr_size = 0;
173     if (GetByteOrderAndAddressSize(exe_scope, address, byte_order, addr_size)) {
174       DataExtractor data(&buf.front(), buf.size(), byte_order, addr_size);
175 
176       DumpDataExtractor(data, strm,
177                         0,                    // Start offset in "data"
178                         eFormatHex,           // Print as characters
179                         buf.size(),           // Size of item
180                         1,                    // Items count
181                         UINT32_MAX,           // num per line
182                         LLDB_INVALID_ADDRESS, // base address
183                         0,                    // bitfield bit size
184                         0);                   // bitfield bit offset
185 
186       return true;
187     }
188   }
189   return false;
190 }
191 
192 static size_t ReadCStringFromMemory(ExecutionContextScope *exe_scope,
193                                     const Address &address, Stream *strm) {
194   if (exe_scope == nullptr)
195     return 0;
196   const size_t k_buf_len = 256;
197   char buf[k_buf_len + 1];
198   buf[k_buf_len] = '\0'; // NULL terminate
199 
200   // Byte order and address size don't matter for C string dumping..
201   DataExtractor data(buf, sizeof(buf), endian::InlHostByteOrder(), 4);
202   size_t total_len = 0;
203   size_t bytes_read;
204   Address curr_address(address);
205   strm->PutChar('"');
206   while ((bytes_read = ReadBytes(exe_scope, curr_address, buf, k_buf_len)) >
207          0) {
208     size_t len = strlen(buf);
209     if (len == 0)
210       break;
211     if (len > bytes_read)
212       len = bytes_read;
213 
214     DumpDataExtractor(data, strm,
215                       0,                    // Start offset in "data"
216                       eFormatChar,          // Print as characters
217                       1,                    // Size of item (1 byte for a char!)
218                       len,                  // How many bytes to print?
219                       UINT32_MAX,           // num per line
220                       LLDB_INVALID_ADDRESS, // base address
221                       0,                    // bitfield bit size
222 
223                       0); // bitfield bit offset
224 
225     total_len += bytes_read;
226 
227     if (len < k_buf_len)
228       break;
229     curr_address.SetOffset(curr_address.GetOffset() + bytes_read);
230   }
231   strm->PutChar('"');
232   return total_len;
233 }
234 
235 Address::Address(lldb::addr_t abs_addr) : m_section_wp(), m_offset(abs_addr) {}
236 
237 Address::Address(addr_t address, const SectionList *section_list)
238     : m_section_wp(), m_offset(LLDB_INVALID_ADDRESS) {
239   ResolveAddressUsingFileSections(address, section_list);
240 }
241 
242 const Address &Address::operator=(const Address &rhs) {
243   if (this != &rhs) {
244     m_section_wp = rhs.m_section_wp;
245     m_offset = rhs.m_offset;
246   }
247   return *this;
248 }
249 
250 bool Address::ResolveAddressUsingFileSections(addr_t file_addr,
251                                               const SectionList *section_list) {
252   if (section_list) {
253     SectionSP section_sp(
254         section_list->FindSectionContainingFileAddress(file_addr));
255     m_section_wp = section_sp;
256     if (section_sp) {
257       assert(section_sp->ContainsFileAddress(file_addr));
258       m_offset = file_addr - section_sp->GetFileAddress();
259       return true; // Successfully transformed addr into a section offset
260                    // address
261     }
262   }
263   m_offset = file_addr;
264   return false; // Failed to resolve this address to a section offset value
265 }
266 
267 ModuleSP Address::GetModule() const {
268   lldb::ModuleSP module_sp;
269   SectionSP section_sp(GetSection());
270   if (section_sp)
271     module_sp = section_sp->GetModule();
272   return module_sp;
273 }
274 
275 addr_t Address::GetFileAddress() const {
276   SectionSP section_sp(GetSection());
277   if (section_sp) {
278     addr_t sect_file_addr = section_sp->GetFileAddress();
279     if (sect_file_addr == LLDB_INVALID_ADDRESS) {
280       // Section isn't resolved, we can't return a valid file address
281       return LLDB_INVALID_ADDRESS;
282     }
283     // We have a valid file range, so we can return the file based
284     // address by adding the file base address to our offset
285     return sect_file_addr + m_offset;
286   } else if (SectionWasDeletedPrivate()) {
287     // Used to have a valid section but it got deleted so the
288     // offset doesn't mean anything without the section
289     return LLDB_INVALID_ADDRESS;
290   }
291   // No section, we just return the offset since it is the value in this case
292   return m_offset;
293 }
294 
295 addr_t Address::GetLoadAddress(Target *target) const {
296   SectionSP section_sp(GetSection());
297   if (section_sp) {
298     if (target) {
299       addr_t sect_load_addr = section_sp->GetLoadBaseAddress(target);
300 
301       if (sect_load_addr != LLDB_INVALID_ADDRESS) {
302         // We have a valid file range, so we can return the file based
303         // address by adding the file base address to our offset
304         return sect_load_addr + m_offset;
305       }
306     }
307   } else if (SectionWasDeletedPrivate()) {
308     // Used to have a valid section but it got deleted so the
309     // offset doesn't mean anything without the section
310     return LLDB_INVALID_ADDRESS;
311   } else {
312     // We don't have a section so the offset is the load address
313     return m_offset;
314   }
315   // The section isn't resolved or an invalid target was passed in
316   // so we can't return a valid load address.
317   return LLDB_INVALID_ADDRESS;
318 }
319 
320 addr_t Address::GetCallableLoadAddress(Target *target, bool is_indirect) const {
321   addr_t code_addr = LLDB_INVALID_ADDRESS;
322 
323   if (is_indirect && target) {
324     ProcessSP processSP = target->GetProcessSP();
325     Error error;
326     if (processSP) {
327       code_addr = processSP->ResolveIndirectFunction(this, error);
328       if (!error.Success())
329         code_addr = LLDB_INVALID_ADDRESS;
330     }
331   } else {
332     code_addr = GetLoadAddress(target);
333   }
334 
335   if (code_addr == LLDB_INVALID_ADDRESS)
336     return code_addr;
337 
338   if (target)
339     return target->GetCallableLoadAddress(code_addr, GetAddressClass());
340   return code_addr;
341 }
342 
343 bool Address::SetCallableLoadAddress(lldb::addr_t load_addr, Target *target) {
344   if (SetLoadAddress(load_addr, target)) {
345     if (target)
346       m_offset = target->GetCallableLoadAddress(m_offset, GetAddressClass());
347     return true;
348   }
349   return false;
350 }
351 
352 addr_t Address::GetOpcodeLoadAddress(Target *target,
353                                      AddressClass addr_class) const {
354   addr_t code_addr = GetLoadAddress(target);
355   if (code_addr != LLDB_INVALID_ADDRESS) {
356     if (addr_class == eAddressClassInvalid)
357       addr_class = GetAddressClass();
358     code_addr = target->GetOpcodeLoadAddress(code_addr, addr_class);
359   }
360   return code_addr;
361 }
362 
363 bool Address::SetOpcodeLoadAddress(lldb::addr_t load_addr, Target *target,
364                                    AddressClass addr_class) {
365   if (SetLoadAddress(load_addr, target)) {
366     if (target) {
367       if (addr_class == eAddressClassInvalid)
368         addr_class = GetAddressClass();
369       m_offset = target->GetOpcodeLoadAddress(m_offset, addr_class);
370     }
371     return true;
372   }
373   return false;
374 }
375 
376 bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
377                    DumpStyle fallback_style, uint32_t addr_size) const {
378   // If the section was nullptr, only load address is going to work unless we
379   // are
380   // trying to deref a pointer
381   SectionSP section_sp(GetSection());
382   if (!section_sp && style != DumpStyleResolvedPointerDescription)
383     style = DumpStyleLoadAddress;
384 
385   ExecutionContext exe_ctx(exe_scope);
386   Target *target = exe_ctx.GetTargetPtr();
387   // If addr_byte_size is UINT32_MAX, then determine the correct address
388   // byte size for the process or default to the size of addr_t
389   if (addr_size == UINT32_MAX) {
390     if (target)
391       addr_size = target->GetArchitecture().GetAddressByteSize();
392     else
393       addr_size = sizeof(addr_t);
394   }
395 
396   Address so_addr;
397   switch (style) {
398   case DumpStyleInvalid:
399     return false;
400 
401   case DumpStyleSectionNameOffset:
402     if (section_sp) {
403       section_sp->DumpName(s);
404       s->Printf(" + %" PRIu64, m_offset);
405     } else {
406       s->Address(m_offset, addr_size);
407     }
408     break;
409 
410   case DumpStyleSectionPointerOffset:
411     s->Printf("(Section *)%p + ", static_cast<void *>(section_sp.get()));
412     s->Address(m_offset, addr_size);
413     break;
414 
415   case DumpStyleModuleWithFileAddress:
416     if (section_sp) {
417       ModuleSP module_sp = section_sp->GetModule();
418       if (module_sp)
419         s->Printf("%s[", module_sp->GetFileSpec().GetFilename().AsCString(
420                              "<Unknown>"));
421       else
422         s->Printf("%s[", "<Unknown>");
423     }
424     LLVM_FALLTHROUGH;
425   case DumpStyleFileAddress: {
426     addr_t file_addr = GetFileAddress();
427     if (file_addr == LLDB_INVALID_ADDRESS) {
428       if (fallback_style != DumpStyleInvalid)
429         return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
430       return false;
431     }
432     s->Address(file_addr, addr_size);
433     if (style == DumpStyleModuleWithFileAddress && section_sp)
434       s->PutChar(']');
435   } break;
436 
437   case DumpStyleLoadAddress: {
438     addr_t load_addr = GetLoadAddress(target);
439 
440     /*
441      * MIPS:
442      * Display address in compressed form for MIPS16 or microMIPS
443      * if the address belongs to eAddressClassCodeAlternateISA.
444     */
445     if (target) {
446       const llvm::Triple::ArchType llvm_arch =
447           target->GetArchitecture().GetMachine();
448       if (llvm_arch == llvm::Triple::mips ||
449           llvm_arch == llvm::Triple::mipsel ||
450           llvm_arch == llvm::Triple::mips64 ||
451           llvm_arch == llvm::Triple::mips64el)
452         load_addr = GetCallableLoadAddress(target);
453     }
454 
455     if (load_addr == LLDB_INVALID_ADDRESS) {
456       if (fallback_style != DumpStyleInvalid)
457         return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
458       return false;
459     }
460     s->Address(load_addr, addr_size);
461   } break;
462 
463   case DumpStyleResolvedDescription:
464   case DumpStyleResolvedDescriptionNoModule:
465   case DumpStyleResolvedDescriptionNoFunctionArguments:
466   case DumpStyleNoFunctionName:
467     if (IsSectionOffset()) {
468       uint32_t pointer_size = 4;
469       ModuleSP module_sp(GetModule());
470       if (target)
471         pointer_size = target->GetArchitecture().GetAddressByteSize();
472       else if (module_sp)
473         pointer_size = module_sp->GetArchitecture().GetAddressByteSize();
474 
475       bool showed_info = false;
476       if (section_sp) {
477         SectionType sect_type = section_sp->GetType();
478         switch (sect_type) {
479         case eSectionTypeData:
480           if (module_sp) {
481             SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
482             if (sym_vendor) {
483               Symtab *symtab = sym_vendor->GetSymtab();
484               if (symtab) {
485                 const addr_t file_Addr = GetFileAddress();
486                 Symbol *symbol =
487                     symtab->FindSymbolContainingFileAddress(file_Addr);
488                 if (symbol) {
489                   const char *symbol_name = symbol->GetName().AsCString();
490                   if (symbol_name) {
491                     s->PutCString(symbol_name);
492                     addr_t delta =
493                         file_Addr - symbol->GetAddressRef().GetFileAddress();
494                     if (delta)
495                       s->Printf(" + %" PRIu64, delta);
496                     showed_info = true;
497                   }
498                 }
499               }
500             }
501           }
502           break;
503 
504         case eSectionTypeDataCString:
505           // Read the C string from memory and display it
506           showed_info = true;
507           ReadCStringFromMemory(exe_scope, *this, s);
508           break;
509 
510         case eSectionTypeDataCStringPointers:
511           if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) {
512 #if VERBOSE_OUTPUT
513             s->PutCString("(char *)");
514             so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
515                          DumpStyleFileAddress);
516             s->PutCString(": ");
517 #endif
518             showed_info = true;
519             ReadCStringFromMemory(exe_scope, so_addr, s);
520           }
521           break;
522 
523         case eSectionTypeDataObjCMessageRefs:
524           if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) {
525             if (target && so_addr.IsSectionOffset()) {
526               SymbolContext func_sc;
527               target->GetImages().ResolveSymbolContextForAddress(
528                   so_addr, eSymbolContextEverything, func_sc);
529               if (func_sc.function != nullptr || func_sc.symbol != nullptr) {
530                 showed_info = true;
531 #if VERBOSE_OUTPUT
532                 s->PutCString("(objc_msgref *) -> { (func*)");
533                 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
534                              DumpStyleFileAddress);
535 #else
536                 s->PutCString("{ ");
537 #endif
538                 Address cstr_addr(*this);
539                 cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size);
540                 func_sc.DumpStopContext(s, exe_scope, so_addr, true, true,
541                                         false, true, true);
542                 if (ReadAddress(exe_scope, cstr_addr, pointer_size, so_addr)) {
543 #if VERBOSE_OUTPUT
544                   s->PutCString("), (char *)");
545                   so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
546                                DumpStyleFileAddress);
547                   s->PutCString(" (");
548 #else
549                   s->PutCString(", ");
550 #endif
551                   ReadCStringFromMemory(exe_scope, so_addr, s);
552                 }
553 #if VERBOSE_OUTPUT
554                 s->PutCString(") }");
555 #else
556                 s->PutCString(" }");
557 #endif
558               }
559             }
560           }
561           break;
562 
563         case eSectionTypeDataObjCCFStrings: {
564           Address cfstring_data_addr(*this);
565           cfstring_data_addr.SetOffset(cfstring_data_addr.GetOffset() +
566                                        (2 * pointer_size));
567           if (ReadAddress(exe_scope, cfstring_data_addr, pointer_size,
568                           so_addr)) {
569 #if VERBOSE_OUTPUT
570             s->PutCString("(CFString *) ");
571             cfstring_data_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
572                                     DumpStyleFileAddress);
573             s->PutCString(" -> @");
574 #else
575             s->PutChar('@');
576 #endif
577             if (so_addr.Dump(s, exe_scope, DumpStyleResolvedDescription))
578               showed_info = true;
579           }
580         } break;
581 
582         case eSectionTypeData4:
583           // Read the 4 byte data and display it
584           showed_info = true;
585           s->PutCString("(uint32_t) ");
586           DumpUInt(exe_scope, *this, 4, s);
587           break;
588 
589         case eSectionTypeData8:
590           // Read the 8 byte data and display it
591           showed_info = true;
592           s->PutCString("(uint64_t) ");
593           DumpUInt(exe_scope, *this, 8, s);
594           break;
595 
596         case eSectionTypeData16:
597           // Read the 16 byte data and display it
598           showed_info = true;
599           s->PutCString("(uint128_t) ");
600           DumpUInt(exe_scope, *this, 16, s);
601           break;
602 
603         case eSectionTypeDataPointers:
604           // Read the pointer data and display it
605           if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) {
606             s->PutCString("(void *)");
607             so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
608                          DumpStyleFileAddress);
609 
610             showed_info = true;
611             if (so_addr.IsSectionOffset()) {
612               SymbolContext pointer_sc;
613               if (target) {
614                 target->GetImages().ResolveSymbolContextForAddress(
615                     so_addr, eSymbolContextEverything, pointer_sc);
616                 if (pointer_sc.function != nullptr ||
617                     pointer_sc.symbol != nullptr) {
618                   s->PutCString(": ");
619                   pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false,
620                                              false, true, true);
621                 }
622               }
623             }
624           }
625           break;
626 
627         default:
628           break;
629         }
630       }
631 
632       if (!showed_info) {
633         if (module_sp) {
634           SymbolContext sc;
635           module_sp->ResolveSymbolContextForAddress(
636               *this, eSymbolContextEverything, sc);
637           if (sc.function || sc.symbol) {
638             bool show_stop_context = true;
639             const bool show_module = (style == DumpStyleResolvedDescription);
640             const bool show_fullpaths = false;
641             const bool show_inlined_frames = true;
642             const bool show_function_arguments =
643                 (style != DumpStyleResolvedDescriptionNoFunctionArguments);
644             const bool show_function_name = (style != DumpStyleNoFunctionName);
645             if (sc.function == nullptr && sc.symbol != nullptr) {
646               // If we have just a symbol make sure it is in the right section
647               if (sc.symbol->ValueIsAddress()) {
648                 if (sc.symbol->GetAddressRef().GetSection() != GetSection()) {
649                   // don't show the module if the symbol is a trampoline symbol
650                   show_stop_context = false;
651                 }
652               }
653             }
654             if (show_stop_context) {
655               // We have a function or a symbol from the same
656               // sections as this address.
657               sc.DumpStopContext(s, exe_scope, *this, show_fullpaths,
658                                  show_module, show_inlined_frames,
659                                  show_function_arguments, show_function_name);
660             } else {
661               // We found a symbol but it was in a different
662               // section so it isn't the symbol we should be
663               // showing, just show the section name + offset
664               Dump(s, exe_scope, DumpStyleSectionNameOffset);
665             }
666           }
667         }
668       }
669     } else {
670       if (fallback_style != DumpStyleInvalid)
671         return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
672       return false;
673     }
674     break;
675 
676   case DumpStyleDetailedSymbolContext:
677     if (IsSectionOffset()) {
678       ModuleSP module_sp(GetModule());
679       if (module_sp) {
680         SymbolContext sc;
681         module_sp->ResolveSymbolContextForAddress(
682             *this, eSymbolContextEverything | eSymbolContextVariable, sc);
683         if (sc.symbol) {
684           // If we have just a symbol make sure it is in the same section
685           // as our address. If it isn't, then we might have just found
686           // the last symbol that came before the address that we are
687           // looking up that has nothing to do with our address lookup.
688           if (sc.symbol->ValueIsAddress() &&
689               sc.symbol->GetAddressRef().GetSection() != GetSection())
690             sc.symbol = nullptr;
691         }
692         sc.GetDescription(s, eDescriptionLevelBrief, target);
693 
694         if (sc.block) {
695           bool can_create = true;
696           bool get_parent_variables = true;
697           bool stop_if_block_is_inlined_function = false;
698           VariableList variable_list;
699           sc.block->AppendVariables(can_create, get_parent_variables,
700                                     stop_if_block_is_inlined_function,
701                                     [](Variable *) { return true; },
702                                     &variable_list);
703 
704           const size_t num_variables = variable_list.GetSize();
705           for (size_t var_idx = 0; var_idx < num_variables; ++var_idx) {
706             Variable *var = variable_list.GetVariableAtIndex(var_idx).get();
707             if (var && var->LocationIsValidForAddress(*this)) {
708               s->Indent();
709               s->Printf("   Variable: id = {0x%8.8" PRIx64 "}, name = \"%s\"",
710                         var->GetID(), var->GetName().GetCString());
711               Type *type = var->GetType();
712               if (type)
713                 s->Printf(", type = \"%s\"", type->GetName().GetCString());
714               else
715                 s->PutCString(", type = <unknown>");
716               s->PutCString(", location = ");
717               var->DumpLocationForAddress(s, *this);
718               s->PutCString(", decl = ");
719               var->GetDeclaration().DumpStopContext(s, false);
720               s->EOL();
721             }
722           }
723         }
724       }
725     } else {
726       if (fallback_style != DumpStyleInvalid)
727         return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
728       return false;
729     }
730     break;
731 
732   case DumpStyleResolvedPointerDescription: {
733     Process *process = exe_ctx.GetProcessPtr();
734     if (process) {
735       addr_t load_addr = GetLoadAddress(target);
736       if (load_addr != LLDB_INVALID_ADDRESS) {
737         Error memory_error;
738         addr_t dereferenced_load_addr =
739             process->ReadPointerFromMemory(load_addr, memory_error);
740         if (dereferenced_load_addr != LLDB_INVALID_ADDRESS) {
741           Address dereferenced_addr;
742           if (dereferenced_addr.SetLoadAddress(dereferenced_load_addr,
743                                                target)) {
744             StreamString strm;
745             if (dereferenced_addr.Dump(&strm, exe_scope,
746                                        DumpStyleResolvedDescription,
747                                        DumpStyleInvalid, addr_size)) {
748               s->Address(dereferenced_load_addr, addr_size, " -> ", " ");
749               s->Write(strm.GetString().data(), strm.GetSize());
750               return true;
751             }
752           }
753         }
754       }
755     }
756     if (fallback_style != DumpStyleInvalid)
757       return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
758     return false;
759   } break;
760   }
761 
762   return true;
763 }
764 
765 bool Address::SectionWasDeleted() const {
766   if (GetSection())
767     return false;
768   return SectionWasDeletedPrivate();
769 }
770 
771 bool Address::SectionWasDeletedPrivate() const {
772   lldb::SectionWP empty_section_wp;
773 
774   // If either call to "std::weak_ptr::owner_before(...) value returns true,
775   // this
776   // indicates that m_section_wp once contained (possibly still does) a
777   // reference
778   // to a valid shared pointer. This helps us know if we had a valid reference
779   // to
780   // a section which is now invalid because the module it was in was
781   // unloaded/deleted,
782   // or if the address doesn't have a valid reference to a section.
783   return empty_section_wp.owner_before(m_section_wp) ||
784          m_section_wp.owner_before(empty_section_wp);
785 }
786 
787 uint32_t Address::CalculateSymbolContext(SymbolContext *sc,
788                                          uint32_t resolve_scope) const {
789   sc->Clear(false);
790   // Absolute addresses don't have enough information to reconstruct even their
791   // target.
792 
793   SectionSP section_sp(GetSection());
794   if (section_sp) {
795     ModuleSP module_sp(section_sp->GetModule());
796     if (module_sp) {
797       sc->module_sp = module_sp;
798       if (sc->module_sp)
799         return sc->module_sp->ResolveSymbolContextForAddress(
800             *this, resolve_scope, *sc);
801     }
802   }
803   return 0;
804 }
805 
806 ModuleSP Address::CalculateSymbolContextModule() const {
807   SectionSP section_sp(GetSection());
808   if (section_sp)
809     return section_sp->GetModule();
810   return ModuleSP();
811 }
812 
813 CompileUnit *Address::CalculateSymbolContextCompileUnit() const {
814   SectionSP section_sp(GetSection());
815   if (section_sp) {
816     SymbolContext sc;
817     sc.module_sp = section_sp->GetModule();
818     if (sc.module_sp) {
819       sc.module_sp->ResolveSymbolContextForAddress(*this,
820                                                    eSymbolContextCompUnit, sc);
821       return sc.comp_unit;
822     }
823   }
824   return nullptr;
825 }
826 
827 Function *Address::CalculateSymbolContextFunction() const {
828   SectionSP section_sp(GetSection());
829   if (section_sp) {
830     SymbolContext sc;
831     sc.module_sp = section_sp->GetModule();
832     if (sc.module_sp) {
833       sc.module_sp->ResolveSymbolContextForAddress(*this,
834                                                    eSymbolContextFunction, sc);
835       return sc.function;
836     }
837   }
838   return nullptr;
839 }
840 
841 Block *Address::CalculateSymbolContextBlock() const {
842   SectionSP section_sp(GetSection());
843   if (section_sp) {
844     SymbolContext sc;
845     sc.module_sp = section_sp->GetModule();
846     if (sc.module_sp) {
847       sc.module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextBlock,
848                                                    sc);
849       return sc.block;
850     }
851   }
852   return nullptr;
853 }
854 
855 Symbol *Address::CalculateSymbolContextSymbol() const {
856   SectionSP section_sp(GetSection());
857   if (section_sp) {
858     SymbolContext sc;
859     sc.module_sp = section_sp->GetModule();
860     if (sc.module_sp) {
861       sc.module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextSymbol,
862                                                    sc);
863       return sc.symbol;
864     }
865   }
866   return nullptr;
867 }
868 
869 bool Address::CalculateSymbolContextLineEntry(LineEntry &line_entry) const {
870   SectionSP section_sp(GetSection());
871   if (section_sp) {
872     SymbolContext sc;
873     sc.module_sp = section_sp->GetModule();
874     if (sc.module_sp) {
875       sc.module_sp->ResolveSymbolContextForAddress(*this,
876                                                    eSymbolContextLineEntry, sc);
877       if (sc.line_entry.IsValid()) {
878         line_entry = sc.line_entry;
879         return true;
880       }
881     }
882   }
883   line_entry.Clear();
884   return false;
885 }
886 
887 int Address::CompareFileAddress(const Address &a, const Address &b) {
888   addr_t a_file_addr = a.GetFileAddress();
889   addr_t b_file_addr = b.GetFileAddress();
890   if (a_file_addr < b_file_addr)
891     return -1;
892   if (a_file_addr > b_file_addr)
893     return +1;
894   return 0;
895 }
896 
897 int Address::CompareLoadAddress(const Address &a, const Address &b,
898                                 Target *target) {
899   assert(target != nullptr);
900   addr_t a_load_addr = a.GetLoadAddress(target);
901   addr_t b_load_addr = b.GetLoadAddress(target);
902   if (a_load_addr < b_load_addr)
903     return -1;
904   if (a_load_addr > b_load_addr)
905     return +1;
906   return 0;
907 }
908 
909 int Address::CompareModulePointerAndOffset(const Address &a, const Address &b) {
910   ModuleSP a_module_sp(a.GetModule());
911   ModuleSP b_module_sp(b.GetModule());
912   Module *a_module = a_module_sp.get();
913   Module *b_module = b_module_sp.get();
914   if (a_module < b_module)
915     return -1;
916   if (a_module > b_module)
917     return +1;
918   // Modules are the same, just compare the file address since they should
919   // be unique
920   addr_t a_file_addr = a.GetFileAddress();
921   addr_t b_file_addr = b.GetFileAddress();
922   if (a_file_addr < b_file_addr)
923     return -1;
924   if (a_file_addr > b_file_addr)
925     return +1;
926   return 0;
927 }
928 
929 size_t Address::MemorySize() const {
930   // Noting special for the memory size of a single Address object,
931   // it is just the size of itself.
932   return sizeof(Address);
933 }
934 
935 //----------------------------------------------------------------------
936 // NOTE: Be careful using this operator. It can correctly compare two
937 // addresses from the same Module correctly. It can't compare two
938 // addresses from different modules in any meaningful way, but it will
939 // compare the module pointers.
940 //
941 // To sum things up:
942 // - works great for addresses within the same module
943 // - it works for addresses across multiple modules, but don't expect the
944 //   address results to make much sense
945 //
946 // This basically lets Address objects be used in ordered collection
947 // classes.
948 //----------------------------------------------------------------------
949 
950 bool lldb_private::operator<(const Address &lhs, const Address &rhs) {
951   ModuleSP lhs_module_sp(lhs.GetModule());
952   ModuleSP rhs_module_sp(rhs.GetModule());
953   Module *lhs_module = lhs_module_sp.get();
954   Module *rhs_module = rhs_module_sp.get();
955   if (lhs_module == rhs_module) {
956     // Addresses are in the same module, just compare the file addresses
957     return lhs.GetFileAddress() < rhs.GetFileAddress();
958   } else {
959     // The addresses are from different modules, just use the module
960     // pointer value to get consistent ordering
961     return lhs_module < rhs_module;
962   }
963 }
964 
965 bool lldb_private::operator>(const Address &lhs, const Address &rhs) {
966   ModuleSP lhs_module_sp(lhs.GetModule());
967   ModuleSP rhs_module_sp(rhs.GetModule());
968   Module *lhs_module = lhs_module_sp.get();
969   Module *rhs_module = rhs_module_sp.get();
970   if (lhs_module == rhs_module) {
971     // Addresses are in the same module, just compare the file addresses
972     return lhs.GetFileAddress() > rhs.GetFileAddress();
973   } else {
974     // The addresses are from different modules, just use the module
975     // pointer value to get consistent ordering
976     return lhs_module > rhs_module;
977   }
978 }
979 
980 // The operator == checks for exact equality only (same section, same offset)
981 bool lldb_private::operator==(const Address &a, const Address &rhs) {
982   return a.GetOffset() == rhs.GetOffset() && a.GetSection() == rhs.GetSection();
983 }
984 
985 // The operator != checks for exact inequality only (differing section, or
986 // different offset)
987 bool lldb_private::operator!=(const Address &a, const Address &rhs) {
988   return a.GetOffset() != rhs.GetOffset() || a.GetSection() != rhs.GetSection();
989 }
990 
991 AddressClass Address::GetAddressClass() const {
992   ModuleSP module_sp(GetModule());
993   if (module_sp) {
994     ObjectFile *obj_file = module_sp->GetObjectFile();
995     if (obj_file) {
996       // Give the symbol vendor a chance to add to the unified section list.
997       module_sp->GetSymbolVendor();
998       return obj_file->GetAddressClass(GetFileAddress());
999     }
1000   }
1001   return eAddressClassUnknown;
1002 }
1003 
1004 bool Address::SetLoadAddress(lldb::addr_t load_addr, Target *target) {
1005   if (target &&
1006       target->GetSectionLoadList().ResolveLoadAddress(load_addr, *this))
1007     return true;
1008   m_section_wp.reset();
1009   m_offset = load_addr;
1010   return false;
1011 }
1012