diff --git a/lldb/source/Plugins/ObjectFile/CMakeLists.txt b/lldb/source/Plugins/ObjectFile/CMakeLists.txt --- a/lldb/source/Plugins/ObjectFile/CMakeLists.txt +++ b/lldb/source/Plugins/ObjectFile/CMakeLists.txt @@ -6,4 +6,5 @@ add_subdirectory(Minidump) add_subdirectory(PDB) add_subdirectory(PECOFF) +add_subdirectory(Placeholder) add_subdirectory(wasm) diff --git a/lldb/source/Plugins/ObjectFile/Placeholder/CMakeLists.txt b/lldb/source/Plugins/ObjectFile/Placeholder/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/lldb/source/Plugins/ObjectFile/Placeholder/CMakeLists.txt @@ -0,0 +1,12 @@ +add_lldb_library(lldbPluginObjectFilePlaceholder PLUGIN + ObjectFilePlaceholder.cpp + + LINK_LIBS + lldbCore + lldbHost + lldbSymbol + lldbTarget + LINK_COMPONENTS + Object + Support + ) diff --git a/lldb/source/Plugins/ObjectFile/Placeholder/ObjectFilePlaceholder.h b/lldb/source/Plugins/ObjectFile/Placeholder/ObjectFilePlaceholder.h new file mode 100644 --- /dev/null +++ b/lldb/source/Plugins/ObjectFile/Placeholder/ObjectFilePlaceholder.h @@ -0,0 +1,74 @@ +//===-- ObjectFilePlaceholder.h ---------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_PLACEHOLDER_OBJECTFILEPLACEHOLDER_H +#define LLDB_SOURCE_PLUGINS_OBJECTFILE_PLACEHOLDER_OBJECTFILEPLACEHOLDER_H + +#include "lldb/Symbol/ObjectFile.h" + +#include "lldb/Target/Target.h" +#include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/UUID.h" +#include "lldb/lldb-private.h" + +/// A minimal ObjectFile implementation providing a dummy object file for the +/// cases when the real module binary is not available. This allows the module +/// to show up in "image list" and symbols to be added to it. +class ObjectFilePlaceholder : public lldb_private::ObjectFile { +public: + // Static Functions + static void Initialize() {} + + static void Terminate() {} + + static llvm::StringRef GetPluginNameStatic() { return "placeholder"; } + + ObjectFilePlaceholder(const lldb::ModuleSP &module_sp, + const lldb_private::ModuleSpec &module_spec, + lldb::addr_t base, lldb::addr_t size); + + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } + bool ParseHeader() override { return true; } + Type CalculateType() override { return eTypeUnknown; } + Strata CalculateStrata() override { return eStrataUnknown; } + uint32_t GetDependentModules(lldb_private::FileSpecList &file_list) override { + return 0; + } + bool IsExecutable() const override { return false; } + lldb_private::ArchSpec GetArchitecture() override { return m_arch; } + lldb_private::UUID GetUUID() override { return m_uuid; } + void ParseSymtab(lldb_private::Symtab &symtab) override {} + bool IsStripped() override { return true; } + lldb::ByteOrder GetByteOrder() const override { + return m_arch.GetByteOrder(); + } + + uint32_t GetAddressByteSize() const override { + return m_arch.GetAddressByteSize(); + } + + lldb_private::Address GetBaseAddress() override; + + void CreateSections(lldb_private::SectionList &unified_section_list) override; + + bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value, + bool value_is_offset) override; + + void Dump(lldb_private::Stream *s) override; + + lldb::addr_t GetBaseImageAddress() const { return m_base; } + +private: + lldb_private::ArchSpec m_arch; + lldb_private::UUID m_uuid; + lldb::addr_t m_base; + lldb::addr_t m_size; +}; + +#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_PLACEHOLDER_OBJECTFILEPLACEHOLDER_H diff --git a/lldb/source/Plugins/ObjectFile/Placeholder/ObjectFilePlaceholder.cpp b/lldb/source/Plugins/ObjectFile/Placeholder/ObjectFilePlaceholder.cpp new file mode 100644 --- /dev/null +++ b/lldb/source/Plugins/ObjectFile/Placeholder/ObjectFilePlaceholder.cpp @@ -0,0 +1,70 @@ +//===-- ObjectFilePlaceholder.cpp----------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ObjectFilePlaceholder.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Section.h" +#include "lldb/Target/SectionLoadList.h" +#include "lldb/Target/Target.h" + +#include + +using namespace lldb; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE(ObjectFilePlaceholder) + +ObjectFilePlaceholder::ObjectFilePlaceholder( + const lldb::ModuleSP &module_sp, + const lldb_private::ModuleSpec &module_spec, lldb::addr_t base, + lldb::addr_t size) + : ObjectFile(module_sp, &module_spec.GetFileSpec(), /*file_offset*/ 0, + /*length*/ 0, /*data_sp*/ nullptr, /*data_offset*/ 0), + m_arch(module_spec.GetArchitecture()), m_uuid(module_spec.GetUUID()), + m_base(base), m_size(size) { + m_symtab_up = std::make_unique(this); +} + +void ObjectFilePlaceholder::CreateSections( + lldb_private::SectionList &unified_section_list) { + m_sections_up = std::make_unique(); + auto section_sp = std::make_shared( + GetModule(), this, /*sect_id*/ 0, + lldb_private::ConstString(".module_image"), eSectionTypeOther, m_base, + m_size, /*file_offset*/ 0, /*file_size*/ 0, + /*log2align*/ 0, /*flags*/ 0); + section_sp->SetPermissions(ePermissionsReadable | ePermissionsExecutable); + m_sections_up->AddSection(section_sp); + unified_section_list.AddSection(std::move(section_sp)); +} + +lldb_private::Address ObjectFilePlaceholder::GetBaseAddress() { + return lldb_private::Address(m_sections_up->GetSectionAtIndex(0), 0); +} + +bool ObjectFilePlaceholder::SetLoadAddress(Target &target, addr_t value, + bool value_is_offset) { + assert(!value_is_offset); + assert(value == m_base); + + // Create sections if they haven't been created already. + GetModule()->GetSectionList(); + assert(m_sections_up->GetNumSections(0) == 1); + + target.GetSectionLoadList().SetSectionLoadAddress( + m_sections_up->GetSectionAtIndex(0), m_base); + return true; +} + +void ObjectFilePlaceholder::Dump(lldb_private::Stream *s) { + s->Format("Placeholder object file for {0} loaded at [{1:x}-{2:x})\n", + GetFileSpec(), m_base, m_base + m_size); +} diff --git a/lldb/source/Plugins/Process/minidump/CMakeLists.txt b/lldb/source/Plugins/Process/minidump/CMakeLists.txt --- a/lldb/source/Plugins/Process/minidump/CMakeLists.txt +++ b/lldb/source/Plugins/Process/minidump/CMakeLists.txt @@ -14,6 +14,7 @@ lldbUtility lldbPluginProcessUtility lldbPluginProcessElfCore + lldbPluginObjectFilePlaceholder LINK_COMPONENTS BinaryFormat Object diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp --- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp +++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp @@ -34,6 +34,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Threading.h" +#include "Plugins/ObjectFile/Placeholder/ObjectFilePlaceholder.h" #include "Plugins/Process/Utility/StopInfoMachException.h" #include @@ -47,84 +48,6 @@ namespace { -/// A minimal ObjectFile implementation providing a dummy object file for the -/// cases when the real module binary is not available. This allows the module -/// to show up in "image list" and symbols to be added to it. -class PlaceholderObjectFile : public ObjectFile { -public: - PlaceholderObjectFile(const lldb::ModuleSP &module_sp, - const ModuleSpec &module_spec, lldb::addr_t base, - lldb::addr_t size) - : ObjectFile(module_sp, &module_spec.GetFileSpec(), /*file_offset*/ 0, - /*length*/ 0, /*data_sp*/ nullptr, /*data_offset*/ 0), - m_arch(module_spec.GetArchitecture()), m_uuid(module_spec.GetUUID()), - m_base(base), m_size(size) { - m_symtab_up = std::make_unique(this); - } - - static ConstString GetStaticPluginName() { - return ConstString("placeholder"); - } - llvm::StringRef GetPluginName() override { - return GetStaticPluginName().GetStringRef(); - } - bool ParseHeader() override { return true; } - Type CalculateType() override { return eTypeUnknown; } - Strata CalculateStrata() override { return eStrataUnknown; } - uint32_t GetDependentModules(FileSpecList &file_list) override { return 0; } - bool IsExecutable() const override { return false; } - ArchSpec GetArchitecture() override { return m_arch; } - UUID GetUUID() override { return m_uuid; } - void ParseSymtab(lldb_private::Symtab &symtab) override {} - bool IsStripped() override { return true; } - ByteOrder GetByteOrder() const override { return m_arch.GetByteOrder(); } - - uint32_t GetAddressByteSize() const override { - return m_arch.GetAddressByteSize(); - } - - Address GetBaseAddress() override { - return Address(m_sections_up->GetSectionAtIndex(0), 0); - } - - void CreateSections(SectionList &unified_section_list) override { - m_sections_up = std::make_unique(); - auto section_sp = std::make_shared
( - GetModule(), this, /*sect_id*/ 0, ConstString(".module_image"), - eSectionTypeOther, m_base, m_size, /*file_offset*/ 0, /*file_size*/ 0, - /*log2align*/ 0, /*flags*/ 0); - section_sp->SetPermissions(ePermissionsReadable | ePermissionsExecutable); - m_sections_up->AddSection(section_sp); - unified_section_list.AddSection(std::move(section_sp)); - } - - bool SetLoadAddress(Target &target, addr_t value, - bool value_is_offset) override { - assert(!value_is_offset); - assert(value == m_base); - - // Create sections if they haven't been created already. - GetModule()->GetSectionList(); - assert(m_sections_up->GetNumSections(0) == 1); - - target.GetSectionLoadList().SetSectionLoadAddress( - m_sections_up->GetSectionAtIndex(0), m_base); - return true; - } - - void Dump(Stream *s) override { - s->Format("Placeholder object file for {0} loaded at [{1:x}-{2:x})\n", - GetFileSpec(), m_base, m_base + m_size); - } - - lldb::addr_t GetBaseImageAddress() const { return m_base; } -private: - ArchSpec m_arch; - UUID m_uuid; - lldb::addr_t m_base; - lldb::addr_t m_size; -}; - /// Duplicate the HashElfTextSection() from the breakpad sources. /// /// Breakpad, a Google crash log reporting tool suite, creates minidump files @@ -578,12 +501,12 @@ // Watch out for place holder modules that have different paths, but the // same UUID. If the base address is different, create a new module. If // we don't then we will end up setting the load address of a different - // PlaceholderObjectFile and an assertion will fire. + // ObjectFilePlaceholder and an assertion will fire. auto *objfile = module_sp->GetObjectFile(); if (objfile && objfile->GetPluginName() == - PlaceholderObjectFile::GetStaticPluginName().GetStringRef()) { - if (((PlaceholderObjectFile *)objfile)->GetBaseImageAddress() != + ObjectFilePlaceholder::GetPluginNameStatic()) { + if (((ObjectFilePlaceholder *)objfile)->GetBaseImageAddress() != load_addr) module_sp.reset(); } @@ -601,7 +524,7 @@ "placeholder module for: {0}", name); - module_sp = Module::CreateModuleFromObjectFile( + module_sp = Module::CreateModuleFromObjectFile( module_spec, load_addr, load_size); GetTarget().GetImages().Append(module_sp, true /* notify */); }