LLDB mainline
ObjectFile.cpp
Go to the documentation of this file.
1//===-- ObjectFile.cpp ----------------------------------------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
10#include "lldb/Core/Module.h"
13#include "lldb/Core/Section.h"
17#include "lldb/Target/Process.h"
19#include "lldb/Target/Target.h"
23#include "lldb/Utility/Log.h"
24#include "lldb/Utility/Timer.h"
25#include "lldb/lldb-private.h"
26
27#include "llvm/Support/DJB.h"
28
29using namespace lldb;
30using namespace lldb_private;
31
34
35static ObjectFileSP
37 lldb::offset_t file_offset, lldb::offset_t file_size,
38 DataBufferSP data_sp, lldb::offset_t &data_offset) {
40 for (uint32_t idx = 0;
42 idx)) != nullptr;
43 ++idx) {
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);
48 }
49 return {};
50}
51
53ObjectFile::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));
62
63 if (!module_sp)
64 return {};
65
66 if (!file)
67 return {};
68
69 if (!data_sp) {
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()) {
76 module_sp, file, file_offset, file_size, data_sp, data_offset);
77 if (object_file_sp)
78 return object_file_sp;
79 }
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
83 // file.
84 if (file_size > 0) {
86 file->GetPath(), g_initial_bytes_to_read, file_offset);
87 data_offset = 0;
88 }
89 }
90
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);
95
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);
102 if (file_size > 0) {
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.
108 // Also, don't read
109 // ANY data in case there is data cached in the container plug-ins
110 // (like BSD archives caching the contained objects within an
111 // file).
113 module_sp, file, file_offset, file_size, data_sp, data_offset);
114 if (object_file_sp)
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...
119 archive_file.GetPath(), g_initial_bytes_to_read, file_offset);
120 }
121 }
122 }
123
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.
128 for (uint32_t idx = 0;
130 nullptr;
131 ++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;
136 }
137
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.
142 module_sp, file, file_offset, file_size, data_sp, data_offset);
143 if (object_file_sp)
144 return object_file_sp;
145 }
146
147 // We didn't find it, so clear our shared pointer in case it contains
148 // anything and return an empty shared pointer
149 return {};
150}
151
153 const ProcessSP &process_sp,
154 lldb::addr_t header_addr,
155 WritableDataBufferSP data_sp) {
156 ObjectFileSP object_file_sp;
157
158 if (module_sp) {
159 LLDB_SCOPED_TIMERF("ObjectFile::FindPlugin (module = "
160 "%s, process = %p, header_addr = "
161 "0x%" PRIx64 ")",
162 module_sp->GetFileSpec().GetPath().c_str(),
163 static_cast<void *>(process_sp.get()), header_addr);
164 uint32_t idx;
165
166 // Check if this is a normal object file by iterating through all object
167 // file plugin instances.
168 ObjectFileCreateMemoryInstance create_callback;
169 for (idx = 0;
170 (create_callback =
172 nullptr;
173 ++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;
178 }
179 }
180
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;
185}
186
188 DataBufferSP data_sp;
189 offset_t data_offset = 0;
190 ModuleSP module_sp = std::make_shared<Module>(file_spec);
191 return static_cast<bool>(ObjectFile::FindPlugin(
192 module_sp, &file_spec, 0, FileSystem::Instance().GetByteSize(file_spec),
193 data_sp, data_offset));
194}
195
197 lldb::offset_t file_offset,
198 lldb::offset_t file_size,
199 ModuleSpecList &specs,
200 DataBufferSP data_sp) {
201 if (!data_sp)
203 file.GetPath(), g_initial_bytes_to_read, file_offset);
204 if (data_sp) {
205 if (file_size == 0) {
206 const lldb::offset_t actual_file_size =
208 if (actual_file_size > file_offset)
209 file_size = actual_file_size - file_offset;
210 }
211 return ObjectFile::GetModuleSpecifications(file, // file spec
212 data_sp, // data bytes
213 0, // data offset
214 file_offset, // file offset
215 file_size, // file length
216 specs);
217 }
218 return 0;
219}
220
222 const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
223 lldb::offset_t data_offset, lldb::offset_t file_offset,
225 const size_t initial_count = specs.GetSize();
227 uint32_t i;
228 // Try the ObjectFile plug-ins
229 for (i = 0;
230 (callback =
232 i)) != nullptr;
233 ++i) {
234 if (callback(file, data_sp, data_offset, file_offset, file_size, specs) > 0)
235 return specs.GetSize() - initial_count;
236 }
237
238 // Try the ObjectContainer plug-ins
239 for (i = 0;
240 (callback = PluginManager::
242 nullptr;
243 ++i) {
244 if (callback(file, data_sp, data_offset, file_offset, file_size, specs) > 0)
245 return specs.GetSize() - initial_count;
246 }
247 return 0;
248}
249
251 const FileSpec *file_spec_ptr,
252 lldb::offset_t file_offset, lldb::offset_t length,
253 lldb::DataBufferSP data_sp, lldb::offset_t data_offset)
254 : ModuleChild(module_sp),
255 m_file(), // This file could be different from the original module's file
257 m_file_offset(file_offset), m_length(length), m_data(), m_process_wp(),
259 m_symtab_once_up(new llvm::once_flag()) {
260 if (file_spec_ptr)
261 m_file = *file_spec_ptr;
262 if (data_sp)
263 m_data.SetData(data_sp, data_offset, length);
264 Log *log = GetLog(LLDBLog::Object);
265 LLDB_LOGF(log,
266 "%p ObjectFile::ObjectFile() module = %p (%s), file = %s, "
267 "file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64,
268 static_cast<void *>(this), static_cast<void *>(module_sp.get()),
269 module_sp->GetSpecificationDescription().c_str(),
270 m_file ? m_file.GetPath().c_str() : "<NULL>", m_file_offset,
271 m_length);
272}
273
275 const ProcessSP &process_sp, lldb::addr_t header_addr,
276 DataBufferSP header_data_sp)
277 : ModuleChild(module_sp), m_file(), m_type(eTypeInvalid),
279 m_process_wp(process_sp), m_memory_addr(header_addr), m_sections_up(),
280 m_symtab_up(), m_symtab_once_up(new llvm::once_flag()) {
281 if (header_data_sp)
282 m_data.SetData(header_data_sp, 0, header_data_sp->GetByteSize());
283 Log *log = GetLog(LLDBLog::Object);
284 LLDB_LOGF(log,
285 "%p ObjectFile::ObjectFile() module = %p (%s), process = %p, "
286 "header_addr = 0x%" PRIx64,
287 static_cast<void *>(this), static_cast<void *>(module_sp.get()),
288 module_sp->GetSpecificationDescription().c_str(),
289 static_cast<void *>(process_sp.get()), m_memory_addr);
290}
291
293 Log *log = GetLog(LLDBLog::Object);
294 LLDB_LOGF(log, "%p ObjectFile::~ObjectFile ()\n", static_cast<void *>(this));
295}
296
298 ModuleSP module_sp(GetModule());
299 if (module_sp)
300 return module_sp->SetArchitecture(new_arch);
301 return false;
302}
303
305 Symtab *symtab = GetSymtab();
306 if (symtab) {
307 Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
308 if (symbol) {
309 if (symbol->ValueIsAddress()) {
310 const SectionSP section_sp(symbol->GetAddressRef().GetSection());
311 if (section_sp) {
312 const SectionType section_type = section_sp->GetType();
313 switch (section_type) {
316 case eSectionTypeCode:
317 return AddressClass::eCode;
320 case eSectionTypeData:
332 return AddressClass::eData;
368 case eSectionTypeCTF:
386 // In case of absolute sections decide the address class based on
387 // the symbol type because the section type isn't specify if it is
388 // a code or a data section.
389 break;
390 }
391 }
392 }
393
394 const SymbolType symbol_type = symbol->GetType();
395 switch (symbol_type) {
396 case eSymbolTypeAny:
400 case eSymbolTypeCode:
401 return AddressClass::eCode;
403 return AddressClass::eCode;
405 return AddressClass::eCode;
406 case eSymbolTypeData:
407 return AddressClass::eData;
420 case eSymbolTypeBlock:
422 case eSymbolTypeLocal:
423 return AddressClass::eData;
424 case eSymbolTypeParam:
425 return AddressClass::eData;
427 return AddressClass::eData;
454 }
455 }
456 }
458}
459
461 lldb::addr_t addr,
462 size_t byte_size) {
463 WritableDataBufferSP data_sp;
464 if (process_sp) {
465 std::unique_ptr<DataBufferHeap> data_up(new DataBufferHeap(byte_size, 0));
467 const size_t bytes_read = process_sp->ReadMemory(
468 addr, data_up->GetBytes(), data_up->GetByteSize(), error);
469 if (bytes_read == byte_size)
470 data_sp.reset(data_up.release());
471 }
472 return data_sp;
473}
474
475size_t ObjectFile::GetData(lldb::offset_t offset, size_t length,
476 DataExtractor &data) const {
477 // The entire file has already been mmap'ed into m_data, so just copy from
478 // there as the back mmap buffer will be shared with shared pointers.
479 return data.SetData(m_data, offset, length);
480}
481
482size_t ObjectFile::CopyData(lldb::offset_t offset, size_t length,
483 void *dst) const {
484 // The entire file has already been mmap'ed into m_data, so just copy from
485 // there Note that the data remains in target byte order.
486 return m_data.CopyData(offset, length, dst);
487}
488
490 lldb::offset_t section_offset, void *dst,
491 size_t dst_len) {
492 assert(section);
493 section_offset *= section->GetTargetByteSize();
494
495 // If some other objectfile owns this data, pass this to them.
496 if (section->GetObjectFile() != this)
497 return section->GetObjectFile()->ReadSectionData(section, section_offset,
498 dst, dst_len);
499
500 if (!section->IsRelocated())
501 RelocateSection(section);
502
503 if (IsInMemory()) {
504 ProcessSP process_sp(m_process_wp.lock());
505 if (process_sp) {
507 const addr_t base_load_addr =
508 section->GetLoadBaseAddress(&process_sp->GetTarget());
509 if (base_load_addr != LLDB_INVALID_ADDRESS)
510 return process_sp->ReadMemory(base_load_addr + section_offset, dst,
511 dst_len, error);
512 }
513 } else {
514 const lldb::offset_t section_file_size = section->GetFileSize();
515 if (section_offset < section_file_size) {
516 const size_t section_bytes_left = section_file_size - section_offset;
517 size_t section_dst_len = dst_len;
518 if (section_dst_len > section_bytes_left)
519 section_dst_len = section_bytes_left;
520 return CopyData(section->GetFileOffset() + section_offset,
521 section_dst_len, dst);
522 } else {
523 if (section->GetType() == eSectionTypeZeroFill) {
524 const uint64_t section_size = section->GetByteSize();
525 const uint64_t section_bytes_left = section_size - section_offset;
526 uint64_t section_dst_len = dst_len;
527 if (section_dst_len > section_bytes_left)
528 section_dst_len = section_bytes_left;
529 memset(dst, 0, section_dst_len);
530 return section_dst_len;
531 }
532 }
533 }
534 return 0;
535}
536
537// Get the section data the file on disk
539 DataExtractor &section_data) {
540 // If some other objectfile owns this data, pass this to them.
541 if (section->GetObjectFile() != this)
542 return section->GetObjectFile()->ReadSectionData(section, section_data);
543
544 if (!section->IsRelocated())
545 RelocateSection(section);
546
547 if (IsInMemory()) {
548 ProcessSP process_sp(m_process_wp.lock());
549 if (process_sp) {
550 const addr_t base_load_addr =
551 section->GetLoadBaseAddress(&process_sp->GetTarget());
552 if (base_load_addr != LLDB_INVALID_ADDRESS) {
553 DataBufferSP data_sp(
554 ReadMemory(process_sp, base_load_addr, section->GetByteSize()));
555 if (data_sp) {
556 section_data.SetData(data_sp, 0, data_sp->GetByteSize());
557 section_data.SetByteOrder(process_sp->GetByteOrder());
558 section_data.SetAddressByteSize(process_sp->GetAddressByteSize());
559 return section_data.GetByteSize();
560 }
561 }
562 }
563 }
564
565 // The object file now contains a full mmap'ed copy of the object file
566 // data, so just use this
567 return GetData(section->GetFileOffset(), GetSectionDataSize(section),
568 section_data);
569}
570
571bool ObjectFile::SplitArchivePathWithObject(llvm::StringRef path_with_object,
572 FileSpec &archive_file,
573 ConstString &archive_object,
574 bool must_exist) {
575 size_t len = path_with_object.size();
576 if (len < 2 || path_with_object.back() != ')')
577 return false;
578 llvm::StringRef archive = path_with_object.substr(0, path_with_object.rfind('('));
579 if (archive.empty())
580 return false;
581 llvm::StringRef object = path_with_object.substr(archive.size() + 1).drop_back();
582 archive_file.SetFile(archive, FileSpec::Style::native);
583 if (must_exist && !FileSystem::Instance().Exists(archive_file))
584 return false;
585 archive_object.SetString(object);
586 return true;
587}
588
590 ModuleSP module_sp(GetModule());
591 if (module_sp) {
592 Log *log = GetLog(LLDBLog::Object);
593 LLDB_LOGF(log, "%p ObjectFile::ClearSymtab () symtab = %p",
594 static_cast<void *>(this),
595 static_cast<void *>(m_symtab_up.get()));
596 // Since we need to clear the symbol table, we need a new llvm::once_flag
597 // instance so we can safely create another symbol table
598 m_symtab_once_up.reset(new llvm::once_flag());
599 m_symtab_up.reset();
600 }
601}
602
603SectionList *ObjectFile::GetSectionList(bool update_module_section_list) {
604 if (m_sections_up == nullptr) {
605 if (update_module_section_list) {
606 ModuleSP module_sp(GetModule());
607 if (module_sp) {
608 std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
609 CreateSections(*module_sp->GetUnifiedSectionList());
610 }
611 } else {
612 SectionList unified_section_list;
613 CreateSections(unified_section_list);
614 }
615 }
616 return m_sections_up.get();
617}
618
621 lldb::SymbolType symbol_type_hint) {
622 if (!name.empty()) {
623 if (name.starts_with("_OBJC_")) {
624 // ObjC
625 if (name.starts_with("_OBJC_CLASS_$_"))
627 if (name.starts_with("_OBJC_METACLASS_$_"))
629 if (name.starts_with("_OBJC_IVAR_$_"))
631 } else if (name.starts_with(".objc_class_name_")) {
632 // ObjC v1
634 }
635 }
636 return symbol_type_hint;
637}
638
641 return llvm::StringSwitch<SectionType>(name)
642 .Case("abbrev", eSectionTypeDWARFDebugAbbrev)
643 .Case("abbrev.dwo", eSectionTypeDWARFDebugAbbrevDwo)
644 .Case("addr", eSectionTypeDWARFDebugAddr)
645 .Case("aranges", eSectionTypeDWARFDebugAranges)
646 .Case("cu_index", eSectionTypeDWARFDebugCuIndex)
647 .Case("frame", eSectionTypeDWARFDebugFrame)
648 .Case("info", eSectionTypeDWARFDebugInfo)
649 .Case("info.dwo", eSectionTypeDWARFDebugInfoDwo)
650 .Cases("line", "line.dwo", eSectionTypeDWARFDebugLine)
651 .Cases("line_str", "line_str.dwo", eSectionTypeDWARFDebugLineStr)
652 .Case("loc", eSectionTypeDWARFDebugLoc)
653 .Case("loc.dwo", eSectionTypeDWARFDebugLocDwo)
654 .Case("loclists", eSectionTypeDWARFDebugLocLists)
655 .Case("loclists.dwo", eSectionTypeDWARFDebugLocListsDwo)
656 .Case("macinfo", eSectionTypeDWARFDebugMacInfo)
657 .Cases("macro", "macro.dwo", eSectionTypeDWARFDebugMacro)
658 .Case("names", eSectionTypeDWARFDebugNames)
659 .Case("pubnames", eSectionTypeDWARFDebugPubNames)
660 .Case("pubtypes", eSectionTypeDWARFDebugPubTypes)
661 .Case("ranges", eSectionTypeDWARFDebugRanges)
662 .Case("rnglists", eSectionTypeDWARFDebugRngLists)
663 .Case("rnglists.dwo", eSectionTypeDWARFDebugRngListsDwo)
664 .Case("str", eSectionTypeDWARFDebugStr)
665 .Case("str.dwo", eSectionTypeDWARFDebugStrDwo)
666 .Cases("str_offsets", "str_offs", eSectionTypeDWARFDebugStrOffsets)
667 .Case("str_offsets.dwo", eSectionTypeDWARFDebugStrOffsetsDwo)
668 .Case("tu_index", eSectionTypeDWARFDebugTuIndex)
669 .Case("types", eSectionTypeDWARFDebugTypes)
670 .Case("types.dwo", eSectionTypeDWARFDebugTypesDwo)
671 .Default(eSectionTypeOther);
672}
673
674std::vector<ObjectFile::LoadableData>
676 std::vector<LoadableData> loadables;
677 SectionList *section_list = GetSectionList();
678 if (!section_list)
679 return loadables;
680 // Create a list of loadable data from loadable sections
681 size_t section_count = section_list->GetNumSections(0);
682 for (size_t i = 0; i < section_count; ++i) {
683 LoadableData loadable;
684 SectionSP section_sp = section_list->GetSectionAtIndex(i);
685 loadable.Dest = target.GetSectionLoadAddress(section_sp);
686 if (loadable.Dest == LLDB_INVALID_ADDRESS)
687 continue;
688 // We can skip sections like bss
689 if (section_sp->GetFileSize() == 0)
690 continue;
691 DataExtractor section_data;
692 section_sp->GetSectionData(section_data);
693 loadable.Contents = llvm::ArrayRef<uint8_t>(section_data.GetDataStart(),
694 section_data.GetByteSize());
695 loadables.push_back(loadable);
696 }
697 return loadables;
698}
699
700std::unique_ptr<CallFrameInfo> ObjectFile::CreateCallFrameInfo() {
701 return {};
702}
703
707
709 uint64_t Offset) {
710 return FileSystem::Instance().CreateDataBuffer(file.GetPath(), Size, Offset);
711}
712
713void llvm::format_provider<ObjectFile::Type>::format(
714 const ObjectFile::Type &type, raw_ostream &OS, StringRef Style) {
715 switch (type) {
717 OS << "invalid";
718 break;
720 OS << "core file";
721 break;
723 OS << "executable";
724 break;
726 OS << "debug info";
727 break;
729 OS << "dynamic linker";
730 break;
732 OS << "object file";
733 break;
735 OS << "shared library";
736 break;
738 OS << "stub library";
739 break;
741 OS << "jit";
742 break;
744 OS << "unknown";
745 break;
746 }
747}
748
749void llvm::format_provider<ObjectFile::Strata>::format(
750 const ObjectFile::Strata &strata, raw_ostream &OS, StringRef Style) {
751 switch (strata) {
753 OS << "invalid";
754 break;
756 OS << "unknown";
757 break;
759 OS << "user";
760 break;
762 OS << "kernel";
763 break;
765 OS << "raw image";
766 break;
768 OS << "jit";
769 break;
770 }
771}
772
773Symtab *ObjectFile::GetSymtab(bool can_create) {
774 ModuleSP module_sp(GetModule());
775 if (module_sp && can_create) {
776 // We can't take the module lock in ObjectFile::GetSymtab() or we can
777 // deadlock in DWARF indexing when any file asks for the symbol table from
778 // an object file. This currently happens in the preloading of symbols in
779 // SymbolFileDWARF::PreloadSymbols() because the main thread will take the
780 // module lock, and then threads will be spun up to index the DWARF and
781 // any of those threads might end up trying to relocate items in the DWARF
782 // sections which causes ObjectFile::GetSectionData(...) to relocate section
783 // data which requires the symbol table.
784 //
785 // So to work around this, we create the symbol table one time using
786 // llvm::once_flag, lock it, and then set the unique pointer. Any other
787 // thread that gets ahold of the symbol table before parsing is done, will
788 // not be able to access the symbol table contents since all APIs in Symtab
789 // are protected by a mutex in the Symtab object itself.
790 llvm::call_once(*m_symtab_once_up, [&]() {
791 Symtab *symtab = new Symtab(this);
792 std::lock_guard<std::recursive_mutex> symtab_guard(symtab->GetMutex());
793 m_symtab_up.reset(symtab);
794 if (!m_symtab_up->LoadFromCache()) {
795 ElapsedTime elapsed(module_sp->GetSymtabParseTime());
797 m_symtab_up->Finalize();
798 }
799 });
800 }
801 return m_symtab_up.get();
802}
803
805 if (m_cache_hash)
806 return *m_cache_hash;
807 StreamString strm;
808 strm.Format("{0}-{1}-{2}", m_file, GetType(), GetStrata());
809 m_cache_hash = llvm::djbHash(strm.GetString());
810 return *m_cache_hash;
811}
812
813std::string ObjectFile::GetObjectName() const {
814 if (ModuleSP module_sp = GetModule())
815 if (ConstString object_name = module_sp->GetObjectName())
816 return llvm::formatv("{0}({1})", GetFileSpec().GetFilename().GetString(),
817 object_name.GetString())
818 .str();
819 return GetFileSpec().GetFilename().GetString();
820}
821
822namespace llvm {
823namespace json {
824
825bool fromJSON(const llvm::json::Value &value,
826 lldb_private::ObjectFile::Type &type, llvm::json::Path path) {
827 if (auto str = value.getAsString()) {
828 type = llvm::StringSwitch<ObjectFile::Type>(*str)
829 .Case("corefile", ObjectFile::eTypeCoreFile)
830 .Case("executable", ObjectFile::eTypeExecutable)
831 .Case("debuginfo", ObjectFile::eTypeDebugInfo)
832 .Case("dynamiclinker", ObjectFile::eTypeDynamicLinker)
833 .Case("objectfile", ObjectFile::eTypeObjectFile)
834 .Case("sharedlibrary", ObjectFile::eTypeSharedLibrary)
835 .Case("stublibrary", ObjectFile::eTypeStubLibrary)
836 .Case("jit", ObjectFile::eTypeJIT)
837 .Case("unknown", ObjectFile::eTypeUnknown)
838 .Default(ObjectFile::eTypeInvalid);
839
840 if (type == ObjectFile::eTypeInvalid) {
841 path.report("invalid object type");
842 return false;
843 }
844
845 return true;
846 }
847 path.report("expected string");
848 return false;
849}
850} // namespace json
851} // namespace llvm
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOGF(log,...)
Definition Log.h:376
static ObjectFileSP CreateObjectFromContainer(const lldb::ModuleSP &module_sp, const FileSpec *file, lldb::offset_t file_offset, lldb::offset_t file_size, DataBufferSP data_sp, lldb::offset_t &data_offset)
static double elapsed(const StatsTimepoint &start, const StatsTimepoint &end)
#define LLDB_SCOPED_TIMERF(...)
Definition Timer.h:86
lldb::SectionSP GetSection() const
Get const accessor for the section.
Definition Address.h:432
An architecture specification class.
Definition ArchSpec.h:31
A uniqued constant string class.
Definition ConstString.h:40
std::string GetString() const
Get the string value as a std::string.
void SetString(llvm::StringRef s)
A subclass of DataBuffer that stores a data buffer on the heap.
An data extractor class.
void SetByteOrder(lldb::ByteOrder byte_order)
Set the byte_order value.
uint64_t GetByteSize() const
Get the number of bytes contained in this object.
const uint8_t * GetDataStart() const
Get the data start pointer.
lldb::offset_t SetData(const void *bytes, lldb::offset_t length, lldb::ByteOrder byte_order)
Set data with a buffer that is caller owned.
void SetAddressByteSize(uint32_t addr_size)
Set the address byte size.
A class that measures elapsed time in an exception safe way.
Definition Statistics.h:76
A file utility class.
Definition FileSpec.h:57
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
Definition FileSpec.cpp:174
const ConstString & GetFilename() const
Filename string const get accessor.
Definition FileSpec.h:251
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:374
uint64_t GetByteSize(const FileSpec &file_spec) const
Returns the on-disk size of the given file in bytes.
bool Exists(const FileSpec &file_spec) const
Returns whether the given file exists.
static FileSystem & Instance()
std::shared_ptr< DataBuffer > CreateDataBuffer(const llvm::Twine &path, uint64_t size=0, uint64_t offset=0)
Create memory buffer from path.
ModuleChild(const lldb::ModuleSP &module_sp)
Construct with owning module.
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
static lldb::ObjectFileSP FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file_spec, lldb::offset_t file_offset, lldb::offset_t file_size, lldb::DataBufferSP &data_sp, lldb::offset_t &data_offset)
Find a ObjectFile plug-in that can parse file_spec.
DataExtractor m_data
The data for this object file so things can be parsed lazily.
Definition ObjectFile.h:784
std::unique_ptr< lldb_private::SectionList > m_sections_up
Definition ObjectFile.h:788
static bool IsObjectFile(lldb_private::FileSpec file_spec)
static lldb::DataBufferSP MapFileData(const FileSpec &file, uint64_t Size, uint64_t Offset)
ObjectFile(const lldb::ModuleSP &module_sp, const FileSpec *file_spec_ptr, lldb::offset_t file_offset, lldb::offset_t length, lldb::DataBufferSP data_sp, lldb::offset_t data_offset)
Construct with a parent module, offset, and header data.
virtual std::vector< LoadableData > GetLoadableData(Target &target)
Loads this objfile to memory.
~ObjectFile() override
Destructor.
std::unique_ptr< lldb_private::Symtab > m_symtab_up
Definition ObjectFile.h:789
const lldb::addr_t m_memory_addr
Set if the object file only exists in memory.
Definition ObjectFile.h:787
static size_t g_initial_bytes_to_read
The number of bytes to read when going through the plugins.
Definition ObjectFile.h:811
static lldb::SectionType GetDWARFSectionTypeFromName(llvm::StringRef name)
Parses the section type from a section name for DWARF sections.
virtual void ParseSymtab(Symtab &symtab)=0
Parse the symbol table into the provides symbol table object.
virtual AddressClass GetAddressClass(lldb::addr_t file_addr)
Get the address type given a file address in an object file.
Symtab * GetSymtab(bool can_create=true)
Gets the symbol table for the currently selected architecture (and object for archives).
static lldb::WritableDataBufferSP ReadMemory(const lldb::ProcessSP &process_sp, lldb::addr_t addr, size_t byte_size)
size_t GetData(lldb::offset_t offset, size_t length, DataExtractor &data) const
@ eTypeExecutable
A normal executable.
Definition ObjectFile.h:54
@ eTypeDebugInfo
An object file that contains only debug information.
Definition ObjectFile.h:56
@ eTypeStubLibrary
A library that can be linked against but not used for execution.
Definition ObjectFile.h:64
@ eTypeObjectFile
An intermediate object file.
Definition ObjectFile.h:60
@ eTypeDynamicLinker
The platform's dynamic linker executable.
Definition ObjectFile.h:58
@ eTypeCoreFile
A core file that has a checkpoint of a program's execution state.
Definition ObjectFile.h:52
@ eTypeSharedLibrary
A shared library that can be used during execution.
Definition ObjectFile.h:62
@ eTypeJIT
JIT code that has symbols, sections and possibly debug info.
Definition ObjectFile.h:66
lldb::addr_t m_file_offset
The offset in bytes into the file, or the address in memory.
Definition ObjectFile.h:778
static lldb::SymbolType GetSymbolTypeFromName(llvm::StringRef name, lldb::SymbolType symbol_type_hint=lldb::eSymbolTypeUndefined)
virtual size_t GetSectionDataSize(Section *section)
Definition ObjectFile.h:704
virtual std::unique_ptr< CallFrameInfo > CreateCallFrameInfo()
Creates a plugin-specific call frame info.
virtual void ClearSymtab()
Frees the symbol table.
bool SetModulesArchitecture(const ArchSpec &new_arch)
Sets the architecture for a module.
virtual FileSpec & GetFileSpec()
Get accessor to the object file specification.
Definition ObjectFile.h:281
std::string GetObjectName() const
static bool SplitArchivePathWithObject(llvm::StringRef path_with_object, lldb_private::FileSpec &archive_file, lldb_private::ConstString &archive_object, bool must_exist)
Split a path into a file path with object name.
virtual void CreateSections(SectionList &unified_section_list)=0
size_t CopyData(lldb::offset_t offset, size_t length, void *dst) const
virtual void RelocateSection(lldb_private::Section *section)
Perform relocations on the section if necessary.
std::optional< uint32_t > m_cache_hash
Definition ObjectFile.h:796
virtual SectionList * GetSectionList(bool update_module_section_list=true)
Gets the section list for the currently selected architecture (and object for archives).
std::unique_ptr< llvm::once_flag > m_symtab_once_up
We need a llvm::once_flag that we can use to avoid locking the module lock and deadlocking LLDB.
Definition ObjectFile.h:795
bool IsInMemory() const
Returns true if the object file exists only in memory.
Definition ObjectFile.h:709
lldb::ProcessWP m_process_wp
Definition ObjectFile.h:785
uint32_t GetCacheHash()
Get a hash that can be used for caching object file releated information.
lldb::addr_t m_length
The length of this object file if it is known (can be zero if length is unknown or can't be determine...
Definition ObjectFile.h:780
virtual size_t ReadSectionData(Section *section, lldb::offset_t section_offset, void *dst, size_t dst_len)
static size_t GetModuleSpecifications(const FileSpec &file, lldb::offset_t file_offset, lldb::offset_t file_size, ModuleSpecList &specs, lldb::DataBufferSP data_sp=lldb::DataBufferSP())
virtual lldb::addr_t GetByteSize() const
Definition ObjectFile.h:274
static ObjectFileCreateMemoryInstance GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx)
static ObjectContainerCreateInstance GetObjectContainerCreateCallbackAtIndex(uint32_t idx)
static ObjectFileCreateInstance GetObjectFileCreateCallbackAtIndex(uint32_t idx)
static ObjectFileGetModuleSpecifications GetObjectContainerGetModuleSpecificationsCallbackAtIndex(uint32_t idx)
static ObjectFileGetModuleSpecifications GetObjectFileGetModuleSpecificationsCallbackAtIndex(uint32_t idx)
size_t GetNumSections(uint32_t depth) const
Definition Section.cpp:540
lldb::SectionSP GetSectionAtIndex(size_t idx) const
Definition Section.cpp:551
uint32_t GetTargetByteSize() const
Definition Section.h:263
lldb::offset_t GetFileOffset() const
Definition Section.h:170
ObjectFile * GetObjectFile()
Definition Section.h:220
lldb::SectionType GetType() const
Definition Section.h:204
lldb::addr_t GetLoadBaseAddress(Target *target) const
Definition Section.cpp:233
lldb::addr_t GetByteSize() const
Definition Section.h:186
lldb::offset_t GetFileSize() const
Definition Section.h:176
bool IsRelocated() const
Definition Section.h:265
An error handling class.
Definition Status.h:118
llvm::StringRef GetString() const
void Format(const char *format, Args &&... args)
Definition Stream.h:352
bool ValueIsAddress() const
Definition Symbol.cpp:165
Address & GetAddressRef()
Definition Symbol.h:73
lldb::SymbolType GetType() const
Definition Symbol.h:169
Symbol * FindSymbolContainingFileAddress(lldb::addr_t file_addr)
Definition Symtab.cpp:1045
std::recursive_mutex & GetMutex()
Definition Symtab.h:51
lldb::addr_t GetSectionLoadAddress(const lldb::SectionSP &section_sp)
Definition Target.cpp:5235
#define LLDB_INVALID_ADDRESS
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:332
size_t(* ObjectFileGetModuleSpecifications)(const FileSpec &file, lldb::DataBufferSP &data_sp, lldb::offset_t data_offset, lldb::offset_t file_offset, lldb::offset_t length, ModuleSpecList &module_specs)
ObjectContainer *(* ObjectContainerCreateInstance)(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, lldb::offset_t data_offset, const FileSpec *file, lldb::offset_t offset, lldb::offset_t length)
ObjectFile *(* ObjectFileCreateMemoryInstance)(const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t offset)
bool fromJSON(const llvm::json::Value &value, TraceSupportedResponse &info, llvm::json::Path path)
ObjectFile *(* ObjectFileCreateInstance)(const lldb::ModuleSP &module_sp, lldb::DataBufferSP data_sp, lldb::offset_t data_offset, const FileSpec *file, lldb::offset_t file_offset, lldb::offset_t length)
uint64_t offset_t
Definition lldb-types.h:85
std::shared_ptr< lldb_private::ObjectFile > ObjectFileSP
std::shared_ptr< lldb_private::Process > ProcessSP
SymbolType
Symbol types.
@ eSymbolTypeUndefined
@ eSymbolTypeVariableType
@ eSymbolTypeObjCMetaClass
@ eSymbolTypeReExported
@ eSymbolTypeObjCClass
@ eSymbolTypeObjectFile
@ eSymbolTypeTrampoline
@ eSymbolTypeResolver
@ eSymbolTypeSourceFile
@ eSymbolTypeException
@ eSymbolTypeVariable
@ eSymbolTypeAbsolute
@ eSymbolTypeAdditional
When symbols take more than one entry, the extra entries get this type.
@ eSymbolTypeInstrumentation
@ eSymbolTypeHeaderFile
@ eSymbolTypeCommonBlock
@ eSymbolTypeCompiler
@ eSymbolTypeLineHeader
@ eSymbolTypeObjCIVar
@ eSymbolTypeLineEntry
@ eSymbolTypeScopeBegin
@ eSymbolTypeScopeEnd
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::Section > SectionSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
uint64_t addr_t
Definition lldb-types.h:80
@ eSectionTypeDWARFDebugStrOffsets
@ eSectionTypeELFDynamicSymbols
Elf SHT_DYNSYM section.
@ eSectionTypeInvalid
@ eSectionTypeDWARFDebugPubNames
@ eSectionTypeDataObjCCFStrings
Objective-C const CFString/NSString objects.
@ eSectionTypeZeroFill
@ eSectionTypeDWARFDebugLocDwo
@ eSectionTypeDWARFDebugFrame
@ eSectionTypeARMextab
@ eSectionTypeContainer
The section contains child sections.
@ eSectionTypeDWARFDebugLocLists
DWARF v5 .debug_loclists.
@ eSectionTypeDWARFDebugTypes
DWARF .debug_types section.
@ eSectionTypeDataSymbolAddress
Address of a symbol in the symbol table.
@ eSectionTypeELFDynamicLinkInfo
Elf SHT_DYNAMIC section.
@ eSectionTypeDWARFDebugMacInfo
@ eSectionTypeAbsoluteAddress
Dummy section for symbols with absolute address.
@ eSectionTypeCompactUnwind
compact unwind section in Mach-O, __TEXT,__unwind_info
@ eSectionTypeELFRelocationEntries
Elf SHT_REL or SHT_REL section.
@ eSectionTypeDWARFAppleNamespaces
@ eSectionTypeLLDBFormatters
@ eSectionTypeDWARFDebugNames
DWARF v5 .debug_names.
@ eSectionTypeDWARFDebugRngLists
DWARF v5 .debug_rnglists.
@ eSectionTypeEHFrame
@ eSectionTypeDWARFDebugStrOffsetsDwo
@ eSectionTypeDWARFDebugMacro
@ eSectionTypeDWARFAppleTypes
@ eSectionTypeDWARFDebugInfo
@ eSectionTypeDWARFDebugTypesDwo
@ eSectionTypeDWARFDebugRanges
@ eSectionTypeDWARFDebugRngListsDwo
@ eSectionTypeLLDBTypeSummaries
@ eSectionTypeGoSymtab
@ eSectionTypeARMexidx
@ eSectionTypeDWARFDebugLine
@ eSectionTypeDWARFDebugPubTypes
@ eSectionTypeDataObjCMessageRefs
Pointer to function pointer + selector.
@ eSectionTypeDWARFDebugTuIndex
@ eSectionTypeDWARFDebugStr
@ eSectionTypeDWARFDebugLineStr
DWARF v5 .debug_line_str.
@ eSectionTypeDWARFDebugLoc
@ eSectionTypeDWARFAppleNames
@ eSectionTypeDataCStringPointers
Pointers to C string data.
@ eSectionTypeDWARFAppleObjC
@ eSectionTypeSwiftModules
@ eSectionTypeDWARFDebugCuIndex
@ eSectionTypeDWARFDebugAranges
@ eSectionTypeDWARFDebugAbbrevDwo
@ eSectionTypeDWARFGNUDebugAltLink
@ eSectionTypeDWARFDebugStrDwo
@ eSectionTypeDWARFDebugAbbrev
@ eSectionTypeDataPointers
@ eSectionTypeDWARFDebugLocListsDwo
@ eSectionTypeDWARFDebugInfoDwo
@ eSectionTypeDWARFDebugAddr
@ eSectionTypeWasmName
@ eSectionTypeDataCString
Inlined C string data.
@ eSectionTypeELFSymbolTable
Elf SHT_SYMTAB section.
std::shared_ptr< lldb_private::Module > ModuleSP
llvm::ArrayRef< uint8_t > Contents
Definition ObjectFile.h:97