1 //===-- ObjectFile.cpp ----------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Symbol/ObjectFile.h"
10 #include "lldb/Core/Module.h"
11 #include "lldb/Core/ModuleSpec.h"
12 #include "lldb/Core/PluginManager.h"
13 #include "lldb/Core/Section.h"
14 #include "lldb/Symbol/CallFrameInfo.h"
15 #include "lldb/Symbol/ObjectContainer.h"
16 #include "lldb/Symbol/SymbolFile.h"
17 #include "lldb/Target/Process.h"
18 #include "lldb/Target/SectionLoadList.h"
19 #include "lldb/Target/Target.h"
20 #include "lldb/Utility/DataBuffer.h"
21 #include "lldb/Utility/DataBufferHeap.h"
22 #include "lldb/Utility/Log.h"
23 #include "lldb/Utility/Timer.h"
24 #include "lldb/lldb-private.h"
26 #include "llvm/Support/DJB.h"
29 using namespace lldb_private
;
34 CreateObjectFromContainer(const lldb::ModuleSP
&module_sp
, const FileSpec
*file
,
35 lldb::offset_t file_offset
, lldb::offset_t file_size
,
36 DataBufferSP
&data_sp
, lldb::offset_t
&data_offset
) {
37 ObjectContainerCreateInstance callback
;
38 for (uint32_t idx
= 0;
39 (callback
= PluginManager::GetObjectContainerCreateCallbackAtIndex(
42 std::unique_ptr
<ObjectContainer
> object_container_up(callback(
43 module_sp
, data_sp
, data_offset
, file
, file_offset
, file_size
));
44 if (object_container_up
)
45 return object_container_up
->GetObjectFile(file
);
51 ObjectFile::FindPlugin(const lldb::ModuleSP
&module_sp
, const FileSpec
*file
,
52 lldb::offset_t file_offset
, lldb::offset_t file_size
,
53 DataBufferSP
&data_sp
, lldb::offset_t
&data_offset
) {
55 "ObjectFile::FindPlugin (module = %s, file = %p, file_offset = "
56 "0x%8.8" PRIx64
", file_size = 0x%8.8" PRIx64
")",
57 module_sp
->GetFileSpec().GetPath().c_str(),
58 static_cast<const void *>(file
), static_cast<uint64_t>(file_offset
),
59 static_cast<uint64_t>(file_size
));
68 const bool file_exists
= FileSystem::Instance().Exists(*file
);
69 // We have an object name which most likely means we have a .o file in
70 // a static archive (.a file). Try and see if we have a cached archive
71 // first without reading any data first
72 if (file_exists
&& module_sp
->GetObjectName()) {
73 ObjectFileSP object_file_sp
= CreateObjectFromContainer(
74 module_sp
, file
, file_offset
, file_size
, data_sp
, data_offset
);
76 return object_file_sp
;
78 // Ok, we didn't find any containers that have a named object, now lets
79 // read the first 512 bytes from the file so the object file and object
80 // container plug-ins can use these bytes to see if they can parse this
83 data_sp
= FileSystem::Instance().CreateDataBuffer(file
->GetPath(), 512,
89 if (!data_sp
|| data_sp
->GetByteSize() == 0) {
90 // Check for archive file with format "/path/to/archive.a(object.o)"
91 llvm::SmallString
<256> path_with_object
;
92 module_sp
->GetFileSpec().GetPath(path_with_object
);
94 FileSpec archive_file
;
95 ConstString archive_object
;
96 const bool must_exist
= true;
97 if (ObjectFile::SplitArchivePathWithObject(path_with_object
, archive_file
,
98 archive_object
, must_exist
)) {
99 file_size
= FileSystem::Instance().GetByteSize(archive_file
);
101 file
= &archive_file
;
102 module_sp
->SetFileSpecAndObjectName(archive_file
, archive_object
);
103 // Check if this is a object container by iterating through all
104 // object container plugin instances and then trying to get an
105 // object file from the container plugins since we had a name.
107 // ANY data in case there is data cached in the container plug-ins
108 // (like BSD archives caching the contained objects within an
110 ObjectFileSP object_file_sp
= CreateObjectFromContainer(
111 module_sp
, file
, file_offset
, file_size
, data_sp
, data_offset
);
113 return object_file_sp
;
114 // We failed to find any cached object files in the container plug-
115 // ins, so lets read the first 512 bytes and try again below...
116 data_sp
= FileSystem::Instance().CreateDataBuffer(
117 archive_file
.GetPath(), 512, file_offset
);
122 if (data_sp
&& data_sp
->GetByteSize() > 0) {
123 // Check if this is a normal object file by iterating through all
124 // object file plugin instances.
125 ObjectFileCreateInstance callback
;
126 for (uint32_t idx
= 0;
127 (callback
= PluginManager::GetObjectFileCreateCallbackAtIndex(idx
)) !=
130 ObjectFileSP
object_file_sp(callback(module_sp
, data_sp
, data_offset
,
131 file
, file_offset
, file_size
));
132 if (object_file_sp
.get())
133 return object_file_sp
;
136 // Check if this is a object container by iterating through all object
137 // container plugin instances and then trying to get an object file
138 // from the container.
139 ObjectFileSP object_file_sp
= CreateObjectFromContainer(
140 module_sp
, file
, file_offset
, file_size
, data_sp
, data_offset
);
142 return object_file_sp
;
145 // We didn't find it, so clear our shared pointer in case it contains
146 // anything and return an empty shared pointer
150 ObjectFileSP
ObjectFile::FindPlugin(const lldb::ModuleSP
&module_sp
,
151 const ProcessSP
&process_sp
,
152 lldb::addr_t header_addr
,
153 DataBufferSP
&data_sp
) {
154 ObjectFileSP object_file_sp
;
157 LLDB_SCOPED_TIMERF("ObjectFile::FindPlugin (module = "
158 "%s, process = %p, header_addr = "
160 module_sp
->GetFileSpec().GetPath().c_str(),
161 static_cast<void *>(process_sp
.get()), header_addr
);
164 // Check if this is a normal object file by iterating through all object
165 // file plugin instances.
166 ObjectFileCreateMemoryInstance create_callback
;
169 PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(idx
)) !=
172 object_file_sp
.reset(
173 create_callback(module_sp
, data_sp
, process_sp
, header_addr
));
174 if (object_file_sp
.get())
175 return object_file_sp
;
179 // We didn't find it, so clear our shared pointer in case it contains
180 // anything and return an empty shared pointer
181 object_file_sp
.reset();
182 return object_file_sp
;
185 size_t ObjectFile::GetModuleSpecifications(const FileSpec
&file
,
186 lldb::offset_t file_offset
,
187 lldb::offset_t file_size
,
188 ModuleSpecList
&specs
,
189 DataBufferSP data_sp
) {
191 data_sp
= FileSystem::Instance().CreateDataBuffer(file
.GetPath(), 512,
194 if (file_size
== 0) {
195 const lldb::offset_t actual_file_size
=
196 FileSystem::Instance().GetByteSize(file
);
197 if (actual_file_size
> file_offset
)
198 file_size
= actual_file_size
- file_offset
;
200 return ObjectFile::GetModuleSpecifications(file
, // file spec
201 data_sp
, // data bytes
203 file_offset
, // file offset
204 file_size
, // file length
210 size_t ObjectFile::GetModuleSpecifications(
211 const lldb_private::FileSpec
&file
, lldb::DataBufferSP
&data_sp
,
212 lldb::offset_t data_offset
, lldb::offset_t file_offset
,
213 lldb::offset_t file_size
, lldb_private::ModuleSpecList
&specs
) {
214 const size_t initial_count
= specs
.GetSize();
215 ObjectFileGetModuleSpecifications callback
;
217 // Try the ObjectFile plug-ins
220 PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex(
223 if (callback(file
, data_sp
, data_offset
, file_offset
, file_size
, specs
) > 0)
224 return specs
.GetSize() - initial_count
;
227 // Try the ObjectContainer plug-ins
229 (callback
= PluginManager::
230 GetObjectContainerGetModuleSpecificationsCallbackAtIndex(i
)) !=
233 if (callback(file
, data_sp
, data_offset
, file_offset
, file_size
, specs
) > 0)
234 return specs
.GetSize() - initial_count
;
239 ObjectFile::ObjectFile(const lldb::ModuleSP
&module_sp
,
240 const FileSpec
*file_spec_ptr
,
241 lldb::offset_t file_offset
, lldb::offset_t length
,
242 const lldb::DataBufferSP
&data_sp
,
243 lldb::offset_t data_offset
)
244 : ModuleChild(module_sp
),
245 m_file(), // This file could be different from the original module's file
246 m_type(eTypeInvalid
), m_strata(eStrataInvalid
),
247 m_file_offset(file_offset
), m_length(length
), m_data(), m_process_wp(),
248 m_memory_addr(LLDB_INVALID_ADDRESS
), m_sections_up(), m_symtab_up(),
249 m_symtab_once_up(new llvm::once_flag()) {
251 m_file
= *file_spec_ptr
;
253 m_data
.SetData(data_sp
, data_offset
, length
);
254 Log
*log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT
));
256 "%p ObjectFile::ObjectFile() module = %p (%s), file = %s, "
257 "file_offset = 0x%8.8" PRIx64
", size = %" PRIu64
,
258 static_cast<void *>(this), static_cast<void *>(module_sp
.get()),
259 module_sp
->GetSpecificationDescription().c_str(),
260 m_file
? m_file
.GetPath().c_str() : "<NULL>", m_file_offset
,
264 ObjectFile::ObjectFile(const lldb::ModuleSP
&module_sp
,
265 const ProcessSP
&process_sp
, lldb::addr_t header_addr
,
266 DataBufferSP
&header_data_sp
)
267 : ModuleChild(module_sp
), m_file(), m_type(eTypeInvalid
),
268 m_strata(eStrataInvalid
), m_file_offset(0), m_length(0), m_data(),
269 m_process_wp(process_sp
), m_memory_addr(header_addr
), m_sections_up(),
270 m_symtab_up(), m_symtab_once_up(new llvm::once_flag()) {
272 m_data
.SetData(header_data_sp
, 0, header_data_sp
->GetByteSize());
273 Log
*log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT
));
275 "%p ObjectFile::ObjectFile() module = %p (%s), process = %p, "
276 "header_addr = 0x%" PRIx64
,
277 static_cast<void *>(this), static_cast<void *>(module_sp
.get()),
278 module_sp
->GetSpecificationDescription().c_str(),
279 static_cast<void *>(process_sp
.get()), m_memory_addr
);
282 ObjectFile::~ObjectFile() {
283 Log
*log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT
));
284 LLDB_LOGF(log
, "%p ObjectFile::~ObjectFile ()\n", static_cast<void *>(this));
287 bool ObjectFile::SetModulesArchitecture(const ArchSpec
&new_arch
) {
288 ModuleSP
module_sp(GetModule());
290 return module_sp
->SetArchitecture(new_arch
);
294 AddressClass
ObjectFile::GetAddressClass(addr_t file_addr
) {
295 Symtab
*symtab
= GetSymtab();
297 Symbol
*symbol
= symtab
->FindSymbolContainingFileAddress(file_addr
);
299 if (symbol
->ValueIsAddress()) {
300 const SectionSP
section_sp(symbol
->GetAddressRef().GetSection());
302 const SectionType section_type
= section_sp
->GetType();
303 switch (section_type
) {
304 case eSectionTypeInvalid
:
305 return AddressClass::eUnknown
;
306 case eSectionTypeCode
:
307 return AddressClass::eCode
;
308 case eSectionTypeContainer
:
309 return AddressClass::eUnknown
;
310 case eSectionTypeData
:
311 case eSectionTypeDataCString
:
312 case eSectionTypeDataCStringPointers
:
313 case eSectionTypeDataSymbolAddress
:
314 case eSectionTypeData4
:
315 case eSectionTypeData8
:
316 case eSectionTypeData16
:
317 case eSectionTypeDataPointers
:
318 case eSectionTypeZeroFill
:
319 case eSectionTypeDataObjCMessageRefs
:
320 case eSectionTypeDataObjCCFStrings
:
321 case eSectionTypeGoSymtab
:
322 return AddressClass::eData
;
323 case eSectionTypeDebug
:
324 case eSectionTypeDWARFDebugAbbrev
:
325 case eSectionTypeDWARFDebugAbbrevDwo
:
326 case eSectionTypeDWARFDebugAddr
:
327 case eSectionTypeDWARFDebugAranges
:
328 case eSectionTypeDWARFDebugCuIndex
:
329 case eSectionTypeDWARFDebugFrame
:
330 case eSectionTypeDWARFDebugInfo
:
331 case eSectionTypeDWARFDebugInfoDwo
:
332 case eSectionTypeDWARFDebugLine
:
333 case eSectionTypeDWARFDebugLineStr
:
334 case eSectionTypeDWARFDebugLoc
:
335 case eSectionTypeDWARFDebugLocDwo
:
336 case eSectionTypeDWARFDebugLocLists
:
337 case eSectionTypeDWARFDebugLocListsDwo
:
338 case eSectionTypeDWARFDebugMacInfo
:
339 case eSectionTypeDWARFDebugMacro
:
340 case eSectionTypeDWARFDebugNames
:
341 case eSectionTypeDWARFDebugPubNames
:
342 case eSectionTypeDWARFDebugPubTypes
:
343 case eSectionTypeDWARFDebugRanges
:
344 case eSectionTypeDWARFDebugRngLists
:
345 case eSectionTypeDWARFDebugRngListsDwo
:
346 case eSectionTypeDWARFDebugStr
:
347 case eSectionTypeDWARFDebugStrDwo
:
348 case eSectionTypeDWARFDebugStrOffsets
:
349 case eSectionTypeDWARFDebugStrOffsetsDwo
:
350 case eSectionTypeDWARFDebugTuIndex
:
351 case eSectionTypeDWARFDebugTypes
:
352 case eSectionTypeDWARFDebugTypesDwo
:
353 case eSectionTypeDWARFAppleNames
:
354 case eSectionTypeDWARFAppleTypes
:
355 case eSectionTypeDWARFAppleNamespaces
:
356 case eSectionTypeDWARFAppleObjC
:
357 case eSectionTypeDWARFGNUDebugAltLink
:
358 return AddressClass::eDebug
;
359 case eSectionTypeEHFrame
:
360 case eSectionTypeARMexidx
:
361 case eSectionTypeARMextab
:
362 case eSectionTypeCompactUnwind
:
363 return AddressClass::eRuntime
;
364 case eSectionTypeELFSymbolTable
:
365 case eSectionTypeELFDynamicSymbols
:
366 case eSectionTypeELFRelocationEntries
:
367 case eSectionTypeELFDynamicLinkInfo
:
368 case eSectionTypeOther
:
369 return AddressClass::eUnknown
;
370 case eSectionTypeAbsoluteAddress
:
371 // In case of absolute sections decide the address class based on
372 // the symbol type because the section type isn't specify if it is
373 // a code or a data section.
379 const SymbolType symbol_type
= symbol
->GetType();
380 switch (symbol_type
) {
382 return AddressClass::eUnknown
;
383 case eSymbolTypeAbsolute
:
384 return AddressClass::eUnknown
;
385 case eSymbolTypeCode
:
386 return AddressClass::eCode
;
387 case eSymbolTypeTrampoline
:
388 return AddressClass::eCode
;
389 case eSymbolTypeResolver
:
390 return AddressClass::eCode
;
391 case eSymbolTypeData
:
392 return AddressClass::eData
;
393 case eSymbolTypeRuntime
:
394 return AddressClass::eRuntime
;
395 case eSymbolTypeException
:
396 return AddressClass::eRuntime
;
397 case eSymbolTypeSourceFile
:
398 return AddressClass::eDebug
;
399 case eSymbolTypeHeaderFile
:
400 return AddressClass::eDebug
;
401 case eSymbolTypeObjectFile
:
402 return AddressClass::eDebug
;
403 case eSymbolTypeCommonBlock
:
404 return AddressClass::eDebug
;
405 case eSymbolTypeBlock
:
406 return AddressClass::eDebug
;
407 case eSymbolTypeLocal
:
408 return AddressClass::eData
;
409 case eSymbolTypeParam
:
410 return AddressClass::eData
;
411 case eSymbolTypeVariable
:
412 return AddressClass::eData
;
413 case eSymbolTypeVariableType
:
414 return AddressClass::eDebug
;
415 case eSymbolTypeLineEntry
:
416 return AddressClass::eDebug
;
417 case eSymbolTypeLineHeader
:
418 return AddressClass::eDebug
;
419 case eSymbolTypeScopeBegin
:
420 return AddressClass::eDebug
;
421 case eSymbolTypeScopeEnd
:
422 return AddressClass::eDebug
;
423 case eSymbolTypeAdditional
:
424 return AddressClass::eUnknown
;
425 case eSymbolTypeCompiler
:
426 return AddressClass::eDebug
;
427 case eSymbolTypeInstrumentation
:
428 return AddressClass::eDebug
;
429 case eSymbolTypeUndefined
:
430 return AddressClass::eUnknown
;
431 case eSymbolTypeObjCClass
:
432 return AddressClass::eRuntime
;
433 case eSymbolTypeObjCMetaClass
:
434 return AddressClass::eRuntime
;
435 case eSymbolTypeObjCIVar
:
436 return AddressClass::eRuntime
;
437 case eSymbolTypeReExported
:
438 return AddressClass::eRuntime
;
442 return AddressClass::eUnknown
;
445 DataBufferSP
ObjectFile::ReadMemory(const ProcessSP
&process_sp
,
446 lldb::addr_t addr
, size_t byte_size
) {
447 DataBufferSP data_sp
;
449 std::unique_ptr
<DataBufferHeap
> data_up(new DataBufferHeap(byte_size
, 0));
451 const size_t bytes_read
= process_sp
->ReadMemory(
452 addr
, data_up
->GetBytes(), data_up
->GetByteSize(), error
);
453 if (bytes_read
== byte_size
)
454 data_sp
.reset(data_up
.release());
459 size_t ObjectFile::GetData(lldb::offset_t offset
, size_t length
,
460 DataExtractor
&data
) const {
461 // The entire file has already been mmap'ed into m_data, so just copy from
462 // there as the back mmap buffer will be shared with shared pointers.
463 return data
.SetData(m_data
, offset
, length
);
466 size_t ObjectFile::CopyData(lldb::offset_t offset
, size_t length
,
468 // The entire file has already been mmap'ed into m_data, so just copy from
469 // there Note that the data remains in target byte order.
470 return m_data
.CopyData(offset
, length
, dst
);
473 size_t ObjectFile::ReadSectionData(Section
*section
,
474 lldb::offset_t section_offset
, void *dst
,
477 section_offset
*= section
->GetTargetByteSize();
479 // If some other objectfile owns this data, pass this to them.
480 if (section
->GetObjectFile() != this)
481 return section
->GetObjectFile()->ReadSectionData(section
, section_offset
,
484 if (!section
->IsRelocated())
485 RelocateSection(section
);
488 ProcessSP
process_sp(m_process_wp
.lock());
491 const addr_t base_load_addr
=
492 section
->GetLoadBaseAddress(&process_sp
->GetTarget());
493 if (base_load_addr
!= LLDB_INVALID_ADDRESS
)
494 return process_sp
->ReadMemory(base_load_addr
+ section_offset
, dst
,
498 const lldb::offset_t section_file_size
= section
->GetFileSize();
499 if (section_offset
< section_file_size
) {
500 const size_t section_bytes_left
= section_file_size
- section_offset
;
501 size_t section_dst_len
= dst_len
;
502 if (section_dst_len
> section_bytes_left
)
503 section_dst_len
= section_bytes_left
;
504 return CopyData(section
->GetFileOffset() + section_offset
,
505 section_dst_len
, dst
);
507 if (section
->GetType() == eSectionTypeZeroFill
) {
508 const uint64_t section_size
= section
->GetByteSize();
509 const uint64_t section_bytes_left
= section_size
- section_offset
;
510 uint64_t section_dst_len
= dst_len
;
511 if (section_dst_len
> section_bytes_left
)
512 section_dst_len
= section_bytes_left
;
513 memset(dst
, 0, section_dst_len
);
514 return section_dst_len
;
521 // Get the section data the file on disk
522 size_t ObjectFile::ReadSectionData(Section
*section
,
523 DataExtractor
§ion_data
) {
524 // If some other objectfile owns this data, pass this to them.
525 if (section
->GetObjectFile() != this)
526 return section
->GetObjectFile()->ReadSectionData(section
, section_data
);
528 if (!section
->IsRelocated())
529 RelocateSection(section
);
532 ProcessSP
process_sp(m_process_wp
.lock());
534 const addr_t base_load_addr
=
535 section
->GetLoadBaseAddress(&process_sp
->GetTarget());
536 if (base_load_addr
!= LLDB_INVALID_ADDRESS
) {
537 DataBufferSP
data_sp(
538 ReadMemory(process_sp
, base_load_addr
, section
->GetByteSize()));
540 section_data
.SetData(data_sp
, 0, data_sp
->GetByteSize());
541 section_data
.SetByteOrder(process_sp
->GetByteOrder());
542 section_data
.SetAddressByteSize(process_sp
->GetAddressByteSize());
543 return section_data
.GetByteSize();
549 // The object file now contains a full mmap'ed copy of the object file
550 // data, so just use this
551 return GetData(section
->GetFileOffset(), section
->GetFileSize(),
555 bool ObjectFile::SplitArchivePathWithObject(llvm::StringRef path_with_object
,
556 FileSpec
&archive_file
,
557 ConstString
&archive_object
,
559 size_t len
= path_with_object
.size();
560 if (len
< 2 || path_with_object
.back() != ')')
562 llvm::StringRef archive
= path_with_object
.substr(0, path_with_object
.rfind('('));
565 llvm::StringRef object
= path_with_object
.substr(archive
.size() + 1).drop_back();
566 archive_file
.SetFile(archive
, FileSpec::Style::native
);
567 if (must_exist
&& !FileSystem::Instance().Exists(archive_file
))
569 archive_object
.SetString(object
);
573 void ObjectFile::ClearSymtab() {
574 ModuleSP
module_sp(GetModule());
576 Log
*log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT
));
577 LLDB_LOGF(log
, "%p ObjectFile::ClearSymtab () symtab = %p",
578 static_cast<void *>(this),
579 static_cast<void *>(m_symtab_up
.get()));
580 // Since we need to clear the symbol table, we need a new llvm::once_flag
581 // instance so we can safely create another symbol table
582 m_symtab_once_up
.reset(new llvm::once_flag());
587 SectionList
*ObjectFile::GetSectionList(bool update_module_section_list
) {
588 if (m_sections_up
== nullptr) {
589 if (update_module_section_list
) {
590 ModuleSP
module_sp(GetModule());
592 std::lock_guard
<std::recursive_mutex
> guard(module_sp
->GetMutex());
593 CreateSections(*module_sp
->GetUnifiedSectionList());
596 SectionList unified_section_list
;
597 CreateSections(unified_section_list
);
600 return m_sections_up
.get();
604 ObjectFile::GetSymbolTypeFromName(llvm::StringRef name
,
605 lldb::SymbolType symbol_type_hint
) {
607 if (name
.startswith("_OBJC_")) {
609 if (name
.startswith("_OBJC_CLASS_$_"))
610 return lldb::eSymbolTypeObjCClass
;
611 if (name
.startswith("_OBJC_METACLASS_$_"))
612 return lldb::eSymbolTypeObjCMetaClass
;
613 if (name
.startswith("_OBJC_IVAR_$_"))
614 return lldb::eSymbolTypeObjCIVar
;
615 } else if (name
.startswith(".objc_class_name_")) {
617 return lldb::eSymbolTypeObjCClass
;
620 return symbol_type_hint
;
623 std::vector
<ObjectFile::LoadableData
>
624 ObjectFile::GetLoadableData(Target
&target
) {
625 std::vector
<LoadableData
> loadables
;
626 SectionList
*section_list
= GetSectionList();
629 // Create a list of loadable data from loadable sections
630 size_t section_count
= section_list
->GetNumSections(0);
631 for (size_t i
= 0; i
< section_count
; ++i
) {
632 LoadableData loadable
;
633 SectionSP section_sp
= section_list
->GetSectionAtIndex(i
);
635 target
.GetSectionLoadList().GetSectionLoadAddress(section_sp
);
636 if (loadable
.Dest
== LLDB_INVALID_ADDRESS
)
638 // We can skip sections like bss
639 if (section_sp
->GetFileSize() == 0)
641 DataExtractor section_data
;
642 section_sp
->GetSectionData(section_data
);
643 loadable
.Contents
= llvm::ArrayRef
<uint8_t>(section_data
.GetDataStart(),
644 section_data
.GetByteSize());
645 loadables
.push_back(loadable
);
650 std::unique_ptr
<CallFrameInfo
> ObjectFile::CreateCallFrameInfo() {
654 void ObjectFile::RelocateSection(lldb_private::Section
*section
)
658 DataBufferSP
ObjectFile::MapFileData(const FileSpec
&file
, uint64_t Size
,
660 return FileSystem::Instance().CreateDataBuffer(file
.GetPath(), Size
, Offset
);
663 void llvm::format_provider
<ObjectFile::Type
>::format(
664 const ObjectFile::Type
&type
, raw_ostream
&OS
, StringRef Style
) {
666 case ObjectFile::eTypeInvalid
:
669 case ObjectFile::eTypeCoreFile
:
672 case ObjectFile::eTypeExecutable
:
675 case ObjectFile::eTypeDebugInfo
:
678 case ObjectFile::eTypeDynamicLinker
:
679 OS
<< "dynamic linker";
681 case ObjectFile::eTypeObjectFile
:
684 case ObjectFile::eTypeSharedLibrary
:
685 OS
<< "shared library";
687 case ObjectFile::eTypeStubLibrary
:
688 OS
<< "stub library";
690 case ObjectFile::eTypeJIT
:
693 case ObjectFile::eTypeUnknown
:
699 void llvm::format_provider
<ObjectFile::Strata
>::format(
700 const ObjectFile::Strata
&strata
, raw_ostream
&OS
, StringRef Style
) {
702 case ObjectFile::eStrataInvalid
:
705 case ObjectFile::eStrataUnknown
:
708 case ObjectFile::eStrataUser
:
711 case ObjectFile::eStrataKernel
:
714 case ObjectFile::eStrataRawImage
:
717 case ObjectFile::eStrataJIT
:
724 Symtab
*ObjectFile::GetSymtab() {
725 ModuleSP
module_sp(GetModule());
727 // We can't take the module lock in ObjectFile::GetSymtab() or we can
728 // deadlock in DWARF indexing when any file asks for the symbol table from
729 // an object file. This currently happens in the preloading of symbols in
730 // SymbolFileDWARF::PreloadSymbols() because the main thread will take the
731 // module lock, and then threads will be spun up to index the DWARF and
732 // any of those threads might end up trying to relocate items in the DWARF
733 // sections which causes ObjectFile::GetSectionData(...) to relocate section
734 // data which requires the symbol table.
736 // So to work around this, we create the symbol table one time using
737 // llvm::once_flag, lock it, and then set the unique pointer. Any other
738 // thread that gets ahold of the symbol table before parsing is done, will
739 // not be able to access the symbol table contents since all APIs in Symtab
740 // are protected by a mutex in the Symtab object itself.
741 llvm::call_once(*m_symtab_once_up
, [&]() {
742 Symtab
*symtab
= new Symtab(this);
743 std::lock_guard
<std::recursive_mutex
> symtab_guard(symtab
->GetMutex());
744 m_symtab_up
.reset(symtab
);
745 if (!m_symtab_up
->LoadFromCache()) {
746 ElapsedTime
elapsed(module_sp
->GetSymtabParseTime());
747 ParseSymtab(*m_symtab_up
);
748 m_symtab_up
->Finalize();
752 return m_symtab_up
.get();
755 uint32_t ObjectFile::GetCacheHash() {
757 return *m_cache_hash
;
759 strm
.Format("{0}-{1}-{2}", m_file
, GetType(), GetStrata());
760 m_cache_hash
= llvm::djbHash(strm
.GetString());
761 return *m_cache_hash
;