OSDN Git Service

MC CFG: Add "dynamic disassembly" support to MCObjectDisassembler.
authorAhmed Bougacha <ahmed.bougacha@gmail.com>
Wed, 21 Aug 2013 07:28:37 +0000 (07:28 +0000)
committerAhmed Bougacha <ahmed.bougacha@gmail.com>
Wed, 21 Aug 2013 07:28:37 +0000 (07:28 +0000)
It can now disassemble code in situations where the effective load
address is different than the load address declared in the object file.
This happens for PIC, hence "dynamic".

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188884 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCObjectDisassembler.h
lib/MC/MCObjectDisassembler.cpp

index de2aae7..edaf7dc 100644 (file)
@@ -65,6 +65,22 @@ public:
   virtual ArrayRef<uint64_t> getStaticExitFunctions();
   /// @}
 
+  /// \name Translation between effective and objectfile load address.
+  /// @{
+  /// \brief Compute the effective load address, from an objectfile virtual
+  /// address. This is implemented in a format-specific way, to take into
+  /// account things like PIE/ASLR when doing dynamic disassembly.
+  /// For example, on Mach-O this would be done by adding the VM addr slide,
+  /// on glibc ELF by keeping a map between segment load addresses, filled
+  /// using dl_iterate_phdr, etc..
+  /// In most static situations and in the default impl., this returns \p Addr.
+  virtual uint64_t getEffectiveLoadAddr(uint64_t Addr);
+
+  /// \brief Compute the original load address, as specified in the objectfile.
+  /// This is the inverse of getEffectiveLoadAddr.
+  virtual uint64_t getOriginalLoadAddr(uint64_t EffectiveAddr);
+  /// @}
+
 protected:
   const object::ObjectFile &Obj;
   const MCDisassembler &Dis;
index 8cb9a8a..4ce8e92 100644 (file)
@@ -44,7 +44,7 @@ uint64_t MCObjectDisassembler::getEntrypoint() {
     if (Name == "main" || Name == "_main") {
       uint64_t Entrypoint;
       SI->getAddress(Entrypoint);
-      return Entrypoint;
+      return getEffectiveLoadAddr(Entrypoint);
     }
   }
   return 0;
@@ -58,6 +58,14 @@ ArrayRef<uint64_t> MCObjectDisassembler::getStaticExitFunctions() {
   return ArrayRef<uint64_t>();
 }
 
+uint64_t MCObjectDisassembler::getEffectiveLoadAddr(uint64_t Addr) {
+  return Addr;
+}
+
+uint64_t MCObjectDisassembler::getOriginalLoadAddr(uint64_t Addr) {
+  return Addr;
+}
+
 MCModule *MCObjectDisassembler::buildEmptyModule() {
   MCModule *Module = new MCModule;
   Module->Entrypoint = getEntrypoint();
@@ -90,6 +98,7 @@ void MCObjectDisassembler::buildSectionAtoms(MCModule *Module) {
     uint64_t SecSize; SI->getSize(SecSize);
     if (StartAddr == UnknownAddressOrSize || SecSize == UnknownAddressOrSize)
       continue;
+    StartAddr = getEffectiveLoadAddr(StartAddr);
 
     StringRef Contents; SI->getContents(Contents);
     StringRefMemoryObject memoryObject(Contents, StartAddr);
@@ -170,6 +179,7 @@ void MCObjectDisassembler::buildCFG(MCModule *Module) {
     if (SymType == SymbolRef::ST_Function) {
       uint64_t SymAddr;
       SI->getAddress(SymAddr);
+      SymAddr = getEffectiveLoadAddr(SymAddr);
       Calls.insert(SymAddr);
       Splits.insert(SymAddr);
     }