Add llvm-style RTTI to ObjectFile hierarchy
authorPavel Labath <pavel@labath.sk>
Wed, 31 Jul 2019 11:57:34 +0000 (11:57 +0000)
committerPavel Labath <pavel@labath.sk>
Wed, 31 Jul 2019 11:57:34 +0000 (11:57 +0000)
Summary:
On the heels of D62934, this patch uses the same approach to introduce
llvm RTTI support to the ObjectFile hierarchy. It also replaces the
existing uses of GetPluginName doing run-time type checks with
llvm::dyn_cast and friends.

This formally introduces new dependencies from some other plugins to
ObjectFile plugins. However, I believe this is fine because:
- these dependencies were already kind of there, and the only reason
  we could get away with not modeling them explicitly was because the
  code was relying on magically knowing what will GetPluginName() return
  for a particular kind of object files.
- the dependencies themselves are logical (it makes sense for
  SymbolVendorELF to depend on ObjectFileELF), or at least don't
  actively get in the way (the JitLoaderGDB->MachO thing).
- they don't introduce any new dependency loops as ObjectFile plugins
  don't depend on any other plugins

Reviewers: xiaobai, JDevlieghere, espindola

Subscribers: emaste, mgorny, arichardson, MaskRay, lldb-commits

Differential Revision: https://reviews.llvm.org/D65450

llvm-svn: 367413

20 files changed:
lldb/include/lldb/Symbol/ObjectFile.h
lldb/source/Plugins/JITLoader/GDB/CMakeLists.txt
lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h
lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
lldb/source/Plugins/SymbolVendor/ELF/CMakeLists.txt
lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
lldb/source/Plugins/SymbolVendor/MacOSX/CMakeLists.txt
lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
lldb/source/Symbol/ObjectFile.cpp

index 84683e3..76cc055 100644 (file)
@@ -204,6 +204,10 @@ public:
       const char *path_with_object, lldb_private::FileSpec &archive_file,
       lldb_private::ConstString &archive_object, bool must_exist);
 
+  // LLVM RTTI support
+  static char ID;
+  virtual bool isA(const void *ClassID) const { return ClassID == &ID; }
+
   /// Gets the address size in bytes for the current object file.
   ///
   /// \return
index 774d85b..ecdff28 100644 (file)
@@ -16,6 +16,7 @@ add_lldb_library(lldbPluginJITLoaderGDB PLUGIN
     lldbSymbol
     lldbTarget
     lldbUtility
+    lldbPluginObjectFileMachO
   LINK_COMPONENTS
     Support
   )
index 0593af4..2aa284f 100644 (file)
@@ -6,9 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-
-#include "llvm/Support/MathExtras.h"
-
+#include "JITLoaderGDB.h"
+#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
 #include "lldb/Breakpoint/Breakpoint.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
@@ -26,8 +25,7 @@
 #include "lldb/Utility/LLDBAssert.h"
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/StreamString.h"
-
-#include "JITLoaderGDB.h"
+#include "llvm/Support/MathExtras.h"
 
 #include <memory>
 
