mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-14 07:29:01 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188886 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
fe018c4145
commit
0e83b90283
@ -23,6 +23,7 @@ namespace llvm {
|
|||||||
|
|
||||||
namespace object {
|
namespace object {
|
||||||
class ObjectFile;
|
class ObjectFile;
|
||||||
|
class MachOObjectFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
class MCBasicBlock;
|
class MCBasicBlock;
|
||||||
@ -100,6 +101,36 @@ private:
|
|||||||
void buildCFG(MCModule *Module);
|
void buildCFG(MCModule *Module);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MCMachOObjectDisassembler : public MCObjectDisassembler {
|
||||||
|
const object::MachOObjectFile &MOOF;
|
||||||
|
|
||||||
|
uint64_t VMAddrSlide;
|
||||||
|
uint64_t HeaderLoadAddress;
|
||||||
|
|
||||||
|
// __DATA;__mod_init_func support.
|
||||||
|
llvm::StringRef ModInitContents;
|
||||||
|
// __DATA;__mod_exit_func support.
|
||||||
|
llvm::StringRef ModExitContents;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// \brief Construct a Mach-O specific object disassembler.
|
||||||
|
/// \param VMAddrSlide The virtual address slide applied by dyld.
|
||||||
|
/// \param HeaderLoadAddress The load address of the mach_header for this
|
||||||
|
/// object.
|
||||||
|
MCMachOObjectDisassembler(const object::MachOObjectFile &MOOF,
|
||||||
|
const MCDisassembler &Dis,
|
||||||
|
const MCInstrAnalysis &MIA, uint64_t VMAddrSlide,
|
||||||
|
uint64_t HeaderLoadAddress);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uint64_t getEffectiveLoadAddr(uint64_t Addr) LLVM_OVERRIDE;
|
||||||
|
uint64_t getOriginalLoadAddr(uint64_t EffectiveAddr) LLVM_OVERRIDE;
|
||||||
|
uint64_t getEntrypoint() LLVM_OVERRIDE;
|
||||||
|
|
||||||
|
ArrayRef<uint64_t> getStaticInitFunctions() LLVM_OVERRIDE;
|
||||||
|
ArrayRef<uint64_t> getStaticExitFunctions() LLVM_OVERRIDE;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -18,7 +18,10 @@
|
|||||||
#include "llvm/MC/MCFunction.h"
|
#include "llvm/MC/MCFunction.h"
|
||||||
#include "llvm/MC/MCInstrAnalysis.h"
|
#include "llvm/MC/MCInstrAnalysis.h"
|
||||||
#include "llvm/MC/MCModule.h"
|
#include "llvm/MC/MCModule.h"
|
||||||
|
#include "llvm/Object/MachO.h"
|
||||||
#include "llvm/Object/ObjectFile.h"
|
#include "llvm/Object/ObjectFile.h"
|
||||||
|
#include "llvm/Support/Debug.h"
|
||||||
|
#include "llvm/Support/MachO.h"
|
||||||
#include "llvm/Support/MemoryObject.h"
|
#include "llvm/Support/MemoryObject.h"
|
||||||
#include "llvm/Support/StringRefMemoryObject.h"
|
#include "llvm/Support/StringRefMemoryObject.h"
|
||||||
#include "llvm/Support/raw_ostream.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);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user