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