summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC/MCObjectDisassembler.cpp
diff options
context:
space:
mode:
authorAhmed Bougacha <ahmed.bougacha@gmail.com>2013-08-21 07:28:44 +0000
committerAhmed Bougacha <ahmed.bougacha@gmail.com>2013-08-21 07:28:44 +0000
commitb09d140f6b8ea0767df23481550cc61ed2bcdab8 (patch)
tree7c9771029663500be1240a301104119fa35ef39a /llvm/lib/MC/MCObjectDisassembler.cpp
parent0a89d2bf76dc3b800cd5a027c7823e67290c6eda (diff)
downloadbcm5719-llvm-b09d140f6b8ea0767df23481550cc61ed2bcdab8.tar.gz
bcm5719-llvm-b09d140f6b8ea0767df23481550cc61ed2bcdab8.zip
MC CFG: Add MCObjectDisassembler Mach-O implementation.
Supports: - entrypoint, using LC_MAIN. - static ctors/dtors, using __mod_{init,exit}_func - translation between effective and object load address, using dyld's VM address slide. llvm-svn: 188886
Diffstat (limited to 'llvm/lib/MC/MCObjectDisassembler.cpp')
-rw-r--r--llvm/lib/MC/MCObjectDisassembler.cpp89
1 files changed, 89 insertions, 0 deletions
diff --git a/llvm/lib/MC/MCObjectDisassembler.cpp b/llvm/lib/MC/MCObjectDisassembler.cpp
index 4ce8e927933..1969bcb4735 100644
--- a/llvm/lib/MC/MCObjectDisassembler.cpp
+++ b/llvm/lib/MC/MCObjectDisassembler.cpp
@@ -18,7 +18,10 @@
#include "llvm/MC/MCFunction.h"
#include "llvm/MC/MCInstrAnalysis.h"
#include "llvm/MC/MCModule.h"
+#include "llvm/Object/MachO.h"
#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/MachO.h"
#include "llvm/Support/MemoryObject.h"
#include "llvm/Support/StringRefMemoryObject.h"
#include "llvm/Support/raw_ostream.h"
@@ -285,3 +288,89 @@ void MCObjectDisassembler::buildCFG(MCModule *Module) {
}
}
}
+
+// MachO MCObjectDisassembler implementation.
+
+MCMachOObjectDisassembler::MCMachOObjectDisassembler(
+ const MachOObjectFile &MOOF, const MCDisassembler &Dis,
+ const MCInstrAnalysis &MIA, uint64_t VMAddrSlide,
+ uint64_t HeaderLoadAddress)
+ : MCObjectDisassembler(MOOF, Dis, MIA), MOOF(MOOF),
+ VMAddrSlide(VMAddrSlide), HeaderLoadAddress(HeaderLoadAddress) {
+
+ error_code ec;
+ for (section_iterator SI = MOOF.begin_sections(), SE = MOOF.end_sections();
+ SI != SE; SI.increment(ec)) {
+ if (ec)
+ break;
+ StringRef Name;
+ SI->getName(Name);
+ // FIXME: We should use the S_ section type instead of the name.
+ if (Name == "__mod_init_func") {
+ DEBUG(dbgs() << "Found __mod_init_func section!\n");
+ SI->getContents(ModInitContents);
+ } else if (Name == "__mod_exit_func") {
+ DEBUG(dbgs() << "Found __mod_exit_func section!\n");
+ SI->getContents(ModExitContents);
+ }
+ }
+}
+
+// FIXME: Only do the translations for addresses actually inside the object.
+uint64_t MCMachOObjectDisassembler::getEffectiveLoadAddr(uint64_t Addr) {
+ return Addr + VMAddrSlide;
+}
+
+uint64_t
+MCMachOObjectDisassembler::getOriginalLoadAddr(uint64_t EffectiveAddr) {
+ return EffectiveAddr - VMAddrSlide;
+}
+
+uint64_t MCMachOObjectDisassembler::getEntrypoint() {
+ uint64_t EntryFileOffset = 0;
+
+ // Look for LC_MAIN.
+ {
+ uint32_t LoadCommandCount = MOOF.getHeader().NumLoadCommands;
+ MachOObjectFile::LoadCommandInfo Load = MOOF.getFirstLoadCommandInfo();
+ for (unsigned I = 0;; ++I) {
+ if (Load.C.Type == MachO::LoadCommandMain) {
+ EntryFileOffset =
+ ((const MachO::entry_point_command *)Load.Ptr)->entryoff;
+ break;
+ }
+
+ if (I == LoadCommandCount - 1)
+ break;
+ else
+ Load = MOOF.getNextLoadCommandInfo(Load);
+ }
+ }
+
+ // If we didn't find anything, default to the common implementation.
+ // FIXME: Maybe we could also look at LC_UNIXTHREAD and friends?
+ if (EntryFileOffset)
+ return MCObjectDisassembler::getEntrypoint();
+
+ return EntryFileOffset + HeaderLoadAddress;
+}
+
+ArrayRef<uint64_t> MCMachOObjectDisassembler::getStaticInitFunctions() {
+ // FIXME: We only handle 64bit mach-o
+ assert(MOOF.is64Bit());
+
+ size_t EntrySize = 8;
+ size_t EntryCount = ModInitContents.size() / EntrySize;
+ return ArrayRef<uint64_t>(
+ reinterpret_cast<const uint64_t *>(ModInitContents.data()), EntryCount);
+}
+
+ArrayRef<uint64_t> MCMachOObjectDisassembler::getStaticExitFunctions() {
+ // FIXME: We only handle 64bit mach-o
+ assert(MOOF.is64Bit());
+
+ size_t EntrySize = 8;
+ size_t EntryCount = ModExitContents.size() / EntrySize;
+ return ArrayRef<uint64_t>(
+ reinterpret_cast<const uint64_t *>(ModExitContents.data()), EntryCount);
+}
OpenPOWER on IntegriCloud