@@ -326,20 +324,16 @@ bool JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries) {
         module_sp->GetObjectFile()->GetSymtab();
 
         m_jit_objects.insert(std::make_pair(symbolfile_addr, module_sp));
-        if (module_sp->GetObjectFile()->GetPluginName() ==
-            ConstString("mach-o")) {
-          ObjectFile *image_object_file = module_sp->GetObjectFile();
-          if (image_object_file) {
-            const SectionList *section_list =
-                image_object_file->GetSectionList();
-            if (section_list) {
-              uint64_t vmaddrheuristic = 0;
-              uint64_t lower = (uint64_t)-1;
-              uint64_t upper = 0;
-              updateSectionLoadAddress(*section_list, target, symbolfile_addr,
-                                       symbolfile_size, vmaddrheuristic, lower,
-                                       upper);
-            }
+        if (auto image_object_file =
+                llvm::dyn_cast<ObjectFileMachO>(module_sp->GetObjectFile())) {
+          const SectionList *section_list = image_object_file->GetSectionList();
+          if (section_list) {
+            uint64_t vmaddrheuristic = 0;
+            uint64_t lower = (uint64_t)-1;
+            uint64_t upper = 0;
+            updateSectionLoadAddress(*section_list, target, symbolfile_addr,
+                                     symbolfile_size, vmaddrheuristic, lower,
+                                     upper);
           }
         } else {
           bool changed = false;
index 60dd9f9..f895e9c 100644 (file)
@@ -42,6 +42,8 @@ llvm::Optional<Header> Header::parse(llvm::StringRef text) {
   return Header{ArchSpec(triple), std::move(uuid)};
 }
 
+char ObjectFileBreakpad::ID;
+
 void ObjectFileBreakpad::Initialize() {
   PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                 GetPluginDescriptionStatic(), CreateInstance,
index e8885e0..2ce6a34 100644 (file)
@@ -48,6 +48,13 @@ public:
 
   uint32_t GetPluginVersion() override { return 1; }
 
+  // LLVM RTTI support
+  static char ID;
+  bool isA(const void *ClassID) const override {
+    return ClassID == &ID || ObjectFile::isA(ClassID);
+  }
+  static bool classof(const ObjectFile *obj) { return obj->isA(&ID); }
+
   // ObjectFile Protocol.
 
   bool ParseHeader() override;
index 37f6145..b107afc 100644 (file)
@@ -333,6 +333,8 @@ static uint32_t subTypeFromElfHeader(const elf::ELFHeader &header) {
   return LLDB_INVALID_CPUTYPE;
 }
 
+char ObjectFileELF::ID;
+
 // Arbitrary constant used as UUID prefix for core files.
 const uint32_t ObjectFileELF::g_core_uuid_magic(0xE210C);
 
index 8abe995..2a21377 100644 (file)
@@ -89,6 +89,13 @@ public:
 
   uint32_t GetPluginVersion() override;
 
+  // LLVM RTTI support
+  static char ID;
+  bool isA(const void *ClassID) const override {
+    return ClassID == &ID || ObjectFile::isA(ClassID);
+  }
+  static bool classof(const ObjectFile *obj) { return obj->isA(&ID); }
+
   // ObjectFile Protocol.
   bool ParseHeader() override;
 
index eaf973d..c55b96d 100644 (file)
@@ -39,6 +39,8 @@
 using namespace lldb;
 using namespace lldb_private;
 
+char ObjectFileJIT::ID;
+
 void ObjectFileJIT::Initialize() {
   PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                 GetPluginDescriptionStatic(), CreateInstance,
index 9924112..c992683 100644 (file)
@@ -46,6 +46,13 @@ public:
                                         lldb::offset_t length,
                                         lldb_private::ModuleSpecList &specs);
 
+  // LLVM RTTI support
+  static char ID;
+  bool isA(const void *ClassID) const override {
+    return ClassID == &ID || ObjectFile::isA(ClassID);
+  }
+  static bool classof(const ObjectFile *obj) { return obj->isA(&ID); }
+
   // Member Functions
   bool ParseHeader() override;
 
index 1007dbb..bfb732b 100644 (file)
@@ -830,6 +830,8 @@ static uint32_t MachHeaderSizeFromMagic(uint32_t magic) {
 
 #define MACHO_NLIST_ARM_SYMBOL_IS_THUMB 0x0008
 
+char ObjectFileMachO::ID;
+
 void ObjectFileMachO::Initialize() {
   PluginManager::RegisterPlugin(
       GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance,
index 2326873..1185e1e 100644 (file)
@@ -63,6 +63,13 @@ public:
   static bool MagicBytesMatch(lldb::DataBufferSP &data_sp, lldb::addr_t offset,
                               lldb::addr_t length);
 
+  // LLVM RTTI support
+  static char ID;
+  bool isA(const void *ClassID) const override {
+    return ClassID == &ID || ObjectFile::isA(ClassID);
+  }
+  static bool classof(const ObjectFile *obj) { return obj->isA(&ID); }
+
   // Member Functions
   bool ParseHeader() override;
 
index 1ab9ce8..d2dd934 100644 (file)
@@ -88,6 +88,8 @@ static UUID GetCoffUUID(llvm::object::COFFObjectFile *coff_obj) {
   return UUID();
 }
 
+char ObjectFilePECOFF::ID;
+
 void ObjectFilePECOFF::Initialize() {
   PluginManager::RegisterPlugin(
       GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance,
index 6aa9eba..68ea7a7 100644 (file)
@@ -85,6 +85,13 @@ public:
 
   static lldb::SymbolType MapSymbolType(uint16_t coff_symbol_type);
 
+  // LLVM RTTI support
+  static char ID;
+  bool isA(const void *ClassID) const override {
+    return ClassID == &ID || ObjectFile::isA(ClassID);
+  }
+  static bool classof(const ObjectFile *obj) { return obj->isA(&ID); }
+
   bool ParseHeader() override;
 
   bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value,
index ef03429..551ef90 100644 (file)
@@ -179,10 +179,7 @@ ConstString SymbolFileBreakpad::GetPluginNameStatic() {
 }
 
 uint32_t SymbolFileBreakpad::CalculateAbilities() {
-  if (!m_objfile_sp)
-    return 0;
-  if (m_objfile_sp->GetPluginName() !=
-      ObjectFileBreakpad::GetPluginNameStatic())
+  if (!m_objfile_sp || !llvm::isa<ObjectFileBreakpad>(*m_objfile_sp))
     return 0;
 
   return CompileUnits | Functions | LineTables;
index cd0ffd7..b12b51b 100644 (file)
@@ -120,6 +120,8 @@ loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator) {
   }
   OwningBinary<Binary> binary = std::move(*expected_binary);
 
+  // TODO: Avoid opening the PE/COFF binary twice by reading this information
+  // directly from the lldb_private::ObjectFile.
   auto *obj = llvm::dyn_cast<llvm::object::COFFObjectFile>(binary.getBinary());
   if (!obj)
     return nullptr;
index e742fac..86562c4 100644 (file)
@@ -5,4 +5,5 @@ add_lldb_library(lldbPluginSymbolVendorELF PLUGIN
     lldbCore
     lldbHost
     lldbSymbol
+    lldbPluginObjectFileELF
   )
index f279af6..92953f0 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <string.h>
 
+#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
@@ -61,15 +62,11 @@ SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp,
   if (!module_sp)
     return nullptr;
 
-  ObjectFile *obj_file = module_sp->GetObjectFile();
+  ObjectFileELF *obj_file =
+      llvm::dyn_cast_or_null<ObjectFileELF>(module_sp->GetObjectFile());
   if (!obj_file)
     return nullptr;
 
-  static ConstString obj_file_elf("elf");
-  ConstString obj_name = obj_file->GetPluginName();
-  if (obj_name != obj_file_elf)
-    return nullptr;
-
   lldb_private::UUID uuid = obj_file->GetUUID();
   if (!uuid)
     return nullptr;
index bbcdff9..8e82eae 100644 (file)
@@ -7,4 +7,5 @@ add_lldb_library(lldbPluginSymbolVendorMacOSX PLUGIN
     lldbCore
     lldbHost
     lldbSymbol
+    lldbPluginObjectFileMachO
   )
index af9ea0a..857f4f0 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <string.h>
 
+#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
@@ -97,15 +98,11 @@ SymbolVendorMacOSX::CreateInstance(const lldb::ModuleSP &module_sp,
   if (!module_sp)
     return NULL;
 
-  ObjectFile *obj_file = module_sp->GetObjectFile();
+  ObjectFile *obj_file =
+      llvm::dyn_cast_or_null<ObjectFileMachO>(module_sp->GetObjectFile());
   if (!obj_file)
     return NULL;
 
-  static ConstString obj_file_macho("mach-o");
-  ConstString obj_name = obj_file->GetPluginName();
-  if (obj_name != obj_file_macho)
-    return NULL;
-
   static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
   Timer scoped_timer(func_cat,
                      "SymbolVendorMacOSX::CreateInstance (module = %s)",
index 35510a2..f0981a8 100644 (file)
@@ -26,6 +26,8 @@
 using namespace lldb;
 using namespace lldb_private;
 
+char ObjectFile::ID;
+
 ObjectFileSP
 ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file,
                        lldb::offset_t file_offset, lldb::offset_t file_size,