[llvm] r188886 - MC CFG: Add MCObjectDisassembler Mach-O implementation.

Ahmed Bougacha ahmed.bougacha at gmail.com
Wed Aug 21 12:47:09 PDT 2013


On Wed, Aug 21, 2013 at 10:39 AM, David Blaikie <dblaikie at gmail.com> wrote:
> On Wed, Aug 21, 2013 at 12:28 AM, Ahmed Bougacha
> <ahmed.bougacha at gmail.com> wrote:
>> Author: ab
>> Date: Wed Aug 21 02:28:44 2013
>> New Revision: 188886
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=188886&view=rev
>> Log:
>> MC CFG: Add MCObjectDisassembler Mach-O implementation.
>
> It /seems/ like this should be testable at this point & thus the
> commit should include test cases, no?

Hmm, it’s hardly testable as is, actually. The only users are the
testcases for my local code, I wanted to get this out there to leave
room for the serious patch/review.
I’ll try harder to come up with something.

-- Ahmed

>>
>> 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.
>>
>> Modified:
>>     llvm/trunk/include/llvm/MC/MCObjectDisassembler.h
>>     llvm/trunk/lib/MC/MCObjectDisassembler.cpp
>>
>> Modified: llvm/trunk/include/llvm/MC/MCObjectDisassembler.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCObjectDisassembler.h?rev=188886&r1=188885&r2=188886&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/MC/MCObjectDisassembler.h (original)
>> +++ llvm/trunk/include/llvm/MC/MCObjectDisassembler.h Wed Aug 21 02:28:44 2013
>> @@ -23,6 +23,7 @@ namespace llvm {
>>
>>  namespace object {
>>    class ObjectFile;
>> +  class MachOObjectFile;
>>  }
>>
>>  class MCBasicBlock;
>> @@ -100,6 +101,36 @@ private:
>>    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
>>
>> Modified: llvm/trunk/lib/MC/MCObjectDisassembler.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCObjectDisassembler.cpp?rev=188886&r1=188885&r2=188886&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/MC/MCObjectDisassembler.cpp (original)
>> +++ llvm/trunk/lib/MC/MCObjectDisassembler.cpp Wed Aug 21 02:28:44 2013
>> @@ -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(MCMo
>>      }
>>    }
>>  }
>> +
>> +// 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);
>> +}
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list