diff options
Diffstat (limited to 'include/llvm/MC')
| -rw-r--r-- | include/llvm/MC/MCDisassembler.h | 57 | ||||
| -rw-r--r-- | include/llvm/MC/MCExternalSymbolizer.h | 58 | ||||
| -rw-r--r-- | include/llvm/MC/MCObjectSymbolizer.h | 74 | ||||
| -rw-r--r-- | include/llvm/MC/MCRelocationInfo.h | 55 | ||||
| -rw-r--r-- | include/llvm/MC/MCSymbolizer.h | 81 |
5 files changed, 294 insertions, 31 deletions
diff --git a/include/llvm/MC/MCDisassembler.h b/include/llvm/MC/MCDisassembler.h index 36fbcb0..5ad2d98 100644 --- a/include/llvm/MC/MCDisassembler.h +++ b/include/llvm/MC/MCDisassembler.h @@ -10,6 +10,9 @@ #define LLVM_MC_MCDISASSEMBLER_H #include "llvm-c/Disassembler.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/MC/MCSymbolizer.h" +#include "llvm/MC/MCRelocationInfo.h" #include "llvm/Support/DataTypes.h" namespace llvm { @@ -53,9 +56,8 @@ public: }; /// Constructor - Performs initial setup for the disassembler. - MCDisassembler(const MCSubtargetInfo &STI) : GetOpInfo(0), SymbolLookUp(0), - DisInfo(0), Ctx(0), - STI(STI), CommentStream(0) {} + MCDisassembler(const MCSubtargetInfo &STI) : STI(STI), Symbolizer(0), + CommentStream(0) {} virtual ~MCDisassembler(); @@ -82,39 +84,32 @@ public: raw_ostream &vStream, raw_ostream &cStream) const = 0; -private: - // - // Hooks for symbolic disassembly via the public 'C' interface. - // - // The function to get the symbolic information for operands. - LLVMOpInfoCallback GetOpInfo; - // The function to lookup a symbol name. - LLVMSymbolLookupCallback SymbolLookUp; - // The pointer to the block of symbolic information for above call back. - void *DisInfo; - // The assembly context for creating symbols and MCExprs in place of - // immediate operands when there is symbolic information. - MCContext *Ctx; protected: // Subtarget information, for instruction decoding predicates if required. const MCSubtargetInfo &STI; +private: + OwningPtr<MCSymbolizer> Symbolizer; + public: - void setupForSymbolicDisassembly(LLVMOpInfoCallback getOpInfo, - LLVMSymbolLookupCallback symbolLookUp, - void *disInfo, - MCContext *ctx) { - GetOpInfo = getOpInfo; - SymbolLookUp = symbolLookUp; - DisInfo = disInfo; - Ctx = ctx; - } - LLVMOpInfoCallback getLLVMOpInfoCallback() const { return GetOpInfo; } - LLVMSymbolLookupCallback getLLVMSymbolLookupCallback() const { - return SymbolLookUp; - } - void *getDisInfoBlock() const { return DisInfo; } - MCContext *getMCContext() const { return Ctx; } + // Helpers around MCSymbolizer + bool tryAddingSymbolicOperand(MCInst &Inst, + int64_t Value, + uint64_t Address, bool IsBranch, + uint64_t Offset, uint64_t InstSize) const; + + void tryAddingPcLoadReferenceComment(int64_t Value, uint64_t Address) const; + + /// Set \p Symzer as the current symbolizer. + /// This takes ownership of \p Symzer, and deletes the previously set one. + void setSymbolizer(OwningPtr<MCSymbolizer> &Symzer); + + /// Sets up an external symbolizer that uses the C API callbacks. + void setupForSymbolicDisassembly(LLVMOpInfoCallback GetOpInfo, + LLVMSymbolLookupCallback SymbolLookUp, + void *DisInfo, + MCContext *Ctx, + OwningPtr<MCRelocationInfo> &RelInfo); // Marked mutable because we cache it inside the disassembler, rather than // having to pass it around as an argument through all the autogenerated code. diff --git a/include/llvm/MC/MCExternalSymbolizer.h b/include/llvm/MC/MCExternalSymbolizer.h new file mode 100644 index 0000000..c942adc --- /dev/null +++ b/include/llvm/MC/MCExternalSymbolizer.h @@ -0,0 +1,58 @@ +//===-- llvm/MC/MCExternalSymbolizer.h - ------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declaration of the MCExternalSymbolizer class, which +// enables library users to provide callbacks (through the C API) to do the +// symbolization externally. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCEXTERNALSYMBOLIZER_H +#define LLVM_MC_MCEXTERNALSYMBOLIZER_H + +#include "llvm-c/Disassembler.h" +#include "llvm/MC/MCSymbolizer.h" + +namespace llvm { + +/// \brief Symbolize using user-provided, C API, callbacks. +/// +/// See llvm-c/Disassembler.h. +class MCExternalSymbolizer : public MCSymbolizer { + + /// \name Hooks for symbolic disassembly via the public 'C' interface. + /// @{ + /// The function to get the symbolic information for operands. + LLVMOpInfoCallback GetOpInfo; + /// The function to lookup a symbol name. + LLVMSymbolLookupCallback SymbolLookUp; + /// The pointer to the block of symbolic information for above call back. + void *DisInfo; + /// @} + +public: + MCExternalSymbolizer(MCContext &Ctx, + OwningPtr<MCRelocationInfo> &RelInfo, + LLVMOpInfoCallback getOpInfo, + LLVMSymbolLookupCallback symbolLookUp, + void *disInfo) + : MCSymbolizer(Ctx, RelInfo), + GetOpInfo(getOpInfo), SymbolLookUp(symbolLookUp), DisInfo(disInfo) {} + + bool tryAddingSymbolicOperand(MCInst &MI, raw_ostream &CommentStream, + int64_t Value, + uint64_t Address, bool IsBranch, + uint64_t Offset, uint64_t InstSize); + void tryAddingPcLoadReferenceComment(raw_ostream &CommentStream, + int64_t Value, uint64_t Address); +}; + +} + +#endif diff --git a/include/llvm/MC/MCObjectSymbolizer.h b/include/llvm/MC/MCObjectSymbolizer.h new file mode 100644 index 0000000..0e3a17b --- /dev/null +++ b/include/llvm/MC/MCObjectSymbolizer.h @@ -0,0 +1,74 @@ +//===-- llvm/MC/MCObjectSymbolizer.h --------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the MCObjectSymbolizer class, an MCSymbolizer that is +// backed by an object::ObjectFile. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCOBJECTSYMBOLIZER_H +#define LLVM_MC_MCOBJECTSYMBOLIZER_H + +#include "llvm/ADT/IntervalMap.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/MC/MCSymbolizer.h" +#include "llvm/Object/ObjectFile.h" + +namespace llvm { + +class MCExpr; +class MCInst; +class MCRelocationInfo; +class raw_ostream; + +/// \brief An ObjectFile-backed symbolizer. +class MCObjectSymbolizer : public MCSymbolizer { +protected: + const object::ObjectFile *Obj; + + typedef DenseMap<uint64_t, object::RelocationRef> AddrToRelocMap; + // FIXME: Working around a missing SectionRef operator!= by storing + // DataRefImpl.p instead of SectionRef. Feel free to improve! + typedef IntervalMap<uint64_t, uintptr_t> AddrToSectionMap; + + AddrToSectionMap::Allocator AddrToSectionAllocator; + AddrToSectionMap AddrToSection; + + // Map a load address to the first relocation that applies there. As far as I + // know, if there are several relocations at the exact same address, they are + // related and the others can be determined from the first that was found in + // the relocation table. For instance, on x86-64 mach-o, a SUBTRACTOR + // relocation (referencing the minuend symbol) is followed by an UNSIGNED + // relocation (referencing the subtrahend symbol). + AddrToRelocMap AddrToReloc; + + MCObjectSymbolizer(MCContext &Ctx, OwningPtr<MCRelocationInfo> &RelInfo, + const object::ObjectFile *Obj); + +public: + /// \name Overridden MCSymbolizer methods: + /// @{ + bool tryAddingSymbolicOperand(MCInst &MI, raw_ostream &cStream, + int64_t Value, + uint64_t Address, bool IsBranch, + uint64_t Offset, uint64_t InstSize); + + void tryAddingPcLoadReferenceComment(raw_ostream &cStream, + int64_t Value, uint64_t Address); + /// @} + + /// \brief Create an object symbolizer for \p Obj. + static MCObjectSymbolizer * + createObjectSymbolizer(MCContext &Ctx, OwningPtr<MCRelocationInfo> &RelInfo, + const object::ObjectFile *Obj); +}; + +} + +#endif diff --git a/include/llvm/MC/MCRelocationInfo.h b/include/llvm/MC/MCRelocationInfo.h new file mode 100644 index 0000000..9dab900 --- /dev/null +++ b/include/llvm/MC/MCRelocationInfo.h @@ -0,0 +1,55 @@ +//==-- llvm/MC/MCRelocationInfo.h --------------------------------*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the MCRelocationInfo class, which provides methods to +// create MCExprs from relocations, either found in an object::ObjectFile +// (object::RelocationRef), or provided through the C API. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCRELOCATIONINFO_H +#define LLVM_MC_MCRELOCATIONINFO_H + +#include "llvm/Support/Compiler.h" + +namespace llvm { + +namespace object { +class RelocationRef; +} +class MCExpr; +class MCContext; + +/// \brief Create MCExprs from relocations found in an object file. +class MCRelocationInfo { + MCRelocationInfo(const MCRelocationInfo &) LLVM_DELETED_FUNCTION; + void operator=(const MCRelocationInfo &) LLVM_DELETED_FUNCTION; + +protected: + MCContext &Ctx; + +public: + MCRelocationInfo(MCContext &Ctx); + virtual ~MCRelocationInfo(); + + /// \brief Create an MCExpr for the relocation \p Rel. + /// \returns If possible, an MCExpr corresponding to Rel, else 0. + virtual const MCExpr *createExprForRelocation(object::RelocationRef Rel); + + /// \brief Create an MCExpr for the target-specific \p VariantKind. + /// The VariantKinds are defined in llvm-c/Disassembler.h. + /// Used by MCExternalSymbolizer. + /// \returns If possible, an MCExpr corresponding to VariantKind, else 0. + virtual const MCExpr *createExprForCAPIVariantKind(const MCExpr *SubExpr, + unsigned VariantKind); +}; + +} + +#endif diff --git a/include/llvm/MC/MCSymbolizer.h b/include/llvm/MC/MCSymbolizer.h new file mode 100644 index 0000000..e42a214 --- /dev/null +++ b/include/llvm/MC/MCSymbolizer.h @@ -0,0 +1,81 @@ +//===-- llvm/MC/MCSymbolizer.h - MCSymbolizer class -------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declaration of the MCSymbolizer class, which is used +// to symbolize instructions decoded from an object, that is, transform their +// immediate operands to MCExprs. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCSYMBOLIZER_H +#define LLVM_MC_MCSYMBOLIZER_H + +#include "llvm/ADT/OwningPtr.h" +#include "llvm/MC/MCRelocationInfo.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/DataTypes.h" + +namespace llvm { + +class MCContext; +class MCInst; +class raw_ostream; + +/// \brief Symbolize and annotate disassembled instructions. +/// +/// For now this mimics the old symbolization logic (from both ARM and x86), that +/// relied on user-provided (C API) callbacks to do the actual symbol lookup in +/// the object file. This was moved to MCExternalSymbolizer. +/// A better API would not rely on actually calling the two methods here from +/// inside each disassembler, but would use the instr info to determine what +/// operands are actually symbolizable, and in what way. I don't think this +/// information exists right now. +class MCSymbolizer { + MCSymbolizer(const MCSymbolizer &) LLVM_DELETED_FUNCTION; + void operator=(const MCSymbolizer &) LLVM_DELETED_FUNCTION; + +protected: + MCContext &Ctx; + OwningPtr<MCRelocationInfo> RelInfo; + +public: + /// \brief Construct an MCSymbolizer, taking ownership of \p RelInfo. + MCSymbolizer(MCContext &Ctx, OwningPtr<MCRelocationInfo> &RelInfo); + virtual ~MCSymbolizer(); + + /// \brief Try to add a symbolic operand instead of \p Value to the MCInst. + /// + /// Instead of having a difficult to read immediate, a symbolic operand would + /// represent this immediate in a more understandable way, for instance as a + /// symbol or an offset from a symbol. Relocations can also be used to enrich + /// the symbolic expression. + /// @param Inst - The MCInst where to insert the symbolic operand. + /// @param cStream - Stream to print comments and annotations on. + /// @param Value - Operand value, pc-adjusted by the caller if necessary. + /// @param Address - Load address of the instruction. + /// @param IsBranch - Is the instruction a branch? + /// @param Offset - Byte offset of the operand inside the inst. + /// @param InstSize - Size of the instruction in bytes. + /// @return Whether a symbolic operand was added. + virtual bool tryAddingSymbolicOperand(MCInst &Inst, raw_ostream &cStream, + int64_t Value, uint64_t Address, + bool IsBranch, uint64_t Offset, + uint64_t InstSize) = 0; + + /// \brief Try to add a comment on the PC-relative load. + /// For instance, in Mach-O, this is used to add annotations to instructions + /// that use C string literals, as found in __cstring. + virtual void tryAddingPcLoadReferenceComment(raw_ostream &cStream, + int64_t Value, + uint64_t Address) = 0; +}; + +} + +#endif |
