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/LLDBLog.h"
23 #include "lldb/Utility/Log.h"
24 #include "lldb/Utility/Timer.h"
25 #include "lldb/lldb-private.h"
27 #include "llvm/Support/DJB.h"
30 using namespace lldb_private
;
33 size_t ObjectFile::g_initial_bytes_to_read
= 512;
36 CreateObjectFromContainer(const lldb::ModuleSP
&module_sp
, const FileSpec
*file
,
37 lldb::offset_t file_offset
, lldb::offset_t file_size
,
38 DataBufferSP data_sp
, lldb::offset_t
&data_offset
) {
39 ObjectContainerCreateInstance callback
;
40 for (uint32_t idx
= 0;
41 (callback
= PluginManager::GetObjectContainerCreateCallbackAtIndex(
44 std::unique_ptr
<ObjectContainer
> object_container_up(callback(
45 module_sp
, data_sp
, data_offset
, file
, file_offset
, file_size
));
46 if (object_container_up
)
47 return object_container_up
->GetObjectFile(file
);
53 ObjectFile::FindPlugin(const lldb::ModuleSP
&module_sp
, const FileSpec
*file
,
54 lldb::offset_t file_offset
, lldb::offset_t file_size
,
55 DataBufferSP
&data_sp
, lldb::offset_t
&data_offset
) {
57 "ObjectFile::FindPlugin (module = %s, file = %p, file_offset = "
58 "0x%8.8" PRIx64
", file_size = 0x%8.8" PRIx64
")",
59 module_sp
->GetFileSpec().GetPath().c_str(),
60 static_cast<const void *>(file
), static_cast<uint64_t>(file_offset
),
61 static_cast<uint64_t>(file_size
));
70 const bool file_exists
= FileSystem::Instance().Exists(*file
);
71 // We have an object name which most likely means we have a .o file in
72 // a static archive (.a file). Try and see if we have a cached archive
73 // first without reading any data first
74 if (file_exists
&& module_sp
->GetObjectName()) {
75 ObjectFileSP object_file_sp
= CreateObjectFromContainer(
76 module_sp
, file
, file_offset
, file_size
, data_sp
, data_offset
);
78 return object_file_sp
;
80 // Ok, we didn't find any containers that have a named object, now lets
81 // read the first 512 bytes from the file so the object file and object
82 // container plug-ins can use these bytes to see if they can parse this
85 data_sp
= FileSystem::Instance().CreateDataBuffer(
86 file
->GetPath(), g_initial_bytes_to_read
, file_offset
);
91 if (!data_sp
|| data_sp
->GetByteSize() == 0) {
92 // Check for archive file with format "/path/to/archive.a(object.o)"
93 llvm::SmallString
<256> path_with_object
;
94 module_sp
->GetFileSpec().GetPath(path_with_object
);
96 FileSpec archive_file
;
97 ConstString archive_object
;
98 const bool must_exist
= true;
99 if (ObjectFile::SplitArchivePathWithObject(path_with_object
, archive_file
,
100 archive_object
, must_exist
)) {
101 file_size
= FileSystem::Instance().GetByteSize(archive_file
);
103 file
= &archive_file
;
104 module_sp
->SetFileSpecAndObjectName(archive_file
, archive_object
);
105 // Check if this is a object container by iterating through all
106 // object container plugin instances and then trying to get an
107 // object file from the container plugins since we had a name.
109 // ANY data in case there is data cached in the container plug-ins
110 // (like BSD archives caching the contained objects within an
112 ObjectFileSP object_file_sp
= CreateObjectFromContainer(
113 module_sp
, file
, file_offset
, file_size
, data_sp
, data_offset
);
115 return object_file_sp
;
116 // We failed to find any cached object files in the container plug-
117 // ins, so lets read the first 512 bytes and try again below...
118 data_sp
= FileSystem::Instance().CreateDataBuffer(
119 archive_file
.GetPath(), g_initial_bytes_to_read
, file_offset
);
124 if (data_sp
&& data_sp
->GetByteSize() > 0) {
125 // Check if this is a normal object file by iterating through all
126 // object file plugin instances.
127 ObjectFileCreateInstance callback
;
128 for (uint32_t idx
= 0;
129 (callback
= PluginManager::GetObjectFileCreateCallbackAtIndex(idx
)) !=
132 ObjectFileSP
object_file_sp(callback(module_sp
, data_sp
, data_offset
,
133 file
, file_offset
, file_size
));
134 if (object_file_sp
.get())
135 return object_file_sp
;
138 // Check if this is a object container by iterating through all object
139 // container plugin instances and then trying to get an object file
140 // from the container.
141 ObjectFileSP object_file_sp
= CreateObjectFromContainer(
142 module_sp
, file
, file_offset
, file_size
, data_sp
, data_offset
);
144 return object_file_sp
;
147 // We didn't find it, so clear our shared pointer in case it contains
148 // anything and return an empty shared pointer
152 ObjectFileSP
ObjectFile::FindPlugin(const lldb::ModuleSP
&module_sp
,
153 const ProcessSP
&process_sp
,
154 lldb::addr_t header_addr
,
155 WritableDataBufferSP data_sp
) {
156 ObjectFileSP object_file_sp
;
159 LLDB_SCOPED_TIMERF("ObjectFile::FindPlugin (module = "
160 "%s, process = %p, header_addr = "
162 module_sp
->GetFileSpec().GetPath().c_str(),
163 static_cast<void *>(process_sp
.get()), header_addr
);
166 // Check if this is a normal object file by iterating through all object
167 // file plugin instances.
168 ObjectFileCreateMemoryInstance create_callback
;
171 PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(idx
)) !=
174 object_file_sp
.reset(
175 create_callback(module_sp
, data_sp
, process_sp
, header_addr
));
176 if (object_file_sp
.get())
177 return object_file_sp
;
181 // We didn't find it, so clear our shared pointer in case it contains
182 // anything and return an empty shared pointer
183 object_file_sp
.reset();
184 return object_file_sp
;
187 size_t ObjectFile::GetModuleSpecifications(const FileSpec
&file
,
188 lldb::offset_t file_offset
,
189 lldb::offset_t file_size
,
190 ModuleSpecList
&specs
,
191 DataBufferSP data_sp
) {
193 data_sp
= FileSystem::Instance().CreateDataBuffer(
194 file
.GetPath(), g_initial_bytes_to_read
, file_offset
);
196 if (file_size
== 0) {
197 const lldb::offset_t actual_file_size
=
198 FileSystem::Instance().GetByteSize(file
);
199 if (actual_file_size
> file_offset
)
200 file_size
= actual_file_size
- file_offset
;
202 return ObjectFile::GetModuleSpecifications(file
, // file spec
203 data_sp
, // data bytes
205 file_offset
, // file offset
206 file_size
, // file length
212 size_t ObjectFile::GetModuleSpecifications(
213 const lldb_private::FileSpec
&file
, lldb::DataBufferSP
&data_sp
,
214 lldb::offset_t data_offset
, lldb::offset_t file_offset
,
215 lldb::offset_t file_size
, lldb_private::ModuleSpecList
&specs
) {
216 const size_t initial_count
= specs
.GetSize();
217 ObjectFileGetModuleSpecifications callback
;
219 // Try the ObjectFile plug-ins
222 PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex(
225 if (callback(file
, data_sp
, data_offset
, file_offset
, file_size
, specs
) > 0)
226 return specs
.GetSize() - initial_count
;
229 // Try the ObjectContainer plug-ins
231 (callback
= PluginManager::
232 GetObjectContainerGetModuleSpecificationsCallbackAtIndex(i
)) !=
235 if (callback(file
, data_sp
, data_offset
, file_offset
, file_size
, specs
) > 0)
236 return specs
.GetSize() - initial_count
;
241 ObjectFile::ObjectFile(const lldb::ModuleSP
&module_sp
,
242 const FileSpec
*file_spec_ptr
,
243 lldb::offset_t file_offset
, lldb::offset_t length
,
244 lldb::DataBufferSP data_sp
, lldb::offset_t data_offset
)
245 : ModuleChild(module_sp
),
246 m_file(), // This file could be different from the original module's file
247 m_type(eTypeInvalid
), m_strata(eStrataInvalid
),
248 m_file_offset(file_offset
), m_length(length
), m_data(), m_process_wp(),
249 m_memory_addr(LLDB_INVALID_ADDRESS
), m_sections_up(), m_symtab_up(),
250 m_symtab_once_up(new llvm::once_flag()) {
252 m_file
= *file_spec_ptr
;
254 m_data
.SetData(data_sp
, data_offset
, length
);
255 Log
*log
= GetLog(LLDBLog::Object
);
257 "%p ObjectFile::ObjectFile() module = %p (%s), file = %s, "
258 "file_offset = 0x%8.8" PRIx64
", size = %" PRIu64
,
259 static_cast<void *>(this), static_cast<void *>(module_sp
.get()),
260 module_sp
->GetSpecificationDescription().c_str(),
261 m_file
? m_file
.GetPath().c_str() : "<NULL>", m_file_offset
,
265 ObjectFile::ObjectFile(const lldb::ModuleSP
&module_sp
,
266 const ProcessSP
&process_sp
, lldb::addr_t header_addr
,
267 DataBufferSP header_data_sp
)
268 : ModuleChild(module_sp
), m_file(), m_type(eTypeInvalid
),
269 m_strata(eStrataInvalid
), m_file_offset(0), m_length(0), m_data(),
270 m_process_wp(process_sp
), m_memory_addr(header_addr
), m_sections_up(),
271 m_symtab_up(), m_symtab_once_up(new llvm::once_flag()) {
273 m_data
.SetData(header_data_sp
, 0, header_data_sp
->GetByteSize());
274 Log
*log
= GetLog(LLDBLog::Object
);
276 "%p ObjectFile::ObjectFile() module = %p (%s), process = %p, "
277 "header_addr = 0x%" PRIx64
,
278 static_cast<void *>(this), static_cast<void *>(module_sp
.get()),
279 module_sp
->GetSpecificationDescription().c_str(),
280 static_cast<void *>(process_sp
.get()), m_memory_addr
);
283 ObjectFile::~ObjectFile() {
284 Log
*log
= GetLog(LLDBLog::Object
);
285 LLDB_LOGF(log
, "%p ObjectFile::~ObjectFile ()\n", static_cast<void *>(this));
288 bool ObjectFile::SetModulesArchitecture(const ArchSpec
&new_arch
) {
289 ModuleSP
module_sp(GetModule());
291 return module_sp
->SetArchitecture(new_arch
);
295 AddressClass
ObjectFile::GetAddressClass(addr_t file_addr
) {
296 Symtab
*symtab
= GetSymtab();
298 Symbol
*symbol
= symtab
->FindSymbolContainingFileAddress(file_addr
);
300 if (symbol
->ValueIsAddress()) {
301 const SectionSP
section_sp(symbol
->GetAddressRef().GetSection());
303 const SectionType section_type
= section_sp
->GetType();
304 switch (section_type
) {
305 case eSectionTypeInvalid
:
306 return AddressClass::eUnknown
;
307 case eSectionTypeCode
:
308 return AddressClass::eCode
;
309 case eSectionTypeContainer
:
310 return AddressClass::eUnknown
;
311 case eSectionTypeData
:
312 case eSectionTypeDataCString
:
313 case eSectionTypeDataCStringPointers
:
314 case eSectionTypeDataSymbolAddress
:
315 case eSectionTypeData4
:
316 case eSectionTypeData8
:
317 case eSectionTypeData16
:
318 case eSectionTypeDataPointers
:
319 case eSectionTypeZeroFill
:
320 case eSectionTypeDataObjCMessageRefs
:
321 case eSectionTypeDataObjCCFStrings
:
322 case eSectionTypeGoSymtab
:
323 return AddressClass::eData
;
324 case eSectionTypeDebug
:
325 case eSectionTypeDWARFDebugAbbrev
:
326 case eSectionTypeDWARFDebugAbbrevDwo
:
327 case eSectionTypeDWARFDebugAddr
:
328 case eSectionTypeDWARFDebugAranges
:
329 case eSectionTypeDWARFDebugCuIndex
:
330 case eSectionTypeDWARFDebugFrame
:
331 case eSectionTypeDWARFDebugInfo
:
332 case eSectionTypeDWARFDebugInfoDwo
:
333 case eSectionTypeDWARFDebugLine
:
334 case eSectionTypeDWARFDebugLineStr
:
335 case eSectionTypeDWARFDebugLoc
:
336 case eSectionTypeDWARFDebugLocDwo
:
337 case eSectionTypeDWARFDebugLocLists
:
338 case eSectionTypeDWARFDebugLocListsDwo
:
339 case eSectionTypeDWARFDebugMacInfo
:
340 case eSectionTypeDWARFDebugMacro
:
341 case eSectionTypeDWARFDebugNames
:
342 case eSectionTypeDWARFDebugPubNames
:
343 case eSectionTypeDWARFDebugPubTypes
:
344 case eSectionTypeDWARFDebugRanges
:
345 case eSectionTypeDWARFDebugRngLists
:
346 case eSectionTypeDWARFDebugRngListsDwo
:
347 case eSectionTypeDWARFDebugStr
:
348 case eSectionTypeDWARFDebugStrDwo
:
349 case eSectionTypeDWARFDebugStrOffsets
:
350 case eSectionTypeDWARFDebugStrOffsetsDwo
:
351 case eSectionTypeDWARFDebugTuIndex
:
352 case eSectionTypeDWARFDebugTypes
:
353 case eSectionTypeDWARFDebugTypesDwo
:
354 case eSectionTypeDWARFAppleNames
:
355 case eSectionTypeDWARFAppleTypes
:
356 case eSectionTypeDWARFAppleNamespaces
:
357 case eSectionTypeDWARFAppleObjC
:
358 case eSectionTypeDWARFGNUDebugAltLink
:
359 case eSectionTypeCTF
:
360 case eSectionTypeSwiftModules
:
361 return AddressClass::eDebug
;
362 case eSectionTypeEHFrame
:
363 case eSectionTypeARMexidx
:
364 case eSectionTypeARMextab
:
365 case eSectionTypeCompactUnwind
:
366 return AddressClass::eRuntime
;
367 case eSectionTypeELFSymbolTable
:
368 case eSectionTypeELFDynamicSymbols
:
369 case eSectionTypeELFRelocationEntries
:
370 case eSectionTypeELFDynamicLinkInfo
:
371 case eSectionTypeOther
:
372 return AddressClass::eUnknown
;
373 case eSectionTypeAbsoluteAddress
:
374 // In case of absolute sections decide the address class based on
375 // the symbol type because the section type isn't specify if it is
376 // a code or a data section.
382 const SymbolType symbol_type
= symbol
->GetType();
383 switch (symbol_type
) {
385 return AddressClass::eUnknown
;
386 case eSymbolTypeAbsolute
:
387 return AddressClass::eUnknown
;
388 case eSymbolTypeCode
:
389 return AddressClass::eCode
;
390 case eSymbolTypeTrampoline
:
391 return AddressClass::eCode
;
392 case eSymbolTypeResolver
:
393 return AddressClass::eCode
;
394 case eSymbolTypeData
:
395 return AddressClass::eData
;
396 case eSymbolTypeRuntime
:
397 return AddressClass::eRuntime
;
398 case eSymbolTypeException
:
399 return AddressClass::eRuntime
;
400 case eSymbolTypeSourceFile
:
401 return AddressClass::eDebug
;
402 case eSymbolTypeHeaderFile
:
403 return AddressClass::eDebug
;
404 case eSymbolTypeObjectFile
:
405 return AddressClass::eDebug
;
406 case eSymbolTypeCommonBlock
:
407 return AddressClass::eDebug
;
408 case eSymbolTypeBlock
:
409 return AddressClass::eDebug
;
410 case eSymbolTypeLocal
:
411 return AddressClass::eData
;
412 case eSymbolTypeParam
:
413 return AddressClass::eData
;
414 case eSymbolTypeVariable
:
415 return AddressClass::eData
;
416 case eSymbolTypeVariableType
:
417 return AddressClass::eDebug
;
418 case eSymbolTypeLineEntry
:
419 return AddressClass::eDebug
;
420 case eSymbolTypeLineHeader
:
421 return AddressClass::eDebug
;
422 case eSymbolTypeScopeBegin
:
423 return AddressClass::eDebug
;
424 case eSymbolTypeScopeEnd
:
425 return AddressClass::eDebug
;
426 case eSymbolTypeAdditional
:
427 return AddressClass::eUnknown
;
428 case eSymbolTypeCompiler
:
429 return AddressClass::eDebug
;
430 case eSymbolTypeInstrumentation
:
431 return AddressClass::eDebug
;
432 case eSymbolTypeUndefined
:
433 return AddressClass::eUnknown
;
434 case eSymbolTypeObjCClass
:
435 return AddressClass::eRuntime
;
436 case eSymbolTypeObjCMetaClass
:
437 return AddressClass::eRuntime
;
438 case eSymbolTypeObjCIVar
:
439 return AddressClass::eRuntime
;
440 case eSymbolTypeReExported
:
441 return AddressClass::eRuntime
;
445 return AddressClass::eUnknown
;
448 DataBufferSP
ObjectFile::ReadMemory(const ProcessSP
&process_sp
,
449 lldb::addr_t addr
, size_t byte_size
) {
450 DataBufferSP data_sp
;
452 std::unique_ptr
<DataBufferHeap
> data_up(new DataBufferHeap(byte_size
, 0));
454 const size_t bytes_read
= process_sp
->ReadMemory(
455 addr
, data_up
->GetBytes(), data_up
->GetByteSize(), error
);
456 if (bytes_read
== byte_size
)
457 data_sp
.reset(data_up
.release());
462 size_t ObjectFile::GetData(lldb::offset_t offset
, size_t length
,
463 DataExtractor
&data
) const {
464 // The entire file has already been mmap'ed into m_data, so just copy from
465 // there as the back mmap buffer will be shared with shared pointers.
466 return data
.SetData(m_data
, offset
, length
);
469 size_t ObjectFile::CopyData(lldb::offset_t offset
, size_t length
,
471 // The entire file has already been mmap'ed into m_data, so just copy from
472 // there Note that the data remains in target byte order.
473 return m_data
.CopyData(offset
, length
, dst
);
476 size_t ObjectFile::ReadSectionData(Section
*section
,
477 lldb::offset_t section_offset
, void *dst
,
480 section_offset
*= section
->GetTargetByteSize();
482 // If some other objectfile owns this data, pass this to them.
483 if (section
->GetObjectFile() != this)
484 return section
->GetObjectFile()->ReadSectionData(section
, section_offset
,
487 if (!section
->IsRelocated())
488 RelocateSection(section
);
491 ProcessSP
process_sp(m_process_wp
.lock());
494 const addr_t base_load_addr
=
495 section
->GetLoadBaseAddress(&process_sp
->GetTarget());
496 if (base_load_addr
!= LLDB_INVALID_ADDRESS
)
497 return process_sp
->ReadMemory(base_load_addr
+ section_offset
, dst
,
501 const lldb::offset_t section_file_size
= section
->GetFileSize();
502 if (section_offset
< section_file_size
) {
503 const size_t section_bytes_left
= section_file_size
- section_offset
;
504 size_t section_dst_len
= dst_len
;
505 if (section_dst_len
> section_bytes_left
)
506 section_dst_len
= section_bytes_left
;
507 return CopyData(section
->GetFileOffset() + section_offset
,
508 section_dst_len
, dst
);
510 if (section
->GetType() == eSectionTypeZeroFill
) {
511 const uint64_t section_size
= section
->GetByteSize();
512 const uint64_t section_bytes_left
= section_size
- section_offset
;
513 uint64_t section_dst_len
= dst_len
;
514 if (section_dst_len
> section_bytes_left
)
515 section_dst_len
= section_bytes_left
;
516 memset(dst
, 0, section_dst_len
);
517 return section_dst_len
;
524 // Get the section data the file on disk
525 size_t ObjectFile::ReadSectionData(Section
*section
,
526 DataExtractor
§ion_data
) {
527 // If some other objectfile owns this data, pass this to them.
528 if (section
->GetObjectFile() != this)
529 return section
->GetObjectFile()->ReadSectionData(section
, section_data
);
531 if (!section
->IsRelocated())
532 RelocateSection(section
);
535 ProcessSP
process_sp(m_process_wp
.lock());
537 const addr_t base_load_addr
=
538 section
->GetLoadBaseAddress(&process_sp
->GetTarget());
539 if (base_load_addr
!= LLDB_INVALID_ADDRESS
) {
540 DataBufferSP
data_sp(
541 ReadMemory(process_sp
, base_load_addr
, section
->GetByteSize()));
543 section_data
.SetData(data_sp
, 0, data_sp
->GetByteSize());
544 section_data
.SetByteOrder(process_sp
->GetByteOrder());
545 section_data
.SetAddressByteSize(process_sp
->GetAddressByteSize());
546 return section_data
.GetByteSize();
552 // The object file now contains a full mmap'ed copy of the object file
553 // data, so just use this
554 return GetData(section
->GetFileOffset(), GetSectionDataSize(section
),
558 bool ObjectFile::SplitArchivePathWithObject(llvm::StringRef path_with_object
,
559 FileSpec
&archive_file
,
560 ConstString
&archive_object
,
562 size_t len
= path_with_object
.size();
563 if (len
< 2 || path_with_object
.back() != ')')
565 llvm::StringRef archive
= path_with_object
.substr(0, path_with_object
.rfind('('));
568 llvm::StringRef object
= path_with_object
.substr(archive
.size() + 1).drop_back();
569 archive_file
.SetFile(archive
, FileSpec::Style::native
);
570 if (must_exist
&& !FileSystem::Instance().Exists(archive_file
))
572 archive_object
.SetString(object
);
576 void ObjectFile::ClearSymtab() {
577 ModuleSP
module_sp(GetModule());
579 Log
*log
= GetLog(LLDBLog::Object
);
580 LLDB_LOGF(log
, "%p ObjectFile::ClearSymtab () symtab = %p",
581 static_cast<void *>(this),
582 static_cast<void *>(m_symtab_up
.get()));
583 // Since we need to clear the symbol table, we need a new llvm::once_flag
584 // instance so we can safely create another symbol table
585 m_symtab_once_up
.reset(new llvm::once_flag());
590 SectionList
*ObjectFile::GetSectionList(bool update_module_section_list
) {
591 if (m_sections_up
== nullptr) {
592 if (update_module_section_list
) {
593 ModuleSP
module_sp(GetModule());
595 std::lock_guard
<std::recursive_mutex
> guard(module_sp
->GetMutex());
596 CreateSections(*module_sp
->GetUnifiedSectionList());
599 SectionList unified_section_list
;
600 CreateSections(unified_section_list
);
603 return m_sections_up
.get();
607 ObjectFile::GetSymbolTypeFromName(llvm::StringRef name
,
608 lldb::SymbolType symbol_type_hint
) {
610 if (name
.startswith("_OBJC_")) {
612 if (name
.startswith("_OBJC_CLASS_$_"))
613 return lldb::eSymbolTypeObjCClass
;
614 if (name
.startswith("_OBJC_METACLASS_$_"))
615 return lldb::eSymbolTypeObjCMetaClass
;
616 if (name
.startswith("_OBJC_IVAR_$_"))
617 return lldb::eSymbolTypeObjCIVar
;
618 } else if (name
.startswith(".objc_class_name_")) {
620 return lldb::eSymbolTypeObjCClass
;
623 return symbol_type_hint
;
626 std::vector
<ObjectFile::LoadableData
>
627 ObjectFile::GetLoadableData(Target
&target
) {
628 std::vector
<LoadableData
> loadables
;
629 SectionList
*section_list
= GetSectionList();
632 // Create a list of loadable data from loadable sections
633 size_t section_count
= section_list
->GetNumSections(0);
634 for (size_t i
= 0; i
< section_count
; ++i
) {
635 LoadableData loadable
;
636 SectionSP section_sp
= section_list
->GetSectionAtIndex(i
);
638 target
.GetSectionLoadList().GetSectionLoadAddress(section_sp
);
639 if (loadable
.Dest
== LLDB_INVALID_ADDRESS
)
641 // We can skip sections like bss
642 if (section_sp
->GetFileSize() == 0)
644 DataExtractor section_data
;
645 section_sp
->GetSectionData(section_data
);
646 loadable
.Contents
= llvm::ArrayRef
<uint8_t>(section_data
.GetDataStart(),
647 section_data
.GetByteSize());
648 loadables
.push_back(loadable
);
653 std::unique_ptr
<CallFrameInfo
> ObjectFile::CreateCallFrameInfo() {
657 void ObjectFile::RelocateSection(lldb_private::Section
*section
)
661 DataBufferSP
ObjectFile::MapFileData(const FileSpec
&file
, uint64_t Size
,
663 return FileSystem::Instance().CreateDataBuffer(file
.GetPath(), Size
, Offset
);
666 void llvm::format_provider
<ObjectFile::Type
>::format(
667 const ObjectFile::Type
&type
, raw_ostream
&OS
, StringRef Style
) {
669 case ObjectFile::eTypeInvalid
:
672 case ObjectFile::eTypeCoreFile
:
675 case ObjectFile::eTypeExecutable
:
678 case ObjectFile::eTypeDebugInfo
:
681 case ObjectFile::eTypeDynamicLinker
:
682 OS
<< "dynamic linker";
684 case ObjectFile::eTypeObjectFile
:
687 case ObjectFile::eTypeSharedLibrary
:
688 OS
<< "shared library";
690 case ObjectFile::eTypeStubLibrary
:
691 OS
<< "stub library";
693 case ObjectFile::eTypeJIT
:
696 case ObjectFile::eTypeUnknown
:
702 void llvm::format_provider
<ObjectFile::Strata
>::format(
703 const ObjectFile::Strata
&strata
, raw_ostream
&OS
, StringRef Style
) {
705 case ObjectFile::eStrataInvalid
:
708 case ObjectFile::eStrataUnknown
:
711 case ObjectFile::eStrataUser
:
714 case ObjectFile::eStrataKernel
:
717 case ObjectFile::eStrataRawImage
:
720 case ObjectFile::eStrataJIT
:
727 Symtab
*ObjectFile::GetSymtab() {
728 ModuleSP
module_sp(GetModule());
730 // We can't take the module lock in ObjectFile::GetSymtab() or we can
731 // deadlock in DWARF indexing when any file asks for the symbol table from
732 // an object file. This currently happens in the preloading of symbols in
733 // SymbolFileDWARF::PreloadSymbols() because the main thread will take the
734 // module lock, and then threads will be spun up to index the DWARF and
735 // any of those threads might end up trying to relocate items in the DWARF
736 // sections which causes ObjectFile::GetSectionData(...) to relocate section
737 // data which requires the symbol table.
739 // So to work around this, we create the symbol table one time using
740 // llvm::once_flag, lock it, and then set the unique pointer. Any other
741 // thread that gets ahold of the symbol table before parsing is done, will
742 // not be able to access the symbol table contents since all APIs in Symtab
743 // are protected by a mutex in the Symtab object itself.
744 llvm::call_once(*m_symtab_once_up
, [&]() {
745 Symtab
*symtab
= new Symtab(this);
746 std::lock_guard
<std::recursive_mutex
> symtab_guard(symtab
->GetMutex());
747 m_symtab_up
.reset(symtab
);
748 if (!m_symtab_up
->LoadFromCache()) {
749 ElapsedTime
elapsed(module_sp
->GetSymtabParseTime());
750 ParseSymtab(*m_symtab_up
);
751 m_symtab_up
->Finalize();
755 return m_symtab_up
.get();
758 uint32_t ObjectFile::GetCacheHash() {
760 return *m_cache_hash
;
762 strm
.Format("{0}-{1}-{2}", m_file
, GetType(), GetStrata());
763 m_cache_hash
= llvm::djbHash(strm
.GetString());
764 return *m_cache_hash
;
770 bool fromJSON(const llvm::json::Value
&value
,
771 lldb_private::ObjectFile::Type
&type
, llvm::json::Path path
) {
772 if (auto str
= value
.getAsString()) {
773 type
= llvm::StringSwitch
<ObjectFile::Type
>(*str
)
774 .Case("corefile", ObjectFile::eTypeCoreFile
)
775 .Case("executable", ObjectFile::eTypeExecutable
)
776 .Case("debuginfo", ObjectFile::eTypeDebugInfo
)
777 .Case("dynamiclinker", ObjectFile::eTypeDynamicLinker
)
778 .Case("objectfile", ObjectFile::eTypeObjectFile
)
779 .Case("sharedlibrary", ObjectFile::eTypeSharedLibrary
)
780 .Case("stublibrary", ObjectFile::eTypeStubLibrary
)
781 .Case("jit", ObjectFile::eTypeJIT
)
782 .Case("unknown", ObjectFile::eTypeUnknown
)
783 .Default(ObjectFile::eTypeInvalid
);
785 if (type
== ObjectFile::eTypeInvalid
) {
786 path
.report("invalid object type");
792 path
.report("expected string");