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

David Blaikie dblaikie at gmail.com
Wed Aug 21 10:39:32 PDT 2013


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?

>
> 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