blob: 0da83eb98edb1354502e9914659589a2d56da2ff [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- Address.cpp ---------------------------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "lldb/Core/Address.h"
Zachary Turner29cb8682017-03-03 20:57:05 +000010#include "lldb/Core/DumpDataExtractor.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000011#include "lldb/Core/Module.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000012#include "lldb/Core/ModuleList.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000013#include "lldb/Core/Section.h"
Greg Clayton1f746072012-08-29 21:13:06 +000014#include "lldb/Symbol/Block.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000015#include "lldb/Symbol/Declaration.h"
16#include "lldb/Symbol/LineEntry.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017#include "lldb/Symbol/ObjectFile.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000018#include "lldb/Symbol/Symbol.h"
19#include "lldb/Symbol/SymbolContext.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000020#include "lldb/Symbol/SymbolVendor.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000021#include "lldb/Symbol/Symtab.h"
22#include "lldb/Symbol/Type.h"
Greg Claytonc749eb82011-07-11 05:12:02 +000023#include "lldb/Symbol/Variable.h"
24#include "lldb/Symbol/VariableList.h"
Greg Claytonf5e56de2010-09-14 23:36:40 +000025#include "lldb/Target/ExecutionContext.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000026#include "lldb/Target/ExecutionContextScope.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027#include "lldb/Target/Process.h"
Greg Claytond5944cd2013-12-06 01:12:00 +000028#include "lldb/Target/SectionLoadList.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029#include "lldb/Target/Target.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000030#include "lldb/Utility/ConstString.h"
31#include "lldb/Utility/DataExtractor.h"
32#include "lldb/Utility/Endian.h"
33#include "lldb/Utility/FileSpec.h"
34#include "lldb/Utility/Status.h"
35#include "lldb/Utility/Stream.h"
36#include "lldb/Utility/StreamString.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000037
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000038#include "llvm/ADT/StringRef.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000039#include "llvm/ADT/Triple.h"
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000040#include "llvm/Support/Compiler.h"
Zachary Turner2f3df612017-04-06 21:28:29 +000041
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000042#include <cstdint>
43#include <memory>
44#include <vector>
Zachary Turner2f3df612017-04-06 21:28:29 +000045
Jonas Devlieghere672d2c12018-11-11 23:16:43 +000046#include <assert.h>
47#include <inttypes.h>
48#include <string.h>
Zachary Turner2f3df612017-04-06 21:28:29 +000049
50namespace lldb_private {
51class CompileUnit;
52}
53namespace lldb_private {
54class Function;
55}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000056
57using namespace lldb;
58using namespace lldb_private;
59
Kate Stoneb9c1b512016-09-06 20:57:50 +000060static size_t ReadBytes(ExecutionContextScope *exe_scope,
61 const Address &address, void *dst, size_t dst_len) {
62 if (exe_scope == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000063 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +000064
65 TargetSP target_sp(exe_scope->CalculateTarget());
66 if (target_sp) {
Zachary Turner97206d52017-05-12 04:51:55 +000067 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +000068 bool prefer_file_cache = false;
69 return target_sp->ReadMemory(address, prefer_file_cache, dst, dst_len,
70 error);
71 }
72 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000073}
74
Kate Stoneb9c1b512016-09-06 20:57:50 +000075static bool GetByteOrderAndAddressSize(ExecutionContextScope *exe_scope,
76 const Address &address,
77 ByteOrder &byte_order,
78 uint32_t &addr_size) {
79 byte_order = eByteOrderInvalid;
80 addr_size = 0;
81 if (exe_scope == nullptr)
82 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000083
Kate Stoneb9c1b512016-09-06 20:57:50 +000084 TargetSP target_sp(exe_scope->CalculateTarget());
85 if (target_sp) {
86 byte_order = target_sp->GetArchitecture().GetByteOrder();
87 addr_size = target_sp->GetArchitecture().GetAddressByteSize();
88 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000089
Kate Stoneb9c1b512016-09-06 20:57:50 +000090 if (byte_order == eByteOrderInvalid || addr_size == 0) {
91 ModuleSP module_sp(address.GetModule());
92 if (module_sp) {
93 byte_order = module_sp->GetArchitecture().GetByteOrder();
94 addr_size = module_sp->GetArchitecture().GetAddressByteSize();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000095 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000096 }
97 return byte_order != eByteOrderInvalid && addr_size != 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000098}
99
Kate Stoneb9c1b512016-09-06 20:57:50 +0000100static uint64_t ReadUIntMax64(ExecutionContextScope *exe_scope,
101 const Address &address, uint32_t byte_size,
102 bool &success) {
103 uint64_t uval64 = 0;
104 if (exe_scope == nullptr || byte_size > sizeof(uint64_t)) {
105 success = false;
106 return 0;
107 }
108 uint64_t buf = 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000109
Kate Stoneb9c1b512016-09-06 20:57:50 +0000110 success = ReadBytes(exe_scope, address, &buf, byte_size) == byte_size;
111 if (success) {
112 ByteOrder byte_order = eByteOrderInvalid;
113 uint32_t addr_size = 0;
114 if (GetByteOrderAndAddressSize(exe_scope, address, byte_order, addr_size)) {
115 DataExtractor data(&buf, sizeof(buf), byte_order, addr_size);
116 lldb::offset_t offset = 0;
117 uval64 = data.GetU64(&offset);
118 } else
119 success = false;
120 }
121 return uval64;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000122}
123
Kate Stoneb9c1b512016-09-06 20:57:50 +0000124static bool ReadAddress(ExecutionContextScope *exe_scope,
125 const Address &address, uint32_t pointer_size,
126 Address &deref_so_addr) {
127 if (exe_scope == nullptr)
128 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000129
Kate Stoneb9c1b512016-09-06 20:57:50 +0000130 bool success = false;
131 addr_t deref_addr = ReadUIntMax64(exe_scope, address, pointer_size, success);
132 if (success) {
133 ExecutionContext exe_ctx;
134 exe_scope->CalculateExecutionContext(exe_ctx);
135 // If we have any sections that are loaded, try and resolve using the
136 // section load list
137 Target *target = exe_ctx.GetTargetPtr();
138 if (target && !target->GetSectionLoadList().IsEmpty()) {
139 if (target->GetSectionLoadList().ResolveLoadAddress(deref_addr,
140 deref_so_addr))
141 return true;
142 } else {
Adrian Prantl05097242018-04-30 16:49:04 +0000143 // If we were not running, yet able to read an integer, we must have a
144 // module
Kate Stoneb9c1b512016-09-06 20:57:50 +0000145 ModuleSP module_sp(address.GetModule());
Greg Claytone72dfb32012-02-24 01:59:29 +0000146
Kate Stoneb9c1b512016-09-06 20:57:50 +0000147 assert(module_sp);
148 if (module_sp->ResolveFileAddress(deref_addr, deref_so_addr))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000149 return true;
150 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000151
152 // We couldn't make "deref_addr" into a section offset value, but we were
Adrian Prantl05097242018-04-30 16:49:04 +0000153 // able to read the address, so we return a section offset address with no
154 // section and "deref_addr" as the offset (address).
Kate Stoneb9c1b512016-09-06 20:57:50 +0000155 deref_so_addr.SetRawAddress(deref_addr);
156 return true;
157 }
158 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000159}
160
Kate Stoneb9c1b512016-09-06 20:57:50 +0000161static bool DumpUInt(ExecutionContextScope *exe_scope, const Address &address,
162 uint32_t byte_size, Stream *strm) {
163 if (exe_scope == nullptr || byte_size == 0)
Jonas Devlieghere09ad8c82019-05-24 00:44:33 +0000164 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000165 std::vector<uint8_t> buf(byte_size, 0);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000166
Kate Stoneb9c1b512016-09-06 20:57:50 +0000167 if (ReadBytes(exe_scope, address, &buf[0], buf.size()) == buf.size()) {
168 ByteOrder byte_order = eByteOrderInvalid;
169 uint32_t addr_size = 0;
170 if (GetByteOrderAndAddressSize(exe_scope, address, byte_order, addr_size)) {
171 DataExtractor data(&buf.front(), buf.size(), byte_order, addr_size);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000172
Zachary Turner29cb8682017-03-03 20:57:05 +0000173 DumpDataExtractor(data, strm,
174 0, // Start offset in "data"
175 eFormatHex, // Print as characters
176 buf.size(), // Size of item
177 1, // Items count
178 UINT32_MAX, // num per line
179 LLDB_INVALID_ADDRESS, // base address
180 0, // bitfield bit size
181 0); // bitfield bit offset
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000182
Kate Stoneb9c1b512016-09-06 20:57:50 +0000183 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000184 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000185 }
186 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000187}
188
Kate Stoneb9c1b512016-09-06 20:57:50 +0000189static size_t ReadCStringFromMemory(ExecutionContextScope *exe_scope,
190 const Address &address, Stream *strm) {
191 if (exe_scope == nullptr)
192 return 0;
193 const size_t k_buf_len = 256;
194 char buf[k_buf_len + 1];
195 buf[k_buf_len] = '\0'; // NULL terminate
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000196
Kate Stoneb9c1b512016-09-06 20:57:50 +0000197 // Byte order and address size don't matter for C string dumping..
198 DataExtractor data(buf, sizeof(buf), endian::InlHostByteOrder(), 4);
199 size_t total_len = 0;
200 size_t bytes_read;
201 Address curr_address(address);
202 strm->PutChar('"');
203 while ((bytes_read = ReadBytes(exe_scope, curr_address, buf, k_buf_len)) >
204 0) {
205 size_t len = strlen(buf);
206 if (len == 0)
207 break;
208 if (len > bytes_read)
209 len = bytes_read;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000210
Zachary Turner29cb8682017-03-03 20:57:05 +0000211 DumpDataExtractor(data, strm,
212 0, // Start offset in "data"
213 eFormatChar, // Print as characters
214 1, // Size of item (1 byte for a char!)
215 len, // How many bytes to print?
216 UINT32_MAX, // num per line
217 LLDB_INVALID_ADDRESS, // base address
218 0, // bitfield bit size
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000219
Zachary Turner29cb8682017-03-03 20:57:05 +0000220 0); // bitfield bit offset
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000221
Kate Stoneb9c1b512016-09-06 20:57:50 +0000222 total_len += bytes_read;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000223
Kate Stoneb9c1b512016-09-06 20:57:50 +0000224 if (len < k_buf_len)
225 break;
226 curr_address.SetOffset(curr_address.GetOffset() + bytes_read);
227 }
228 strm->PutChar('"');
229 return total_len;
230}
231
232Address::Address(lldb::addr_t abs_addr) : m_section_wp(), m_offset(abs_addr) {}
233
234Address::Address(addr_t address, const SectionList *section_list)
235 : m_section_wp(), m_offset(LLDB_INVALID_ADDRESS) {
236 ResolveAddressUsingFileSections(address, section_list);
237}
238
239const Address &Address::operator=(const Address &rhs) {
240 if (this != &rhs) {
241 m_section_wp = rhs.m_section_wp;
242 m_offset = rhs.m_offset;
243 }
244 return *this;
245}
246
247bool Address::ResolveAddressUsingFileSections(addr_t file_addr,
248 const SectionList *section_list) {
249 if (section_list) {
250 SectionSP section_sp(
251 section_list->FindSectionContainingFileAddress(file_addr));
252 m_section_wp = section_sp;
253 if (section_sp) {
254 assert(section_sp->ContainsFileAddress(file_addr));
255 m_offset = file_addr - section_sp->GetFileAddress();
256 return true; // Successfully transformed addr into a section offset
257 // address
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000258 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000259 }
260 m_offset = file_addr;
261 return false; // Failed to resolve this address to a section offset value
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000262}
263
Kate Stoneb9c1b512016-09-06 20:57:50 +0000264ModuleSP Address::GetModule() const {
265 lldb::ModuleSP module_sp;
266 SectionSP section_sp(GetSection());
267 if (section_sp)
268 module_sp = section_sp->GetModule();
269 return module_sp;
Greg Claytone72dfb32012-02-24 01:59:29 +0000270}
271
Kate Stoneb9c1b512016-09-06 20:57:50 +0000272addr_t Address::GetFileAddress() const {
273 SectionSP section_sp(GetSection());
274 if (section_sp) {
275 addr_t sect_file_addr = section_sp->GetFileAddress();
276 if (sect_file_addr == LLDB_INVALID_ADDRESS) {
277 // Section isn't resolved, we can't return a valid file address
278 return LLDB_INVALID_ADDRESS;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000279 }
Adrian Prantl05097242018-04-30 16:49:04 +0000280 // We have a valid file range, so we can return the file based address by
281 // adding the file base address to our offset
Kate Stoneb9c1b512016-09-06 20:57:50 +0000282 return sect_file_addr + m_offset;
Davide Italianoae3f7932018-09-10 23:09:09 +0000283 } else if (SectionWasDeletedPrivate()) {
Adrian Prantl05097242018-04-30 16:49:04 +0000284 // Used to have a valid section but it got deleted so the offset doesn't
285 // mean anything without the section
Kate Stoneb9c1b512016-09-06 20:57:50 +0000286 return LLDB_INVALID_ADDRESS;
287 }
288 // No section, we just return the offset since it is the value in this case
289 return m_offset;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000290}
291
Kate Stoneb9c1b512016-09-06 20:57:50 +0000292addr_t Address::GetLoadAddress(Target *target) const {
293 SectionSP section_sp(GetSection());
294 if (section_sp) {
295 if (target) {
296 addr_t sect_load_addr = section_sp->GetLoadBaseAddress(target);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000297
Kate Stoneb9c1b512016-09-06 20:57:50 +0000298 if (sect_load_addr != LLDB_INVALID_ADDRESS) {
Adrian Prantl05097242018-04-30 16:49:04 +0000299 // We have a valid file range, so we can return the file based address
300 // by adding the file base address to our offset
Kate Stoneb9c1b512016-09-06 20:57:50 +0000301 return sect_load_addr + m_offset;
302 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000303 }
Davide Italianoae3f7932018-09-10 23:09:09 +0000304 } else if (SectionWasDeletedPrivate()) {
Adrian Prantl05097242018-04-30 16:49:04 +0000305 // Used to have a valid section but it got deleted so the offset doesn't
306 // mean anything without the section
Greg Claytonf5e56de2010-09-14 23:36:40 +0000307 return LLDB_INVALID_ADDRESS;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000308 } else {
309 // We don't have a section so the offset is the load address
310 return m_offset;
311 }
Adrian Prantl05097242018-04-30 16:49:04 +0000312 // The section isn't resolved or an invalid target was passed in so we can't
313 // return a valid load address.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000314 return LLDB_INVALID_ADDRESS;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000315}
316
Kate Stoneb9c1b512016-09-06 20:57:50 +0000317addr_t Address::GetCallableLoadAddress(Target *target, bool is_indirect) const {
318 addr_t code_addr = LLDB_INVALID_ADDRESS;
319
320 if (is_indirect && target) {
321 ProcessSP processSP = target->GetProcessSP();
Zachary Turner97206d52017-05-12 04:51:55 +0000322 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000323 if (processSP) {
324 code_addr = processSP->ResolveIndirectFunction(this, error);
325 if (!error.Success())
326 code_addr = LLDB_INVALID_ADDRESS;
Matt Kopec00049b82013-02-27 20:13:38 +0000327 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000328 } else {
329 code_addr = GetLoadAddress(target);
330 }
331
332 if (code_addr == LLDB_INVALID_ADDRESS)
333 return code_addr;
334
335 if (target)
336 return target->GetCallableLoadAddress(code_addr, GetAddressClass());
337 return code_addr;
338}
339
340bool Address::SetCallableLoadAddress(lldb::addr_t load_addr, Target *target) {
341 if (SetLoadAddress(load_addr, target)) {
Greg Claytonf3ef3d22011-05-22 22:46:53 +0000342 if (target)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000343 m_offset = target->GetCallableLoadAddress(m_offset, GetAddressClass());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000344 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000345 }
346 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000347}
348
Kate Stoneb9c1b512016-09-06 20:57:50 +0000349addr_t Address::GetOpcodeLoadAddress(Target *target,
350 AddressClass addr_class) const {
351 addr_t code_addr = GetLoadAddress(target);
352 if (code_addr != LLDB_INVALID_ADDRESS) {
Tatyana Krasnukha04803b32018-06-26 13:06:54 +0000353 if (addr_class == AddressClass::eInvalid)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000354 addr_class = GetAddressClass();
355 code_addr = target->GetOpcodeLoadAddress(code_addr, addr_class);
356 }
357 return code_addr;
Greg Claytonb35db632013-11-09 00:03:31 +0000358}
359
Kate Stoneb9c1b512016-09-06 20:57:50 +0000360bool Address::SetOpcodeLoadAddress(lldb::addr_t load_addr, Target *target,
Pavel Labathc3c72122017-06-08 13:26:35 +0000361 AddressClass addr_class,
362 bool allow_section_end) {
363 if (SetLoadAddress(load_addr, target, allow_section_end)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000364 if (target) {
Tatyana Krasnukha04803b32018-06-26 13:06:54 +0000365 if (addr_class == AddressClass::eInvalid)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000366 addr_class = GetAddressClass();
367 m_offset = target->GetOpcodeLoadAddress(m_offset, addr_class);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000368 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000369 return true;
370 }
371 return false;
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000372}
373
Kate Stoneb9c1b512016-09-06 20:57:50 +0000374bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
375 DumpStyle fallback_style, uint32_t addr_size) const {
376 // If the section was nullptr, only load address is going to work unless we
Adrian Prantl05097242018-04-30 16:49:04 +0000377 // are trying to deref a pointer
Kate Stoneb9c1b512016-09-06 20:57:50 +0000378 SectionSP section_sp(GetSection());
379 if (!section_sp && style != DumpStyleResolvedPointerDescription)
380 style = DumpStyleLoadAddress;
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000381
Kate Stoneb9c1b512016-09-06 20:57:50 +0000382 ExecutionContext exe_ctx(exe_scope);
383 Target *target = exe_ctx.GetTargetPtr();
Adrian Prantl05097242018-04-30 16:49:04 +0000384 // If addr_byte_size is UINT32_MAX, then determine the correct address byte
385 // size for the process or default to the size of addr_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000386 if (addr_size == UINT32_MAX) {
387 if (target)
388 addr_size = target->GetArchitecture().GetAddressByteSize();
389 else
390 addr_size = sizeof(addr_t);
391 }
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000392
Kate Stoneb9c1b512016-09-06 20:57:50 +0000393 Address so_addr;
394 switch (style) {
395 case DumpStyleInvalid:
Greg Clayton7e9b1fd2011-08-12 21:40:01 +0000396 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000397
398 case DumpStyleSectionNameOffset:
399 if (section_sp) {
400 section_sp->DumpName(s);
401 s->Printf(" + %" PRIu64, m_offset);
402 } else {
403 s->Address(m_offset, addr_size);
404 }
405 break;
406
407 case DumpStyleSectionPointerOffset:
408 s->Printf("(Section *)%p + ", static_cast<void *>(section_sp.get()));
409 s->Address(m_offset, addr_size);
410 break;
411
412 case DumpStyleModuleWithFileAddress:
413 if (section_sp) {
414 ModuleSP module_sp = section_sp->GetModule();
415 if (module_sp)
416 s->Printf("%s[", module_sp->GetFileSpec().GetFilename().AsCString(
417 "<Unknown>"));
418 else
419 s->Printf("%s[", "<Unknown>");
420 }
421 LLVM_FALLTHROUGH;
422 case DumpStyleFileAddress: {
423 addr_t file_addr = GetFileAddress();
424 if (file_addr == LLDB_INVALID_ADDRESS) {
425 if (fallback_style != DumpStyleInvalid)
426 return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
427 return false;
428 }
429 s->Address(file_addr, addr_size);
430 if (style == DumpStyleModuleWithFileAddress && section_sp)
431 s->PutChar(']');
432 } break;
433
434 case DumpStyleLoadAddress: {
435 addr_t load_addr = GetLoadAddress(target);
436
437 /*
438 * MIPS:
439 * Display address in compressed form for MIPS16 or microMIPS
Tatyana Krasnukha04803b32018-06-26 13:06:54 +0000440 * if the address belongs to AddressClass::eCodeAlternateISA.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000441 */
442 if (target) {
443 const llvm::Triple::ArchType llvm_arch =
444 target->GetArchitecture().GetMachine();
445 if (llvm_arch == llvm::Triple::mips ||
446 llvm_arch == llvm::Triple::mipsel ||
447 llvm_arch == llvm::Triple::mips64 ||
448 llvm_arch == llvm::Triple::mips64el)
449 load_addr = GetCallableLoadAddress(target);
450 }
451
452 if (load_addr == LLDB_INVALID_ADDRESS) {
453 if (fallback_style != DumpStyleInvalid)
454 return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
455 return false;
456 }
457 s->Address(load_addr, addr_size);
458 } break;
459
460 case DumpStyleResolvedDescription:
461 case DumpStyleResolvedDescriptionNoModule:
462 case DumpStyleResolvedDescriptionNoFunctionArguments:
463 case DumpStyleNoFunctionName:
464 if (IsSectionOffset()) {
465 uint32_t pointer_size = 4;
466 ModuleSP module_sp(GetModule());
467 if (target)
468 pointer_size = target->GetArchitecture().GetAddressByteSize();
469 else if (module_sp)
470 pointer_size = module_sp->GetArchitecture().GetAddressByteSize();
471
472 bool showed_info = false;
473 if (section_sp) {
474 SectionType sect_type = section_sp->GetType();
475 switch (sect_type) {
476 case eSectionTypeData:
477 if (module_sp) {
478 SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
479 if (sym_vendor) {
480 Symtab *symtab = sym_vendor->GetSymtab();
481 if (symtab) {
482 const addr_t file_Addr = GetFileAddress();
483 Symbol *symbol =
484 symtab->FindSymbolContainingFileAddress(file_Addr);
485 if (symbol) {
486 const char *symbol_name = symbol->GetName().AsCString();
487 if (symbol_name) {
488 s->PutCString(symbol_name);
489 addr_t delta =
490 file_Addr - symbol->GetAddressRef().GetFileAddress();
491 if (delta)
492 s->Printf(" + %" PRIu64, delta);
493 showed_info = true;
494 }
495 }
496 }
497 }
498 }
499 break;
500
501 case eSectionTypeDataCString:
502 // Read the C string from memory and display it
503 showed_info = true;
504 ReadCStringFromMemory(exe_scope, *this, s);
505 break;
506
507 case eSectionTypeDataCStringPointers:
508 if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) {
509#if VERBOSE_OUTPUT
510 s->PutCString("(char *)");
511 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
512 DumpStyleFileAddress);
513 s->PutCString(": ");
514#endif
515 showed_info = true;
516 ReadCStringFromMemory(exe_scope, so_addr, s);
517 }
518 break;
519
520 case eSectionTypeDataObjCMessageRefs:
521 if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) {
522 if (target && so_addr.IsSectionOffset()) {
523 SymbolContext func_sc;
524 target->GetImages().ResolveSymbolContextForAddress(
525 so_addr, eSymbolContextEverything, func_sc);
526 if (func_sc.function != nullptr || func_sc.symbol != nullptr) {
527 showed_info = true;
528#if VERBOSE_OUTPUT
529 s->PutCString("(objc_msgref *) -> { (func*)");
530 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
531 DumpStyleFileAddress);
532#else
533 s->PutCString("{ ");
534#endif
535 Address cstr_addr(*this);
536 cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size);
537 func_sc.DumpStopContext(s, exe_scope, so_addr, true, true,
538 false, true, true);
539 if (ReadAddress(exe_scope, cstr_addr, pointer_size, so_addr)) {
540#if VERBOSE_OUTPUT
541 s->PutCString("), (char *)");
542 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
543 DumpStyleFileAddress);
544 s->PutCString(" (");
545#else
546 s->PutCString(", ");
547#endif
548 ReadCStringFromMemory(exe_scope, so_addr, s);
549 }
550#if VERBOSE_OUTPUT
551 s->PutCString(") }");
552#else
553 s->PutCString(" }");
554#endif
555 }
556 }
557 }
558 break;
559
560 case eSectionTypeDataObjCCFStrings: {
561 Address cfstring_data_addr(*this);
562 cfstring_data_addr.SetOffset(cfstring_data_addr.GetOffset() +
563 (2 * pointer_size));
564 if (ReadAddress(exe_scope, cfstring_data_addr, pointer_size,
565 so_addr)) {
566#if VERBOSE_OUTPUT
567 s->PutCString("(CFString *) ");
568 cfstring_data_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
569 DumpStyleFileAddress);
570 s->PutCString(" -> @");
571#else
572 s->PutChar('@');
573#endif
574 if (so_addr.Dump(s, exe_scope, DumpStyleResolvedDescription))
575 showed_info = true;
576 }
577 } break;
578
579 case eSectionTypeData4:
580 // Read the 4 byte data and display it
581 showed_info = true;
582 s->PutCString("(uint32_t) ");
583 DumpUInt(exe_scope, *this, 4, s);
584 break;
585
586 case eSectionTypeData8:
587 // Read the 8 byte data and display it
588 showed_info = true;
589 s->PutCString("(uint64_t) ");
590 DumpUInt(exe_scope, *this, 8, s);
591 break;
592
593 case eSectionTypeData16:
594 // Read the 16 byte data and display it
595 showed_info = true;
596 s->PutCString("(uint128_t) ");
597 DumpUInt(exe_scope, *this, 16, s);
598 break;
599
600 case eSectionTypeDataPointers:
601 // Read the pointer data and display it
602 if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) {
603 s->PutCString("(void *)");
604 so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
605 DumpStyleFileAddress);
606
607 showed_info = true;
608 if (so_addr.IsSectionOffset()) {
609 SymbolContext pointer_sc;
610 if (target) {
611 target->GetImages().ResolveSymbolContextForAddress(
612 so_addr, eSymbolContextEverything, pointer_sc);
613 if (pointer_sc.function != nullptr ||
614 pointer_sc.symbol != nullptr) {
615 s->PutCString(": ");
616 pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false,
617 false, true, true);
618 }
619 }
620 }
621 }
622 break;
623
624 default:
625 break;
626 }
627 }
628
629 if (!showed_info) {
630 if (module_sp) {
631 SymbolContext sc;
632 module_sp->ResolveSymbolContextForAddress(
633 *this, eSymbolContextEverything, sc);
634 if (sc.function || sc.symbol) {
635 bool show_stop_context = true;
636 const bool show_module = (style == DumpStyleResolvedDescription);
637 const bool show_fullpaths = false;
638 const bool show_inlined_frames = true;
639 const bool show_function_arguments =
640 (style != DumpStyleResolvedDescriptionNoFunctionArguments);
641 const bool show_function_name = (style != DumpStyleNoFunctionName);
642 if (sc.function == nullptr && sc.symbol != nullptr) {
643 // If we have just a symbol make sure it is in the right section
644 if (sc.symbol->ValueIsAddress()) {
645 if (sc.symbol->GetAddressRef().GetSection() != GetSection()) {
646 // don't show the module if the symbol is a trampoline symbol
647 show_stop_context = false;
648 }
649 }
650 }
651 if (show_stop_context) {
Adrian Prantl05097242018-04-30 16:49:04 +0000652 // We have a function or a symbol from the same sections as this
653 // address.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000654 sc.DumpStopContext(s, exe_scope, *this, show_fullpaths,
655 show_module, show_inlined_frames,
656 show_function_arguments, show_function_name);
657 } else {
Adrian Prantl05097242018-04-30 16:49:04 +0000658 // We found a symbol but it was in a different section so it
659 // isn't the symbol we should be showing, just show the section
660 // name + offset
Kate Stoneb9c1b512016-09-06 20:57:50 +0000661 Dump(s, exe_scope, DumpStyleSectionNameOffset);
662 }
663 }
664 }
665 }
666 } else {
667 if (fallback_style != DumpStyleInvalid)
668 return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
669 return false;
670 }
671 break;
672
673 case DumpStyleDetailedSymbolContext:
674 if (IsSectionOffset()) {
675 ModuleSP module_sp(GetModule());
676 if (module_sp) {
677 SymbolContext sc;
678 module_sp->ResolveSymbolContextForAddress(
679 *this, eSymbolContextEverything | eSymbolContextVariable, sc);
680 if (sc.symbol) {
Adrian Prantl05097242018-04-30 16:49:04 +0000681 // If we have just a symbol make sure it is in the same section as
682 // our address. If it isn't, then we might have just found the last
683 // symbol that came before the address that we are looking up that
684 // has nothing to do with our address lookup.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000685 if (sc.symbol->ValueIsAddress() &&
686 sc.symbol->GetAddressRef().GetSection() != GetSection())
687 sc.symbol = nullptr;
688 }
689 sc.GetDescription(s, eDescriptionLevelBrief, target);
690
691 if (sc.block) {
692 bool can_create = true;
693 bool get_parent_variables = true;
694 bool stop_if_block_is_inlined_function = false;
695 VariableList variable_list;
696 sc.block->AppendVariables(can_create, get_parent_variables,
697 stop_if_block_is_inlined_function,
698 [](Variable *) { return true; },
699 &variable_list);
700
701 const size_t num_variables = variable_list.GetSize();
702 for (size_t var_idx = 0; var_idx < num_variables; ++var_idx) {
703 Variable *var = variable_list.GetVariableAtIndex(var_idx).get();
704 if (var && var->LocationIsValidForAddress(*this)) {
705 s->Indent();
706 s->Printf(" Variable: id = {0x%8.8" PRIx64 "}, name = \"%s\"",
707 var->GetID(), var->GetName().GetCString());
708 Type *type = var->GetType();
709 if (type)
710 s->Printf(", type = \"%s\"", type->GetName().GetCString());
711 else
712 s->PutCString(", type = <unknown>");
713 s->PutCString(", location = ");
714 var->DumpLocationForAddress(s, *this);
715 s->PutCString(", decl = ");
716 var->GetDeclaration().DumpStopContext(s, false);
717 s->EOL();
718 }
719 }
720 }
721 }
722 } else {
723 if (fallback_style != DumpStyleInvalid)
724 return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
725 return false;
726 }
727 break;
728
729 case DumpStyleResolvedPointerDescription: {
730 Process *process = exe_ctx.GetProcessPtr();
731 if (process) {
732 addr_t load_addr = GetLoadAddress(target);
733 if (load_addr != LLDB_INVALID_ADDRESS) {
Zachary Turner97206d52017-05-12 04:51:55 +0000734 Status memory_error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000735 addr_t dereferenced_load_addr =
736 process->ReadPointerFromMemory(load_addr, memory_error);
737 if (dereferenced_load_addr != LLDB_INVALID_ADDRESS) {
738 Address dereferenced_addr;
739 if (dereferenced_addr.SetLoadAddress(dereferenced_load_addr,
740 target)) {
741 StreamString strm;
742 if (dereferenced_addr.Dump(&strm, exe_scope,
743 DumpStyleResolvedDescription,
744 DumpStyleInvalid, addr_size)) {
745 s->Address(dereferenced_load_addr, addr_size, " -> ", " ");
Zachary Turnerc1564272016-11-16 21:15:24 +0000746 s->Write(strm.GetString().data(), strm.GetSize());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000747 return true;
748 }
749 }
750 }
751 }
752 }
753 if (fallback_style != DumpStyleInvalid)
754 return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
755 return false;
756 } break;
757 }
758
759 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000760}
761
Kate Stoneb9c1b512016-09-06 20:57:50 +0000762bool Address::SectionWasDeleted() const {
Davide Italianoae3f7932018-09-10 23:09:09 +0000763 if (GetSection())
764 return false;
765 return SectionWasDeletedPrivate();
766}
767
768bool Address::SectionWasDeletedPrivate() const {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000769 lldb::SectionWP empty_section_wp;
770
771 // If either call to "std::weak_ptr::owner_before(...) value returns true,
Adrian Prantl05097242018-04-30 16:49:04 +0000772 // this indicates that m_section_wp once contained (possibly still does) a
773 // reference to a valid shared pointer. This helps us know if we had a valid
774 // reference to a section which is now invalid because the module it was in
775 // was unloaded/deleted, or if the address doesn't have a valid reference to
776 // a section.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000777 return empty_section_wp.owner_before(m_section_wp) ||
778 m_section_wp.owner_before(empty_section_wp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000779}
780
Zachary Turner991e4452018-10-25 20:45:19 +0000781uint32_t
782Address::CalculateSymbolContext(SymbolContext *sc,
783 SymbolContextItem resolve_scope) const {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000784 sc->Clear(false);
785 // Absolute addresses don't have enough information to reconstruct even their
786 // target.
787
788 SectionSP section_sp(GetSection());
789 if (section_sp) {
790 ModuleSP module_sp(section_sp->GetModule());
791 if (module_sp) {
792 sc->module_sp = module_sp;
793 if (sc->module_sp)
794 return sc->module_sp->ResolveSymbolContextForAddress(
795 *this, resolve_scope, *sc);
796 }
797 }
798 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000799}
800
Kate Stoneb9c1b512016-09-06 20:57:50 +0000801ModuleSP Address::CalculateSymbolContextModule() const {
802 SectionSP section_sp(GetSection());
803 if (section_sp)
804 return section_sp->GetModule();
805 return ModuleSP();
806}
807
808CompileUnit *Address::CalculateSymbolContextCompileUnit() const {
809 SectionSP section_sp(GetSection());
810 if (section_sp) {
811 SymbolContext sc;
812 sc.module_sp = section_sp->GetModule();
813 if (sc.module_sp) {
814 sc.module_sp->ResolveSymbolContextForAddress(*this,
815 eSymbolContextCompUnit, sc);
816 return sc.comp_unit;
817 }
818 }
819 return nullptr;
820}
821
822Function *Address::CalculateSymbolContextFunction() const {
823 SectionSP section_sp(GetSection());
824 if (section_sp) {
825 SymbolContext sc;
826 sc.module_sp = section_sp->GetModule();
827 if (sc.module_sp) {
828 sc.module_sp->ResolveSymbolContextForAddress(*this,
829 eSymbolContextFunction, sc);
830 return sc.function;
831 }
832 }
833 return nullptr;
834}
835
836Block *Address::CalculateSymbolContextBlock() const {
837 SectionSP section_sp(GetSection());
838 if (section_sp) {
839 SymbolContext sc;
840 sc.module_sp = section_sp->GetModule();
841 if (sc.module_sp) {
842 sc.module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextBlock,
843 sc);
844 return sc.block;
845 }
846 }
847 return nullptr;
848}
849
850Symbol *Address::CalculateSymbolContextSymbol() const {
851 SectionSP section_sp(GetSection());
852 if (section_sp) {
853 SymbolContext sc;
854 sc.module_sp = section_sp->GetModule();
855 if (sc.module_sp) {
856 sc.module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextSymbol,
857 sc);
858 return sc.symbol;
859 }
860 }
861 return nullptr;
862}
863
864bool Address::CalculateSymbolContextLineEntry(LineEntry &line_entry) const {
865 SectionSP section_sp(GetSection());
866 if (section_sp) {
867 SymbolContext sc;
868 sc.module_sp = section_sp->GetModule();
869 if (sc.module_sp) {
870 sc.module_sp->ResolveSymbolContextForAddress(*this,
871 eSymbolContextLineEntry, sc);
872 if (sc.line_entry.IsValid()) {
873 line_entry = sc.line_entry;
874 return true;
875 }
876 }
877 }
878 line_entry.Clear();
879 return false;
880}
881
882int Address::CompareFileAddress(const Address &a, const Address &b) {
883 addr_t a_file_addr = a.GetFileAddress();
884 addr_t b_file_addr = b.GetFileAddress();
885 if (a_file_addr < b_file_addr)
886 return -1;
887 if (a_file_addr > b_file_addr)
888 return +1;
889 return 0;
890}
891
892int Address::CompareLoadAddress(const Address &a, const Address &b,
893 Target *target) {
894 assert(target != nullptr);
895 addr_t a_load_addr = a.GetLoadAddress(target);
896 addr_t b_load_addr = b.GetLoadAddress(target);
897 if (a_load_addr < b_load_addr)
898 return -1;
899 if (a_load_addr > b_load_addr)
900 return +1;
901 return 0;
902}
903
904int Address::CompareModulePointerAndOffset(const Address &a, const Address &b) {
905 ModuleSP a_module_sp(a.GetModule());
906 ModuleSP b_module_sp(b.GetModule());
907 Module *a_module = a_module_sp.get();
908 Module *b_module = b_module_sp.get();
909 if (a_module < b_module)
910 return -1;
911 if (a_module > b_module)
912 return +1;
Adrian Prantl05097242018-04-30 16:49:04 +0000913 // Modules are the same, just compare the file address since they should be
914 // unique
Kate Stoneb9c1b512016-09-06 20:57:50 +0000915 addr_t a_file_addr = a.GetFileAddress();
916 addr_t b_file_addr = b.GetFileAddress();
917 if (a_file_addr < b_file_addr)
918 return -1;
919 if (a_file_addr > b_file_addr)
920 return +1;
921 return 0;
922}
923
924size_t Address::MemorySize() const {
Adrian Prantl05097242018-04-30 16:49:04 +0000925 // Noting special for the memory size of a single Address object, it is just
926 // the size of itself.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000927 return sizeof(Address);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000928}
929
Kate Stoneb9c1b512016-09-06 20:57:50 +0000930// NOTE: Be careful using this operator. It can correctly compare two
Adrian Prantl05097242018-04-30 16:49:04 +0000931// addresses from the same Module correctly. It can't compare two addresses
932// from different modules in any meaningful way, but it will compare the module
933// pointers.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000934//
Greg Claytonb0848c52011-01-08 00:05:12 +0000935// To sum things up:
Adrian Prantl05097242018-04-30 16:49:04 +0000936// - works great for addresses within the same module - it works for addresses
937// across multiple modules, but don't expect the
Greg Claytonb0848c52011-01-08 00:05:12 +0000938// address results to make much sense
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000939//
Adrian Prantl05097242018-04-30 16:49:04 +0000940// This basically lets Address objects be used in ordered collection classes.
Greg Claytonb0848c52011-01-08 00:05:12 +0000941
Kate Stoneb9c1b512016-09-06 20:57:50 +0000942bool lldb_private::operator<(const Address &lhs, const Address &rhs) {
943 ModuleSP lhs_module_sp(lhs.GetModule());
944 ModuleSP rhs_module_sp(rhs.GetModule());
945 Module *lhs_module = lhs_module_sp.get();
946 Module *rhs_module = rhs_module_sp.get();
947 if (lhs_module == rhs_module) {
948 // Addresses are in the same module, just compare the file addresses
949 return lhs.GetFileAddress() < rhs.GetFileAddress();
950 } else {
Adrian Prantl05097242018-04-30 16:49:04 +0000951 // The addresses are from different modules, just use the module pointer
952 // value to get consistent ordering
Kate Stoneb9c1b512016-09-06 20:57:50 +0000953 return lhs_module < rhs_module;
954 }
Greg Claytonb0848c52011-01-08 00:05:12 +0000955}
956
Kate Stoneb9c1b512016-09-06 20:57:50 +0000957bool lldb_private::operator>(const Address &lhs, const Address &rhs) {
958 ModuleSP lhs_module_sp(lhs.GetModule());
959 ModuleSP rhs_module_sp(rhs.GetModule());
960 Module *lhs_module = lhs_module_sp.get();
961 Module *rhs_module = rhs_module_sp.get();
962 if (lhs_module == rhs_module) {
963 // Addresses are in the same module, just compare the file addresses
964 return lhs.GetFileAddress() > rhs.GetFileAddress();
965 } else {
Adrian Prantl05097242018-04-30 16:49:04 +0000966 // The addresses are from different modules, just use the module pointer
967 // value to get consistent ordering
Kate Stoneb9c1b512016-09-06 20:57:50 +0000968 return lhs_module > rhs_module;
969 }
Greg Claytonb0848c52011-01-08 00:05:12 +0000970}
971
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000972// The operator == checks for exact equality only (same section, same offset)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000973bool lldb_private::operator==(const Address &a, const Address &rhs) {
974 return a.GetOffset() == rhs.GetOffset() && a.GetSection() == rhs.GetSection();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000975}
Eugene Zelenko896ddd02016-03-02 01:09:03 +0000976
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000977// The operator != checks for exact inequality only (differing section, or
978// different offset)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000979bool lldb_private::operator!=(const Address &a, const Address &rhs) {
980 return a.GetOffset() != rhs.GetOffset() || a.GetSection() != rhs.GetSection();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000981}
982
Kate Stoneb9c1b512016-09-06 20:57:50 +0000983AddressClass Address::GetAddressClass() const {
984 ModuleSP module_sp(GetModule());
985 if (module_sp) {
986 ObjectFile *obj_file = module_sp->GetObjectFile();
987 if (obj_file) {
Aleksandr Urakov8cfb12b2018-11-30 06:56:37 +0000988 // Give the symbol vendor a chance to add to the unified section list
989 // and to symtab from symbol file
990 if (SymbolVendor *vendor = module_sp->GetSymbolVendor())
991 vendor->GetSymtab();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000992 return obj_file->GetAddressClass(GetFileAddress());
Greg Claytonded470d2011-03-19 01:12:21 +0000993 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000994 }
Tatyana Krasnukha04803b32018-06-26 13:06:54 +0000995 return AddressClass::eUnknown;
Greg Claytonded470d2011-03-19 01:12:21 +0000996}
Greg Claytoncd482e32011-05-18 01:58:14 +0000997
Pavel Labathc3c72122017-06-08 13:26:35 +0000998bool Address::SetLoadAddress(lldb::addr_t load_addr, Target *target,
999 bool allow_section_end) {
1000 if (target && target->GetSectionLoadList().ResolveLoadAddress(
1001 load_addr, *this, allow_section_end))
Kate Stoneb9c1b512016-09-06 20:57:50 +00001002 return true;
1003 m_section_wp.reset();
1004 m_offset = load_addr;
1005 return false;
Greg Claytoncd482e32011-05-18 01:58:14 +00001006}