2011-08-24 18:08:43 +00:00
|
|
|
//===-- Support/TargetRegistry.h - Target Registration ----------*- C++ -*-===//
|
2009-07-15 04:24:58 +00:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file exposes the TargetRegistry interface, which tools can use to access
|
|
|
|
// the appropriate target specific classes (TargetMachine, AsmPrinter, etc.)
|
|
|
|
// which have been registered.
|
|
|
|
//
|
|
|
|
// Target specific class implementations should register themselves using the
|
|
|
|
// appropriate TargetRegistry interfaces.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2011-08-24 18:08:43 +00:00
|
|
|
#ifndef LLVM_SUPPORT_TARGETREGISTRY_H
|
|
|
|
#define LLVM_SUPPORT_TARGETREGISTRY_H
|
2009-07-15 04:24:58 +00:00
|
|
|
|
2014-01-07 11:48:04 +00:00
|
|
|
#include "llvm-c/Disassembler.h"
|
2009-07-26 05:03:33 +00:00
|
|
|
#include "llvm/ADT/Triple.h"
|
2012-12-03 17:02:12 +00:00
|
|
|
#include "llvm/Support/CodeGen.h"
|
2009-07-15 04:24:58 +00:00
|
|
|
#include <cassert>
|
2015-01-18 20:29:04 +00:00
|
|
|
#include <memory>
|
2012-12-03 17:02:12 +00:00
|
|
|
#include <string>
|
2009-07-15 04:24:58 +00:00
|
|
|
|
|
|
|
namespace llvm {
|
2009-08-13 23:48:47 +00:00
|
|
|
class AsmPrinter;
|
2009-07-15 04:24:58 +00:00
|
|
|
class Module;
|
2010-02-21 21:53:53 +00:00
|
|
|
class MCAssembler;
|
2011-07-26 00:24:13 +00:00
|
|
|
class MCAsmBackend;
|
2009-08-22 20:48:53 +00:00
|
|
|
class MCAsmInfo;
|
2010-02-02 23:37:42 +00:00
|
|
|
class MCAsmParser;
|
|
|
|
class MCCodeEmitter;
|
2011-07-26 00:24:13 +00:00
|
|
|
class MCCodeGenInfo;
|
2010-02-02 23:37:42 +00:00
|
|
|
class MCContext;
|
2009-09-09 22:49:13 +00:00
|
|
|
class MCDisassembler;
|
2011-08-23 20:15:21 +00:00
|
|
|
class MCInstrAnalysis;
|
2009-09-14 03:02:37 +00:00
|
|
|
class MCInstPrinter;
|
2011-06-28 20:29:03 +00:00
|
|
|
class MCInstrInfo;
|
2011-06-24 01:44:41 +00:00
|
|
|
class MCRegisterInfo;
|
2010-02-02 23:37:42 +00:00
|
|
|
class MCStreamer;
|
2011-07-09 05:47:46 +00:00
|
|
|
class MCSubtargetInfo;
|
2013-05-24 22:51:52 +00:00
|
|
|
class MCSymbolizer;
|
Add MCSymbolizer for symbolic/annotated disassembly.
This is a basic first step towards symbolization of disassembled
instructions. This used to be done using externally provided (C API)
callbacks. This patch introduces:
- the MCSymbolizer class, that mimics the same functions that were used
in the X86 and ARM disassemblers to symbolize immediate operands and
to annotate loads based off PC (for things like c string literals).
- the MCExternalSymbolizer class, which implements the old C API.
- the MCRelocationInfo class, which provides a way for targets to
translate relocations (either object::RelocationRef, or disassembler
C API VariantKinds) to MCExprs.
- the MCObjectSymbolizer class, which does symbolization using what it
finds in an object::ObjectFile. This makes simple symbolization (with
no fancy relocation stuff) work for all object formats!
- x86-64 Mach-O and ELF MCRelocationInfos.
- A basic ARM Mach-O MCRelocationInfo, that provides just enough to
support the C API VariantKinds.
Most of what works in otool (the only user of the old symbolization API
that I know of) for x86-64 symbolic disassembly (-tvV) works, namely:
- symbol references: call _foo; jmp 15 <_foo+50>
- relocations: call _foo-_bar; call _foo-4
- __cf?string: leaq 193(%rip), %rax ## literal pool for "hello"
Stub support is the main missing part (because libObject doesn't know,
among other things, about mach-o indirect symbols).
As for the MCSymbolizer API, instead of relying on the disassemblers
to call the tryAdding* methods, maybe this could be done automagically
using InstrInfo? For instance, even though PC-relative LEAs are used
to get the address of string literals in a typical Mach-O file, a MOV
would be used in an ELF file. And right now, the explicit symbolization
only recognizes PC-relative LEAs. InstrInfo should have already have
most of what is needed to know what to symbolize, so this can
definitely be improved.
I'd also like to remove object::RelocationRef::getValueString (it seems
only used by relocation printing in objdump), as simply printing the
created MCExpr is definitely enough (and cleaner than string concats).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182625 91177308-0d34-0410-b5e6-96231b3b80d8
2013-05-24 00:39:57 +00:00
|
|
|
class MCRelocationInfo;
|
2011-07-26 00:24:13 +00:00
|
|
|
class MCTargetAsmParser;
|
2014-04-23 11:16:03 +00:00
|
|
|
class MCTargetOptions;
|
2015-02-19 00:45:02 +00:00
|
|
|
class MCTargetStreamer;
|
2009-07-15 04:24:58 +00:00
|
|
|
class TargetMachine;
|
2011-12-02 22:16:29 +00:00
|
|
|
class TargetOptions;
|
2009-09-14 03:02:37 +00:00
|
|
|
class raw_ostream;
|
2010-11-08 02:21:17 +00:00
|
|
|
class formatted_raw_ostream;
|
|
|
|
|
2014-06-20 13:11:28 +00:00
|
|
|
MCStreamer *createNullStreamer(MCContext &Ctx);
|
2014-02-05 18:00:21 +00:00
|
|
|
MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
|
2014-05-07 13:00:43 +00:00
|
|
|
bool isVerboseAsm, bool useDwarfDirectory,
|
2013-10-08 13:08:17 +00:00
|
|
|
MCInstPrinter *InstPrint, MCCodeEmitter *CE,
|
|
|
|
MCAsmBackend *TAB, bool ShowInst);
|
2009-07-15 04:24:58 +00:00
|
|
|
|
2013-05-24 22:51:52 +00:00
|
|
|
MCRelocationInfo *createMCRelocationInfo(StringRef TT, MCContext &Ctx);
|
|
|
|
|
|
|
|
MCSymbolizer *createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
|
|
|
|
LLVMSymbolLookupCallback SymbolLookUp,
|
2015-01-18 20:45:48 +00:00
|
|
|
void *DisInfo, MCContext *Ctx,
|
|
|
|
std::unique_ptr<MCRelocationInfo> &&RelInfo);
|
Add MCSymbolizer for symbolic/annotated disassembly.
This is a basic first step towards symbolization of disassembled
instructions. This used to be done using externally provided (C API)
callbacks. This patch introduces:
- the MCSymbolizer class, that mimics the same functions that were used
in the X86 and ARM disassemblers to symbolize immediate operands and
to annotate loads based off PC (for things like c string literals).
- the MCExternalSymbolizer class, which implements the old C API.
- the MCRelocationInfo class, which provides a way for targets to
translate relocations (either object::RelocationRef, or disassembler
C API VariantKinds) to MCExprs.
- the MCObjectSymbolizer class, which does symbolization using what it
finds in an object::ObjectFile. This makes simple symbolization (with
no fancy relocation stuff) work for all object formats!
- x86-64 Mach-O and ELF MCRelocationInfos.
- A basic ARM Mach-O MCRelocationInfo, that provides just enough to
support the C API VariantKinds.
Most of what works in otool (the only user of the old symbolization API
that I know of) for x86-64 symbolic disassembly (-tvV) works, namely:
- symbol references: call _foo; jmp 15 <_foo+50>
- relocations: call _foo-_bar; call _foo-4
- __cf?string: leaq 193(%rip), %rax ## literal pool for "hello"
Stub support is the main missing part (because libObject doesn't know,
among other things, about mach-o indirect symbols).
As for the MCSymbolizer API, instead of relying on the disassemblers
to call the tryAdding* methods, maybe this could be done automagically
using InstrInfo? For instance, even though PC-relative LEAs are used
to get the address of string literals in a typical Mach-O file, a MOV
would be used in an ELF file. And right now, the explicit symbolization
only recognizes PC-relative LEAs. InstrInfo should have already have
most of what is needed to know what to symbolize, so this can
definitely be improved.
I'd also like to remove object::RelocationRef::getValueString (it seems
only used by relocation printing in objdump), as simply printing the
created MCExpr is definitely enough (and cleaner than string concats).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182625 91177308-0d34-0410-b5e6-96231b3b80d8
2013-05-24 00:39:57 +00:00
|
|
|
|
2009-07-15 04:24:58 +00:00
|
|
|
/// Target - Wrapper for Target specific information.
|
|
|
|
///
|
|
|
|
/// For registration purposes, this is a POD type so that targets can be
|
|
|
|
/// registered without the use of static constructors.
|
2009-07-15 07:09:29 +00:00
|
|
|
///
|
|
|
|
/// Targets should implement a single global instance of this class (which
|
|
|
|
/// will be zero initialized), and pass that instance to the TargetRegistry as
|
|
|
|
/// part of their initialization.
|
|
|
|
class Target {
|
2009-08-12 07:22:17 +00:00
|
|
|
public:
|
|
|
|
friend struct TargetRegistry;
|
|
|
|
|
2013-12-13 16:05:32 +00:00
|
|
|
typedef bool (*ArchMatchFnTy)(Triple::ArchType Arch);
|
2009-07-15 04:24:58 +00:00
|
|
|
|
2013-05-13 01:16:13 +00:00
|
|
|
typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const MCRegisterInfo &MRI,
|
|
|
|
StringRef TT);
|
2011-07-20 07:51:56 +00:00
|
|
|
typedef MCCodeGenInfo *(*MCCodeGenInfoCtorFnTy)(StringRef TT,
|
|
|
|
Reloc::Model RM,
|
2011-11-16 08:38:26 +00:00
|
|
|
CodeModel::Model CM,
|
|
|
|
CodeGenOpt::Level OL);
|
2011-06-28 20:29:03 +00:00
|
|
|
typedef MCInstrInfo *(*MCInstrInfoCtorFnTy)(void);
|
2011-08-08 18:56:44 +00:00
|
|
|
typedef MCInstrAnalysis *(*MCInstrAnalysisCtorFnTy)(const MCInstrInfo*Info);
|
2011-07-18 20:57:22 +00:00
|
|
|
typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(StringRef TT);
|
2011-07-09 05:47:46 +00:00
|
|
|
typedef MCSubtargetInfo *(*MCSubtargetInfoCtorFnTy)(StringRef TT,
|
|
|
|
StringRef CPU,
|
|
|
|
StringRef Features);
|
2009-08-12 07:22:17 +00:00
|
|
|
typedef TargetMachine *(*TargetMachineCtorTy)(const Target &T,
|
2011-07-19 06:37:02 +00:00
|
|
|
StringRef TT,
|
|
|
|
StringRef CPU,
|
|
|
|
StringRef Features,
|
2011-12-02 22:16:29 +00:00
|
|
|
const TargetOptions &Options,
|
2011-07-20 07:51:56 +00:00
|
|
|
Reloc::Model RM,
|
2011-11-16 08:38:26 +00:00
|
|
|
CodeModel::Model CM,
|
|
|
|
CodeGenOpt::Level OL);
|
2015-01-18 20:29:04 +00:00
|
|
|
// If it weren't for layering issues (this header is in llvm/Support, but
|
|
|
|
// depends on MC?) this should take the Streamer by value rather than rvalue
|
|
|
|
// reference.
|
|
|
|
typedef AsmPrinter *(*AsmPrinterCtorTy)(
|
|
|
|
TargetMachine &TM, std::unique_ptr<MCStreamer> &&Streamer);
|
2012-09-18 16:08:49 +00:00
|
|
|
typedef MCAsmBackend *(*MCAsmBackendCtorTy)(const Target &T,
|
2013-09-09 02:37:14 +00:00
|
|
|
const MCRegisterInfo &MRI,
|
2012-09-18 16:08:49 +00:00
|
|
|
StringRef TT,
|
|
|
|
StringRef CPU);
|
2014-04-23 11:16:03 +00:00
|
|
|
typedef MCTargetAsmParser *(*MCAsmParserCtorTy)(
|
|
|
|
MCSubtargetInfo &STI,
|
|
|
|
MCAsmParser &P,
|
|
|
|
const MCInstrInfo &MII,
|
|
|
|
const MCTargetOptions &Options);
|
2011-09-07 17:24:38 +00:00
|
|
|
typedef MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T,
|
2014-04-15 04:40:56 +00:00
|
|
|
const MCSubtargetInfo &STI,
|
|
|
|
MCContext &Ctx);
|
2009-09-14 03:02:37 +00:00
|
|
|
typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T,
|
|
|
|
unsigned SyntaxVariant,
|
2011-09-07 17:24:38 +00:00
|
|
|
const MCAsmInfo &MAI,
|
2012-04-02 06:09:36 +00:00
|
|
|
const MCInstrInfo &MII,
|
2012-03-05 19:33:20 +00:00
|
|
|
const MCRegisterInfo &MRI,
|
2011-09-07 17:24:38 +00:00
|
|
|
const MCSubtargetInfo &STI);
|
2011-07-26 00:42:34 +00:00
|
|
|
typedef MCCodeEmitter *(*MCCodeEmitterCtorTy)(const MCInstrInfo &II,
|
2012-05-15 17:35:52 +00:00
|
|
|
const MCRegisterInfo &MRI,
|
2011-07-26 00:42:34 +00:00
|
|
|
MCContext &Ctx);
|
2014-10-15 16:12:52 +00:00
|
|
|
typedef MCStreamer *(*MCObjectStreamerCtorTy)(
|
|
|
|
const Target &T, StringRef TT, MCContext &Ctx, MCAsmBackend &TAB,
|
2015-03-16 18:06:57 +00:00
|
|
|
raw_ostream &OS, MCCodeEmitter *Emitter, const MCSubtargetInfo &STI,
|
2014-10-15 16:12:52 +00:00
|
|
|
bool RelaxAll);
|
2010-11-08 02:21:17 +00:00
|
|
|
typedef MCStreamer *(*AsmStreamerCtorTy)(MCContext &Ctx,
|
|
|
|
formatted_raw_ostream &OS,
|
|
|
|
bool isVerboseAsm,
|
2011-10-17 23:05:28 +00:00
|
|
|
bool useDwarfDirectory,
|
2010-11-08 02:21:17 +00:00
|
|
|
MCInstPrinter *InstPrint,
|
|
|
|
MCCodeEmitter *CE,
|
2011-07-25 23:24:55 +00:00
|
|
|
MCAsmBackend *TAB,
|
2011-06-17 20:55:01 +00:00
|
|
|
bool ShowInst);
|
2015-02-19 00:45:02 +00:00
|
|
|
typedef MCTargetStreamer *(*NullTargetStreamerCtorTy)(MCStreamer &S);
|
Add MCSymbolizer for symbolic/annotated disassembly.
This is a basic first step towards symbolization of disassembled
instructions. This used to be done using externally provided (C API)
callbacks. This patch introduces:
- the MCSymbolizer class, that mimics the same functions that were used
in the X86 and ARM disassemblers to symbolize immediate operands and
to annotate loads based off PC (for things like c string literals).
- the MCExternalSymbolizer class, which implements the old C API.
- the MCRelocationInfo class, which provides a way for targets to
translate relocations (either object::RelocationRef, or disassembler
C API VariantKinds) to MCExprs.
- the MCObjectSymbolizer class, which does symbolization using what it
finds in an object::ObjectFile. This makes simple symbolization (with
no fancy relocation stuff) work for all object formats!
- x86-64 Mach-O and ELF MCRelocationInfos.
- A basic ARM Mach-O MCRelocationInfo, that provides just enough to
support the C API VariantKinds.
Most of what works in otool (the only user of the old symbolization API
that I know of) for x86-64 symbolic disassembly (-tvV) works, namely:
- symbol references: call _foo; jmp 15 <_foo+50>
- relocations: call _foo-_bar; call _foo-4
- __cf?string: leaq 193(%rip), %rax ## literal pool for "hello"
Stub support is the main missing part (because libObject doesn't know,
among other things, about mach-o indirect symbols).
As for the MCSymbolizer API, instead of relying on the disassemblers
to call the tryAdding* methods, maybe this could be done automagically
using InstrInfo? For instance, even though PC-relative LEAs are used
to get the address of string literals in a typical Mach-O file, a MOV
would be used in an ELF file. And right now, the explicit symbolization
only recognizes PC-relative LEAs. InstrInfo should have already have
most of what is needed to know what to symbolize, so this can
definitely be improved.
I'd also like to remove object::RelocationRef::getValueString (it seems
only used by relocation printing in objdump), as simply printing the
created MCExpr is definitely enough (and cleaner than string concats).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182625 91177308-0d34-0410-b5e6-96231b3b80d8
2013-05-24 00:39:57 +00:00
|
|
|
typedef MCRelocationInfo *(*MCRelocationInfoCtorTy)(StringRef TT,
|
|
|
|
MCContext &Ctx);
|
2015-01-18 20:45:48 +00:00
|
|
|
typedef MCSymbolizer *(*MCSymbolizerCtorTy)(
|
|
|
|
StringRef TT, LLVMOpInfoCallback GetOpInfo,
|
|
|
|
LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo, MCContext *Ctx,
|
|
|
|
std::unique_ptr<MCRelocationInfo> &&RelInfo);
|
2009-08-27 00:51:57 +00:00
|
|
|
|
2009-08-12 07:22:17 +00:00
|
|
|
private:
|
2009-07-15 04:24:58 +00:00
|
|
|
/// Next - The next registered target in the linked list, maintained by the
|
|
|
|
/// TargetRegistry.
|
|
|
|
Target *Next;
|
|
|
|
|
2013-12-13 16:05:32 +00:00
|
|
|
/// The target function for checking if an architecture is supported.
|
|
|
|
ArchMatchFnTy ArchMatchFn;
|
2009-07-15 04:24:58 +00:00
|
|
|
|
|
|
|
/// Name - The target name.
|
|
|
|
const char *Name;
|
|
|
|
|
|
|
|
/// ShortDesc - A short description of the target.
|
|
|
|
const char *ShortDesc;
|
|
|
|
|
2009-07-25 10:09:50 +00:00
|
|
|
/// HasJIT - Whether this target supports the JIT.
|
|
|
|
bool HasJIT;
|
|
|
|
|
2011-07-14 23:50:31 +00:00
|
|
|
/// MCAsmInfoCtorFn - Constructor function for this target's MCAsmInfo, if
|
2011-06-24 01:44:41 +00:00
|
|
|
/// registered.
|
2011-07-14 23:50:31 +00:00
|
|
|
MCAsmInfoCtorFnTy MCAsmInfoCtorFn;
|
2010-02-21 21:53:37 +00:00
|
|
|
|
2011-11-16 08:38:26 +00:00
|
|
|
/// MCCodeGenInfoCtorFn - Constructor function for this target's
|
|
|
|
/// MCCodeGenInfo, if registered.
|
2011-07-19 06:37:02 +00:00
|
|
|
MCCodeGenInfoCtorFnTy MCCodeGenInfoCtorFn;
|
|
|
|
|
2011-06-28 20:29:03 +00:00
|
|
|
/// MCInstrInfoCtorFn - Constructor function for this target's MCInstrInfo,
|
|
|
|
/// if registered.
|
|
|
|
MCInstrInfoCtorFnTy MCInstrInfoCtorFn;
|
|
|
|
|
2011-08-08 18:56:44 +00:00
|
|
|
/// MCInstrAnalysisCtorFn - Constructor function for this target's
|
|
|
|
/// MCInstrAnalysis, if registered.
|
|
|
|
MCInstrAnalysisCtorFnTy MCInstrAnalysisCtorFn;
|
|
|
|
|
2011-06-24 20:42:09 +00:00
|
|
|
/// MCRegInfoCtorFn - Constructor function for this target's MCRegisterInfo,
|
2011-06-24 01:44:41 +00:00
|
|
|
/// if registered.
|
2011-06-24 20:42:09 +00:00
|
|
|
MCRegInfoCtorFnTy MCRegInfoCtorFn;
|
2011-06-24 01:44:41 +00:00
|
|
|
|
2011-07-09 05:47:46 +00:00
|
|
|
/// MCSubtargetInfoCtorFn - Constructor function for this target's
|
|
|
|
/// MCSubtargetInfo, if registered.
|
|
|
|
MCSubtargetInfoCtorFnTy MCSubtargetInfoCtorFn;
|
|
|
|
|
2009-07-15 04:24:58 +00:00
|
|
|
/// TargetMachineCtorFn - Construction function for this target's
|
|
|
|
/// TargetMachine, if registered.
|
|
|
|
TargetMachineCtorTy TargetMachineCtorFn;
|
|
|
|
|
2011-07-25 23:24:55 +00:00
|
|
|
/// MCAsmBackendCtorFn - Construction function for this target's
|
|
|
|
/// MCAsmBackend, if registered.
|
|
|
|
MCAsmBackendCtorTy MCAsmBackendCtorFn;
|
2010-02-21 21:53:53 +00:00
|
|
|
|
2011-07-26 00:24:13 +00:00
|
|
|
/// MCAsmParserCtorFn - Construction function for this target's
|
|
|
|
/// MCTargetAsmParser, if registered.
|
|
|
|
MCAsmParserCtorTy MCAsmParserCtorFn;
|
2010-02-21 21:53:37 +00:00
|
|
|
|
|
|
|
/// AsmPrinterCtorFn - Construction function for this target's AsmPrinter,
|
|
|
|
/// if registered.
|
|
|
|
AsmPrinterCtorTy AsmPrinterCtorFn;
|
|
|
|
|
2009-09-09 22:49:13 +00:00
|
|
|
/// MCDisassemblerCtorFn - Construction function for this target's
|
|
|
|
/// MCDisassembler, if registered.
|
|
|
|
MCDisassemblerCtorTy MCDisassemblerCtorFn;
|
2009-07-17 20:42:00 +00:00
|
|
|
|
2010-02-21 21:53:37 +00:00
|
|
|
/// MCInstPrinterCtorFn - Construction function for this target's
|
2009-09-14 03:02:37 +00:00
|
|
|
/// MCInstPrinter, if registered.
|
|
|
|
MCInstPrinterCtorTy MCInstPrinterCtorFn;
|
2010-02-21 21:53:37 +00:00
|
|
|
|
2011-07-26 00:42:34 +00:00
|
|
|
/// MCCodeEmitterCtorFn - Construction function for this target's
|
|
|
|
/// CodeEmitter, if registered.
|
|
|
|
MCCodeEmitterCtorTy MCCodeEmitterCtorFn;
|
2009-08-27 00:51:57 +00:00
|
|
|
|
2011-07-26 00:42:34 +00:00
|
|
|
/// MCObjectStreamerCtorFn - Construction function for this target's
|
|
|
|
/// MCObjectStreamer, if registered.
|
|
|
|
MCObjectStreamerCtorTy MCObjectStreamerCtorFn;
|
2010-05-21 12:54:43 +00:00
|
|
|
|
2010-11-08 02:21:17 +00:00
|
|
|
/// AsmStreamerCtorFn - Construction function for this target's
|
|
|
|
/// AsmStreamer, if registered (default = llvm::createAsmStreamer).
|
|
|
|
AsmStreamerCtorTy AsmStreamerCtorFn;
|
|
|
|
|
2015-02-19 00:45:02 +00:00
|
|
|
/// Construction function for this target's null TargetStreamer, if
|
|
|
|
/// registered (default = nullptr).
|
|
|
|
NullTargetStreamerCtorTy NullTargetStreamerCtorFn;
|
|
|
|
|
Add MCSymbolizer for symbolic/annotated disassembly.
This is a basic first step towards symbolization of disassembled
instructions. This used to be done using externally provided (C API)
callbacks. This patch introduces:
- the MCSymbolizer class, that mimics the same functions that were used
in the X86 and ARM disassemblers to symbolize immediate operands and
to annotate loads based off PC (for things like c string literals).
- the MCExternalSymbolizer class, which implements the old C API.
- the MCRelocationInfo class, which provides a way for targets to
translate relocations (either object::RelocationRef, or disassembler
C API VariantKinds) to MCExprs.
- the MCObjectSymbolizer class, which does symbolization using what it
finds in an object::ObjectFile. This makes simple symbolization (with
no fancy relocation stuff) work for all object formats!
- x86-64 Mach-O and ELF MCRelocationInfos.
- A basic ARM Mach-O MCRelocationInfo, that provides just enough to
support the C API VariantKinds.
Most of what works in otool (the only user of the old symbolization API
that I know of) for x86-64 symbolic disassembly (-tvV) works, namely:
- symbol references: call _foo; jmp 15 <_foo+50>
- relocations: call _foo-_bar; call _foo-4
- __cf?string: leaq 193(%rip), %rax ## literal pool for "hello"
Stub support is the main missing part (because libObject doesn't know,
among other things, about mach-o indirect symbols).
As for the MCSymbolizer API, instead of relying on the disassemblers
to call the tryAdding* methods, maybe this could be done automagically
using InstrInfo? For instance, even though PC-relative LEAs are used
to get the address of string literals in a typical Mach-O file, a MOV
would be used in an ELF file. And right now, the explicit symbolization
only recognizes PC-relative LEAs. InstrInfo should have already have
most of what is needed to know what to symbolize, so this can
definitely be improved.
I'd also like to remove object::RelocationRef::getValueString (it seems
only used by relocation printing in objdump), as simply printing the
created MCExpr is definitely enough (and cleaner than string concats).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182625 91177308-0d34-0410-b5e6-96231b3b80d8
2013-05-24 00:39:57 +00:00
|
|
|
/// MCRelocationInfoCtorFn - Construction function for this target's
|
|
|
|
/// MCRelocationInfo, if registered (default = llvm::createMCRelocationInfo)
|
|
|
|
MCRelocationInfoCtorTy MCRelocationInfoCtorFn;
|
|
|
|
|
2013-05-24 22:51:52 +00:00
|
|
|
/// MCSymbolizerCtorFn - Construction function for this target's
|
|
|
|
/// MCSymbolizer, if registered (default = llvm::createMCSymbolizer)
|
|
|
|
MCSymbolizerCtorTy MCSymbolizerCtorFn;
|
|
|
|
|
2009-07-15 04:24:58 +00:00
|
|
|
public:
|
2013-10-08 13:08:17 +00:00
|
|
|
Target()
|
2015-02-19 00:45:07 +00:00
|
|
|
: AsmStreamerCtorFn(nullptr), MCRelocationInfoCtorFn(nullptr),
|
|
|
|
MCSymbolizerCtorFn(nullptr) {}
|
2010-11-08 02:21:17 +00:00
|
|
|
|
2009-08-27 00:51:57 +00:00
|
|
|
/// @name Target Information
|
|
|
|
/// @{
|
|
|
|
|
2009-07-16 02:38:28 +00:00
|
|
|
// getNext - Return the next registered target.
|
|
|
|
const Target *getNext() const { return Next; }
|
|
|
|
|
2009-07-15 04:24:58 +00:00
|
|
|
/// getName - Get the target name.
|
|
|
|
const char *getName() const { return Name; }
|
|
|
|
|
|
|
|
/// getShortDescription - Get a short description of the target.
|
|
|
|
const char *getShortDescription() const { return ShortDesc; }
|
|
|
|
|
2009-08-27 00:51:57 +00:00
|
|
|
/// @}
|
|
|
|
/// @name Feature Predicates
|
|
|
|
/// @{
|
|
|
|
|
|
|
|
/// hasJIT - Check if this targets supports the just-in-time compilation.
|
2009-07-25 10:09:50 +00:00
|
|
|
bool hasJIT() const { return HasJIT; }
|
2009-07-15 20:24:03 +00:00
|
|
|
|
2009-07-16 02:06:09 +00:00
|
|
|
/// hasTargetMachine - Check if this target supports code generation.
|
2014-04-07 04:17:22 +00:00
|
|
|
bool hasTargetMachine() const { return TargetMachineCtorFn != nullptr; }
|
2009-07-16 02:06:09 +00:00
|
|
|
|
2011-07-25 23:24:55 +00:00
|
|
|
/// hasMCAsmBackend - Check if this target supports .o generation.
|
2014-04-07 04:17:22 +00:00
|
|
|
bool hasMCAsmBackend() const { return MCAsmBackendCtorFn != nullptr; }
|
2010-02-21 21:53:53 +00:00
|
|
|
|
2009-08-27 00:51:57 +00:00
|
|
|
/// @}
|
|
|
|
/// @name Feature Constructors
|
|
|
|
/// @{
|
2010-02-21 21:53:37 +00:00
|
|
|
|
2011-07-14 23:50:31 +00:00
|
|
|
/// createMCAsmInfo - Create a MCAsmInfo implementation for the specified
|
2009-08-12 07:22:17 +00:00
|
|
|
/// target triple.
|
|
|
|
///
|
2012-09-13 12:34:29 +00:00
|
|
|
/// \param Triple This argument is used to determine the target machine
|
2009-08-12 07:22:17 +00:00
|
|
|
/// feature set; it should always be provided. Generally this should be
|
|
|
|
/// either the target triple from the module, or the target triple of the
|
|
|
|
/// host if that does not exist.
|
2013-05-13 01:16:13 +00:00
|
|
|
MCAsmInfo *createMCAsmInfo(const MCRegisterInfo &MRI,
|
|
|
|
StringRef Triple) const {
|
2011-07-14 23:50:31 +00:00
|
|
|
if (!MCAsmInfoCtorFn)
|
2014-04-07 04:17:22 +00:00
|
|
|
return nullptr;
|
2013-05-13 01:16:13 +00:00
|
|
|
return MCAsmInfoCtorFn(MRI, Triple);
|
2009-08-12 07:22:17 +00:00
|
|
|
}
|
2010-02-21 21:53:37 +00:00
|
|
|
|
2011-07-19 06:37:02 +00:00
|
|
|
/// createMCCodeGenInfo - Create a MCCodeGenInfo implementation.
|
|
|
|
///
|
2011-07-20 07:51:56 +00:00
|
|
|
MCCodeGenInfo *createMCCodeGenInfo(StringRef Triple, Reloc::Model RM,
|
2011-11-16 08:38:26 +00:00
|
|
|
CodeModel::Model CM,
|
|
|
|
CodeGenOpt::Level OL) const {
|
2011-07-19 06:37:02 +00:00
|
|
|
if (!MCCodeGenInfoCtorFn)
|
2014-04-07 04:17:22 +00:00
|
|
|
return nullptr;
|
2011-11-16 08:38:26 +00:00
|
|
|
return MCCodeGenInfoCtorFn(Triple, RM, CM, OL);
|
2011-07-19 06:37:02 +00:00
|
|
|
}
|
|
|
|
|
2011-06-28 20:29:03 +00:00
|
|
|
/// createMCInstrInfo - Create a MCInstrInfo implementation.
|
|
|
|
///
|
|
|
|
MCInstrInfo *createMCInstrInfo() const {
|
|
|
|
if (!MCInstrInfoCtorFn)
|
2014-04-07 04:17:22 +00:00
|
|
|
return nullptr;
|
2011-06-28 20:29:03 +00:00
|
|
|
return MCInstrInfoCtorFn();
|
|
|
|
}
|
|
|
|
|
2011-08-08 18:56:44 +00:00
|
|
|
/// createMCInstrAnalysis - Create a MCInstrAnalysis implementation.
|
|
|
|
///
|
|
|
|
MCInstrAnalysis *createMCInstrAnalysis(const MCInstrInfo *Info) const {
|
|
|
|
if (!MCInstrAnalysisCtorFn)
|
2014-04-07 04:17:22 +00:00
|
|
|
return nullptr;
|
2011-08-08 18:56:44 +00:00
|
|
|
return MCInstrAnalysisCtorFn(Info);
|
|
|
|
}
|
|
|
|
|
2011-06-24 20:42:09 +00:00
|
|
|
/// createMCRegInfo - Create a MCRegisterInfo implementation.
|
2011-06-24 01:44:41 +00:00
|
|
|
///
|
2011-07-18 20:57:22 +00:00
|
|
|
MCRegisterInfo *createMCRegInfo(StringRef Triple) const {
|
2011-06-24 20:42:09 +00:00
|
|
|
if (!MCRegInfoCtorFn)
|
2014-04-07 04:17:22 +00:00
|
|
|
return nullptr;
|
2011-07-18 20:57:22 +00:00
|
|
|
return MCRegInfoCtorFn(Triple);
|
2011-06-24 01:44:41 +00:00
|
|
|
}
|
|
|
|
|
2011-07-09 05:47:46 +00:00
|
|
|
/// createMCSubtargetInfo - Create a MCSubtargetInfo implementation.
|
|
|
|
///
|
2012-09-13 12:34:29 +00:00
|
|
|
/// \param Triple This argument is used to determine the target machine
|
2011-07-09 05:47:46 +00:00
|
|
|
/// feature set; it should always be provided. Generally this should be
|
|
|
|
/// either the target triple from the module, or the target triple of the
|
|
|
|
/// host if that does not exist.
|
2012-09-13 12:34:29 +00:00
|
|
|
/// \param CPU This specifies the name of the target CPU.
|
|
|
|
/// \param Features This specifies the string representation of the
|
2011-07-09 05:47:46 +00:00
|
|
|
/// additional target features.
|
|
|
|
MCSubtargetInfo *createMCSubtargetInfo(StringRef Triple, StringRef CPU,
|
|
|
|
StringRef Features) const {
|
|
|
|
if (!MCSubtargetInfoCtorFn)
|
2014-04-07 04:17:22 +00:00
|
|
|
return nullptr;
|
2011-07-09 05:47:46 +00:00
|
|
|
return MCSubtargetInfoCtorFn(Triple, CPU, Features);
|
|
|
|
}
|
|
|
|
|
2009-08-03 04:03:51 +00:00
|
|
|
/// createTargetMachine - Create a target specific machine implementation
|
2012-09-13 12:34:29 +00:00
|
|
|
/// for the specified \p Triple.
|
2009-08-03 04:03:51 +00:00
|
|
|
///
|
2012-09-13 12:34:29 +00:00
|
|
|
/// \param Triple This argument is used to determine the target machine
|
2009-08-03 04:03:51 +00:00
|
|
|
/// feature set; it should always be provided. Generally this should be
|
|
|
|
/// either the target triple from the module, or the target triple of the
|
|
|
|
/// host if that does not exist.
|
2011-07-19 06:37:02 +00:00
|
|
|
TargetMachine *createTargetMachine(StringRef Triple, StringRef CPU,
|
2011-12-02 22:16:29 +00:00
|
|
|
StringRef Features, const TargetOptions &Options,
|
2011-11-16 08:38:26 +00:00
|
|
|
Reloc::Model RM = Reloc::Default,
|
|
|
|
CodeModel::Model CM = CodeModel::Default,
|
|
|
|
CodeGenOpt::Level OL = CodeGenOpt::Default) const {
|
2009-07-15 04:24:58 +00:00
|
|
|
if (!TargetMachineCtorFn)
|
2014-04-07 04:17:22 +00:00
|
|
|
return nullptr;
|
2011-12-02 22:16:29 +00:00
|
|
|
return TargetMachineCtorFn(*this, Triple, CPU, Features, Options,
|
|
|
|
RM, CM, OL);
|
2009-08-04 04:02:45 +00:00
|
|
|
}
|
2009-07-15 04:24:58 +00:00
|
|
|
|
2011-07-25 23:24:55 +00:00
|
|
|
/// createMCAsmBackend - Create a target specific assembly parser.
|
2010-02-21 21:53:53 +00:00
|
|
|
///
|
2012-09-13 12:34:29 +00:00
|
|
|
/// \param Triple The target triple string.
|
2013-09-09 02:37:14 +00:00
|
|
|
MCAsmBackend *createMCAsmBackend(const MCRegisterInfo &MRI,
|
|
|
|
StringRef Triple, StringRef CPU) const {
|
2011-07-25 23:24:55 +00:00
|
|
|
if (!MCAsmBackendCtorFn)
|
2014-04-07 04:17:22 +00:00
|
|
|
return nullptr;
|
2013-09-09 02:37:14 +00:00
|
|
|
return MCAsmBackendCtorFn(*this, MRI, Triple, CPU);
|
2010-02-21 21:53:53 +00:00
|
|
|
}
|
|
|
|
|
2011-07-26 00:24:13 +00:00
|
|
|
/// createMCAsmParser - Create a target specific assembly parser.
|
2009-07-28 20:47:52 +00:00
|
|
|
///
|
2012-09-13 12:34:29 +00:00
|
|
|
/// \param Parser The target independent parser implementation to use for
|
2009-07-28 20:47:52 +00:00
|
|
|
/// parsing and lexing.
|
2014-04-23 11:16:03 +00:00
|
|
|
MCTargetAsmParser *createMCAsmParser(
|
|
|
|
MCSubtargetInfo &STI,
|
|
|
|
MCAsmParser &Parser,
|
|
|
|
const MCInstrInfo &MII,
|
|
|
|
const MCTargetOptions &Options) const {
|
2011-07-26 00:24:13 +00:00
|
|
|
if (!MCAsmParserCtorFn)
|
2014-04-07 04:17:22 +00:00
|
|
|
return nullptr;
|
2014-04-23 11:16:03 +00:00
|
|
|
return MCAsmParserCtorFn(STI, Parser, MII, Options);
|
2009-07-17 20:42:00 +00:00
|
|
|
}
|
2010-02-21 21:53:37 +00:00
|
|
|
|
|
|
|
/// createAsmPrinter - Create a target specific assembly printer pass. This
|
2010-03-13 20:55:24 +00:00
|
|
|
/// takes ownership of the MCStreamer object.
|
2015-01-18 20:29:04 +00:00
|
|
|
AsmPrinter *createAsmPrinter(TargetMachine &TM,
|
2015-01-18 20:43:57 +00:00
|
|
|
std::unique_ptr<MCStreamer> &&Streamer) const {
|
2010-02-21 21:53:37 +00:00
|
|
|
if (!AsmPrinterCtorFn)
|
2014-04-07 04:17:22 +00:00
|
|
|
return nullptr;
|
2015-01-18 20:29:04 +00:00
|
|
|
return AsmPrinterCtorFn(TM, std::move(Streamer));
|
2010-02-21 21:53:37 +00:00
|
|
|
}
|
|
|
|
|
2014-04-15 04:40:56 +00:00
|
|
|
MCDisassembler *createMCDisassembler(const MCSubtargetInfo &STI,
|
|
|
|
MCContext &Ctx) const {
|
2009-09-09 22:49:13 +00:00
|
|
|
if (!MCDisassemblerCtorFn)
|
2014-04-07 04:17:22 +00:00
|
|
|
return nullptr;
|
2014-04-15 04:40:56 +00:00
|
|
|
return MCDisassemblerCtorFn(*this, STI, Ctx);
|
2009-09-09 22:49:13 +00:00
|
|
|
}
|
2009-08-27 00:51:57 +00:00
|
|
|
|
2011-07-06 19:45:42 +00:00
|
|
|
MCInstPrinter *createMCInstPrinter(unsigned SyntaxVariant,
|
2011-09-07 17:24:38 +00:00
|
|
|
const MCAsmInfo &MAI,
|
2012-04-02 06:09:36 +00:00
|
|
|
const MCInstrInfo &MII,
|
2012-03-05 19:33:20 +00:00
|
|
|
const MCRegisterInfo &MRI,
|
2011-09-07 17:24:38 +00:00
|
|
|
const MCSubtargetInfo &STI) const {
|
2009-09-14 03:02:37 +00:00
|
|
|
if (!MCInstPrinterCtorFn)
|
2014-04-07 04:17:22 +00:00
|
|
|
return nullptr;
|
2012-04-02 06:09:36 +00:00
|
|
|
return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI, MII, MRI, STI);
|
2009-09-14 03:02:37 +00:00
|
|
|
}
|
2010-02-21 21:53:37 +00:00
|
|
|
|
|
|
|
|
2011-07-26 00:42:34 +00:00
|
|
|
/// createMCCodeEmitter - Create a target specific code emitter.
|
|
|
|
MCCodeEmitter *createMCCodeEmitter(const MCInstrInfo &II,
|
2012-05-15 17:35:52 +00:00
|
|
|
const MCRegisterInfo &MRI,
|
2011-07-26 00:42:34 +00:00
|
|
|
MCContext &Ctx) const {
|
|
|
|
if (!MCCodeEmitterCtorFn)
|
2014-04-07 04:17:22 +00:00
|
|
|
return nullptr;
|
2015-03-10 22:03:14 +00:00
|
|
|
return MCCodeEmitterCtorFn(II, MRI, Ctx);
|
2009-08-27 00:51:57 +00:00
|
|
|
}
|
|
|
|
|
2011-07-26 00:42:34 +00:00
|
|
|
/// createMCObjectStreamer - Create a target specific MCStreamer.
|
2010-05-21 12:54:43 +00:00
|
|
|
///
|
2012-09-13 12:34:29 +00:00
|
|
|
/// \param TT The target triple.
|
|
|
|
/// \param Ctx The target context.
|
|
|
|
/// \param TAB The target assembler backend object. Takes ownership.
|
2015-03-16 18:06:57 +00:00
|
|
|
/// \param OS The stream object.
|
|
|
|
/// \param Emitter The target independent assembler object.Takes ownership.
|
2012-09-13 12:34:29 +00:00
|
|
|
/// \param RelaxAll Relax all fixups?
|
2011-07-26 00:42:34 +00:00
|
|
|
MCStreamer *createMCObjectStreamer(StringRef TT, MCContext &Ctx,
|
2015-03-16 18:06:57 +00:00
|
|
|
MCAsmBackend &TAB, raw_ostream &OS,
|
|
|
|
MCCodeEmitter *Emitter,
|
2014-01-26 06:38:58 +00:00
|
|
|
const MCSubtargetInfo &STI,
|
2014-10-15 16:12:52 +00:00
|
|
|
bool RelaxAll) const {
|
2011-07-26 00:42:34 +00:00
|
|
|
if (!MCObjectStreamerCtorFn)
|
2014-04-07 04:17:22 +00:00
|
|
|
return nullptr;
|
2015-03-16 18:06:57 +00:00
|
|
|
return MCObjectStreamerCtorFn(*this, TT, Ctx, TAB, OS, Emitter, STI,
|
2014-10-15 16:12:52 +00:00
|
|
|
RelaxAll);
|
2010-05-21 12:54:43 +00:00
|
|
|
}
|
|
|
|
|
2010-11-08 02:21:17 +00:00
|
|
|
/// createAsmStreamer - Create a target specific MCStreamer.
|
|
|
|
MCStreamer *createAsmStreamer(MCContext &Ctx,
|
|
|
|
formatted_raw_ostream &OS,
|
|
|
|
bool isVerboseAsm,
|
2011-10-17 23:05:28 +00:00
|
|
|
bool useDwarfDirectory,
|
2010-11-08 02:21:17 +00:00
|
|
|
MCInstPrinter *InstPrint,
|
|
|
|
MCCodeEmitter *CE,
|
2011-07-25 23:24:55 +00:00
|
|
|
MCAsmBackend *TAB,
|
2011-06-17 20:55:01 +00:00
|
|
|
bool ShowInst) const {
|
2013-10-16 16:21:40 +00:00
|
|
|
if (AsmStreamerCtorFn)
|
2014-05-07 13:00:43 +00:00
|
|
|
return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useDwarfDirectory,
|
|
|
|
InstPrint, CE, TAB, ShowInst);
|
|
|
|
return llvm::createAsmStreamer(Ctx, OS, isVerboseAsm, useDwarfDirectory,
|
|
|
|
InstPrint, CE, TAB, ShowInst);
|
2010-11-08 02:21:17 +00:00
|
|
|
}
|
|
|
|
|
2014-06-20 13:11:28 +00:00
|
|
|
MCStreamer *createNullStreamer(MCContext &Ctx) const {
|
2015-02-19 00:45:07 +00:00
|
|
|
MCStreamer *S = llvm::createNullStreamer(Ctx);
|
|
|
|
createNullTargetStreamer(*S);
|
|
|
|
return S;
|
2014-06-20 13:11:28 +00:00
|
|
|
}
|
|
|
|
|
2015-02-19 00:45:02 +00:00
|
|
|
MCTargetStreamer *createNullTargetStreamer(MCStreamer &S) const {
|
|
|
|
if (NullTargetStreamerCtorFn)
|
|
|
|
return NullTargetStreamerCtorFn(S);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
Add MCSymbolizer for symbolic/annotated disassembly.
This is a basic first step towards symbolization of disassembled
instructions. This used to be done using externally provided (C API)
callbacks. This patch introduces:
- the MCSymbolizer class, that mimics the same functions that were used
in the X86 and ARM disassemblers to symbolize immediate operands and
to annotate loads based off PC (for things like c string literals).
- the MCExternalSymbolizer class, which implements the old C API.
- the MCRelocationInfo class, which provides a way for targets to
translate relocations (either object::RelocationRef, or disassembler
C API VariantKinds) to MCExprs.
- the MCObjectSymbolizer class, which does symbolization using what it
finds in an object::ObjectFile. This makes simple symbolization (with
no fancy relocation stuff) work for all object formats!
- x86-64 Mach-O and ELF MCRelocationInfos.
- A basic ARM Mach-O MCRelocationInfo, that provides just enough to
support the C API VariantKinds.
Most of what works in otool (the only user of the old symbolization API
that I know of) for x86-64 symbolic disassembly (-tvV) works, namely:
- symbol references: call _foo; jmp 15 <_foo+50>
- relocations: call _foo-_bar; call _foo-4
- __cf?string: leaq 193(%rip), %rax ## literal pool for "hello"
Stub support is the main missing part (because libObject doesn't know,
among other things, about mach-o indirect symbols).
As for the MCSymbolizer API, instead of relying on the disassemblers
to call the tryAdding* methods, maybe this could be done automagically
using InstrInfo? For instance, even though PC-relative LEAs are used
to get the address of string literals in a typical Mach-O file, a MOV
would be used in an ELF file. And right now, the explicit symbolization
only recognizes PC-relative LEAs. InstrInfo should have already have
most of what is needed to know what to symbolize, so this can
definitely be improved.
I'd also like to remove object::RelocationRef::getValueString (it seems
only used by relocation printing in objdump), as simply printing the
created MCExpr is definitely enough (and cleaner than string concats).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182625 91177308-0d34-0410-b5e6-96231b3b80d8
2013-05-24 00:39:57 +00:00
|
|
|
/// createMCRelocationInfo - Create a target specific MCRelocationInfo.
|
|
|
|
///
|
|
|
|
/// \param TT The target triple.
|
|
|
|
/// \param Ctx The target context.
|
|
|
|
MCRelocationInfo *
|
|
|
|
createMCRelocationInfo(StringRef TT, MCContext &Ctx) const {
|
2013-10-16 16:21:40 +00:00
|
|
|
MCRelocationInfoCtorTy Fn = MCRelocationInfoCtorFn
|
|
|
|
? MCRelocationInfoCtorFn
|
|
|
|
: llvm::createMCRelocationInfo;
|
|
|
|
return Fn(TT, Ctx);
|
Add MCSymbolizer for symbolic/annotated disassembly.
This is a basic first step towards symbolization of disassembled
instructions. This used to be done using externally provided (C API)
callbacks. This patch introduces:
- the MCSymbolizer class, that mimics the same functions that were used
in the X86 and ARM disassemblers to symbolize immediate operands and
to annotate loads based off PC (for things like c string literals).
- the MCExternalSymbolizer class, which implements the old C API.
- the MCRelocationInfo class, which provides a way for targets to
translate relocations (either object::RelocationRef, or disassembler
C API VariantKinds) to MCExprs.
- the MCObjectSymbolizer class, which does symbolization using what it
finds in an object::ObjectFile. This makes simple symbolization (with
no fancy relocation stuff) work for all object formats!
- x86-64 Mach-O and ELF MCRelocationInfos.
- A basic ARM Mach-O MCRelocationInfo, that provides just enough to
support the C API VariantKinds.
Most of what works in otool (the only user of the old symbolization API
that I know of) for x86-64 symbolic disassembly (-tvV) works, namely:
- symbol references: call _foo; jmp 15 <_foo+50>
- relocations: call _foo-_bar; call _foo-4
- __cf?string: leaq 193(%rip), %rax ## literal pool for "hello"
Stub support is the main missing part (because libObject doesn't know,
among other things, about mach-o indirect symbols).
As for the MCSymbolizer API, instead of relying on the disassemblers
to call the tryAdding* methods, maybe this could be done automagically
using InstrInfo? For instance, even though PC-relative LEAs are used
to get the address of string literals in a typical Mach-O file, a MOV
would be used in an ELF file. And right now, the explicit symbolization
only recognizes PC-relative LEAs. InstrInfo should have already have
most of what is needed to know what to symbolize, so this can
definitely be improved.
I'd also like to remove object::RelocationRef::getValueString (it seems
only used by relocation printing in objdump), as simply printing the
created MCExpr is definitely enough (and cleaner than string concats).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182625 91177308-0d34-0410-b5e6-96231b3b80d8
2013-05-24 00:39:57 +00:00
|
|
|
}
|
|
|
|
|
2013-05-24 22:51:52 +00:00
|
|
|
/// createMCSymbolizer - Create a target specific MCSymbolizer.
|
|
|
|
///
|
|
|
|
/// \param TT The target triple.
|
|
|
|
/// \param GetOpInfo The function to get the symbolic information for operands.
|
|
|
|
/// \param SymbolLookUp The function to lookup a symbol name.
|
|
|
|
/// \param DisInfo The pointer to the block of symbolic information for above call
|
|
|
|
/// back.
|
|
|
|
/// \param Ctx The target context.
|
|
|
|
/// \param RelInfo The relocation information for this target. Takes ownership.
|
|
|
|
MCSymbolizer *
|
|
|
|
createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
|
2015-01-18 20:45:48 +00:00
|
|
|
LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo,
|
|
|
|
MCContext *Ctx,
|
|
|
|
std::unique_ptr<MCRelocationInfo> &&RelInfo) const {
|
2013-10-16 16:21:40 +00:00
|
|
|
MCSymbolizerCtorTy Fn =
|
|
|
|
MCSymbolizerCtorFn ? MCSymbolizerCtorFn : llvm::createMCSymbolizer;
|
2015-01-18 20:45:48 +00:00
|
|
|
return Fn(TT, GetOpInfo, SymbolLookUp, DisInfo, Ctx, std::move(RelInfo));
|
2013-05-24 22:51:52 +00:00
|
|
|
}
|
|
|
|
|
2009-08-27 00:51:57 +00:00
|
|
|
/// @}
|
2009-07-15 04:24:58 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/// TargetRegistry - Generic interface to target specific features.
|
|
|
|
struct TargetRegistry {
|
2009-07-16 02:06:09 +00:00
|
|
|
class iterator {
|
|
|
|
const Target *Current;
|
|
|
|
explicit iterator(Target *T) : Current(T) {}
|
2009-07-18 23:22:46 +00:00
|
|
|
friend struct TargetRegistry;
|
2009-07-16 02:06:09 +00:00
|
|
|
public:
|
2014-04-07 04:17:22 +00:00
|
|
|
iterator() : Current(nullptr) {}
|
2009-07-16 02:06:09 +00:00
|
|
|
|
|
|
|
bool operator==(const iterator &x) const {
|
|
|
|
return Current == x.Current;
|
|
|
|
}
|
|
|
|
bool operator!=(const iterator &x) const {
|
|
|
|
return !operator==(x);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Iterator traversal: forward iteration only
|
|
|
|
iterator &operator++() { // Preincrement
|
|
|
|
assert(Current && "Cannot increment end iterator!");
|
2009-07-16 02:38:28 +00:00
|
|
|
Current = Current->getNext();
|
2009-07-16 02:06:09 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
iterator operator++(int) { // Postincrement
|
2010-02-21 21:53:37 +00:00
|
|
|
iterator tmp = *this;
|
|
|
|
++*this;
|
2009-07-16 02:06:09 +00:00
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Target &operator*() const {
|
|
|
|
assert(Current && "Cannot dereference end iterator!");
|
|
|
|
return *Current;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Target *operator->() const {
|
|
|
|
return &operator*();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2011-07-22 07:50:44 +00:00
|
|
|
/// printRegisteredTargetsForVersion - Print the registered targets
|
|
|
|
/// appropriately for inclusion in a tool's version output.
|
|
|
|
static void printRegisteredTargetsForVersion();
|
|
|
|
|
2009-07-15 04:24:58 +00:00
|
|
|
/// @name Registry Access
|
|
|
|
/// @{
|
|
|
|
|
2009-07-16 02:06:09 +00:00
|
|
|
static iterator begin();
|
|
|
|
|
|
|
|
static iterator end() { return iterator(); }
|
|
|
|
|
2009-07-26 02:12:58 +00:00
|
|
|
/// lookupTarget - Lookup a target based on a target triple.
|
|
|
|
///
|
|
|
|
/// \param Triple - The triple to use for finding a target.
|
|
|
|
/// \param Error - On failure, an error string describing why no target was
|
|
|
|
/// found.
|
|
|
|
static const Target *lookupTarget(const std::string &Triple,
|
|
|
|
std::string &Error);
|
2009-07-15 04:24:58 +00:00
|
|
|
|
2012-05-08 23:38:45 +00:00
|
|
|
/// lookupTarget - Lookup a target based on an architecture name
|
|
|
|
/// and a target triple. If the architecture name is non-empty,
|
|
|
|
/// then the lookup is done by architecture. Otherwise, the target
|
|
|
|
/// triple is used.
|
|
|
|
///
|
|
|
|
/// \param ArchName - The architecture to use for finding a target.
|
|
|
|
/// \param TheTriple - The triple to use for finding a target. The
|
|
|
|
/// triple is updated with canonical architecture name if a lookup
|
|
|
|
/// by architecture is done.
|
|
|
|
/// \param Error - On failure, an error string describing why no target was
|
|
|
|
/// found.
|
|
|
|
static const Target *lookupTarget(const std::string &ArchName,
|
|
|
|
Triple &TheTriple,
|
|
|
|
std::string &Error);
|
|
|
|
|
2009-07-15 04:24:58 +00:00
|
|
|
/// @}
|
|
|
|
/// @name Target Registration
|
|
|
|
/// @{
|
|
|
|
|
2009-07-15 20:24:03 +00:00
|
|
|
/// RegisterTarget - Register the given target. Attempts to register a
|
|
|
|
/// target which has already been registered will be ignored.
|
2010-02-21 21:53:37 +00:00
|
|
|
///
|
2009-07-15 07:09:29 +00:00
|
|
|
/// Clients are responsible for ensuring that registration doesn't occur
|
|
|
|
/// while another thread is attempting to access the registry. Typically
|
|
|
|
/// this is done by initializing all targets at program startup.
|
2009-07-15 04:24:58 +00:00
|
|
|
///
|
|
|
|
/// @param T - The target being registered.
|
|
|
|
/// @param Name - The target name. This should be a static string.
|
|
|
|
/// @param ShortDesc - A short target description. This should be a static
|
2010-02-21 21:53:37 +00:00
|
|
|
/// string.
|
2013-12-13 16:05:32 +00:00
|
|
|
/// @param ArchMatchFn - The arch match checking function for this target.
|
2009-07-25 10:09:50 +00:00
|
|
|
/// @param HasJIT - Whether the target supports JIT code
|
|
|
|
/// generation.
|
2009-07-15 04:24:58 +00:00
|
|
|
static void RegisterTarget(Target &T,
|
|
|
|
const char *Name,
|
|
|
|
const char *ShortDesc,
|
2013-12-13 16:05:32 +00:00
|
|
|
Target::ArchMatchFnTy ArchMatchFn,
|
2009-07-25 10:09:50 +00:00
|
|
|
bool HasJIT = false);
|
2009-08-12 07:22:17 +00:00
|
|
|
|
2011-07-14 23:50:31 +00:00
|
|
|
/// RegisterMCAsmInfo - Register a MCAsmInfo implementation for the
|
2009-08-12 07:22:17 +00:00
|
|
|
/// given target.
|
2010-02-21 21:53:37 +00:00
|
|
|
///
|
2009-08-12 07:22:17 +00:00
|
|
|
/// Clients are responsible for ensuring that registration doesn't occur
|
|
|
|
/// while another thread is attempting to access the registry. Typically
|
|
|
|
/// this is done by initializing all targets at program startup.
|
2010-02-21 21:53:37 +00:00
|
|
|
///
|
2009-08-12 07:22:17 +00:00
|
|
|
/// @param T - The target being registered.
|
2009-08-22 20:48:53 +00:00
|
|
|
/// @param Fn - A function to construct a MCAsmInfo for the target.
|
2011-07-14 23:50:31 +00:00
|
|
|
static void RegisterMCAsmInfo(Target &T, Target::MCAsmInfoCtorFnTy Fn) {
|
2013-10-16 16:21:40 +00:00
|
|
|
T.MCAsmInfoCtorFn = Fn;
|
2009-08-12 07:22:17 +00:00
|
|
|
}
|
2010-02-21 21:53:37 +00:00
|
|
|
|
2011-07-19 06:37:02 +00:00
|
|
|
/// RegisterMCCodeGenInfo - Register a MCCodeGenInfo implementation for the
|
|
|
|
/// given target.
|
|
|
|
///
|
|
|
|
/// Clients are responsible for ensuring that registration doesn't occur
|
|
|
|
/// while another thread is attempting to access the registry. Typically
|
|
|
|
/// this is done by initializing all targets at program startup.
|
|
|
|
///
|
|
|
|
/// @param T - The target being registered.
|
|
|
|
/// @param Fn - A function to construct a MCCodeGenInfo for the target.
|
|
|
|
static void RegisterMCCodeGenInfo(Target &T,
|
|
|
|
Target::MCCodeGenInfoCtorFnTy Fn) {
|
2013-10-16 16:21:40 +00:00
|
|
|
T.MCCodeGenInfoCtorFn = Fn;
|
2011-07-19 06:37:02 +00:00
|
|
|
}
|
|
|
|
|
2011-06-28 20:29:03 +00:00
|
|
|
/// RegisterMCInstrInfo - Register a MCInstrInfo implementation for the
|
|
|
|
/// given target.
|
|
|
|
///
|
|
|
|
/// Clients are responsible for ensuring that registration doesn't occur
|
|
|
|
/// while another thread is attempting to access the registry. Typically
|
|
|
|
/// this is done by initializing all targets at program startup.
|
|
|
|
///
|
|
|
|
/// @param T - The target being registered.
|
|
|
|
/// @param Fn - A function to construct a MCInstrInfo for the target.
|
|
|
|
static void RegisterMCInstrInfo(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
|
2013-10-16 16:21:40 +00:00
|
|
|
T.MCInstrInfoCtorFn = Fn;
|
2011-06-28 20:29:03 +00:00
|
|
|
}
|
|
|
|
|
2011-08-08 18:56:44 +00:00
|
|
|
/// RegisterMCInstrAnalysis - Register a MCInstrAnalysis implementation for
|
|
|
|
/// the given target.
|
|
|
|
static void RegisterMCInstrAnalysis(Target &T,
|
|
|
|
Target::MCInstrAnalysisCtorFnTy Fn) {
|
2013-10-16 16:21:40 +00:00
|
|
|
T.MCInstrAnalysisCtorFn = Fn;
|
2011-08-08 18:56:44 +00:00
|
|
|
}
|
|
|
|
|
2011-06-24 20:42:09 +00:00
|
|
|
/// RegisterMCRegInfo - Register a MCRegisterInfo implementation for the
|
2011-06-24 01:44:41 +00:00
|
|
|
/// given target.
|
|
|
|
///
|
|
|
|
/// Clients are responsible for ensuring that registration doesn't occur
|
|
|
|
/// while another thread is attempting to access the registry. Typically
|
|
|
|
/// this is done by initializing all targets at program startup.
|
|
|
|
///
|
|
|
|
/// @param T - The target being registered.
|
|
|
|
/// @param Fn - A function to construct a MCRegisterInfo for the target.
|
2011-06-24 20:42:09 +00:00
|
|
|
static void RegisterMCRegInfo(Target &T, Target::MCRegInfoCtorFnTy Fn) {
|
2013-10-16 16:21:40 +00:00
|
|
|
T.MCRegInfoCtorFn = Fn;
|
2011-06-24 01:44:41 +00:00
|
|
|
}
|
|
|
|
|
2011-07-09 05:47:46 +00:00
|
|
|
/// RegisterMCSubtargetInfo - Register a MCSubtargetInfo implementation for
|
|
|
|
/// the given target.
|
|
|
|
///
|
|
|
|
/// Clients are responsible for ensuring that registration doesn't occur
|
|
|
|
/// while another thread is attempting to access the registry. Typically
|
|
|
|
/// this is done by initializing all targets at program startup.
|
|
|
|
///
|
|
|
|
/// @param T - The target being registered.
|
|
|
|
/// @param Fn - A function to construct a MCSubtargetInfo for the target.
|
|
|
|
static void RegisterMCSubtargetInfo(Target &T,
|
|
|
|
Target::MCSubtargetInfoCtorFnTy Fn) {
|
2013-10-16 16:21:40 +00:00
|
|
|
T.MCSubtargetInfoCtorFn = Fn;
|
2011-07-09 05:47:46 +00:00
|
|
|
}
|
|
|
|
|
2009-07-15 04:24:58 +00:00
|
|
|
/// RegisterTargetMachine - Register a TargetMachine implementation for the
|
|
|
|
/// given target.
|
2010-02-21 21:53:37 +00:00
|
|
|
///
|
2009-07-15 07:09:29 +00:00
|
|
|
/// Clients are responsible for ensuring that registration doesn't occur
|
|
|
|
/// while another thread is attempting to access the registry. Typically
|
|
|
|
/// this is done by initializing all targets at program startup.
|
2010-02-21 21:53:37 +00:00
|
|
|
///
|
2009-07-15 04:24:58 +00:00
|
|
|
/// @param T - The target being registered.
|
|
|
|
/// @param Fn - A function to construct a TargetMachine for the target.
|
2010-02-21 21:53:37 +00:00
|
|
|
static void RegisterTargetMachine(Target &T,
|
2009-07-15 04:24:58 +00:00
|
|
|
Target::TargetMachineCtorTy Fn) {
|
2013-10-16 16:21:40 +00:00
|
|
|
T.TargetMachineCtorFn = Fn;
|
2009-07-15 04:24:58 +00:00
|
|
|
}
|
|
|
|
|
2011-07-25 23:24:55 +00:00
|
|
|
/// RegisterMCAsmBackend - Register a MCAsmBackend implementation for the
|
2010-02-21 21:53:53 +00:00
|
|
|
/// given target.
|
|
|
|
///
|
|
|
|
/// Clients are responsible for ensuring that registration doesn't occur
|
|
|
|
/// while another thread is attempting to access the registry. Typically
|
|
|
|
/// this is done by initializing all targets at program startup.
|
|
|
|
///
|
|
|
|
/// @param T - The target being registered.
|
|
|
|
/// @param Fn - A function to construct an AsmBackend for the target.
|
2011-07-25 23:24:55 +00:00
|
|
|
static void RegisterMCAsmBackend(Target &T, Target::MCAsmBackendCtorTy Fn) {
|
2013-10-16 16:21:40 +00:00
|
|
|
T.MCAsmBackendCtorFn = Fn;
|
2010-02-21 21:53:53 +00:00
|
|
|
}
|
|
|
|
|
2011-07-26 00:24:13 +00:00
|
|
|
/// RegisterMCAsmParser - Register a MCTargetAsmParser implementation for
|
|
|
|
/// the given target.
|
2010-02-21 21:53:37 +00:00
|
|
|
///
|
2009-07-17 20:42:00 +00:00
|
|
|
/// Clients are responsible for ensuring that registration doesn't occur
|
|
|
|
/// while another thread is attempting to access the registry. Typically
|
|
|
|
/// this is done by initializing all targets at program startup.
|
|
|
|
///
|
|
|
|
/// @param T - The target being registered.
|
2011-07-26 00:24:13 +00:00
|
|
|
/// @param Fn - A function to construct an MCTargetAsmParser for the target.
|
|
|
|
static void RegisterMCAsmParser(Target &T, Target::MCAsmParserCtorTy Fn) {
|
2013-10-16 16:21:40 +00:00
|
|
|
T.MCAsmParserCtorFn = Fn;
|
2009-07-15 04:24:58 +00:00
|
|
|
}
|
2010-02-21 21:53:37 +00:00
|
|
|
|
|
|
|
/// RegisterAsmPrinter - Register an AsmPrinter implementation for the given
|
|
|
|
/// target.
|
|
|
|
///
|
|
|
|
/// Clients are responsible for ensuring that registration doesn't occur
|
|
|
|
/// while another thread is attempting to access the registry. Typically
|
|
|
|
/// this is done by initializing all targets at program startup.
|
|
|
|
///
|
|
|
|
/// @param T - The target being registered.
|
|
|
|
/// @param Fn - A function to construct an AsmPrinter for the target.
|
|
|
|
static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) {
|
2013-10-16 16:21:40 +00:00
|
|
|
T.AsmPrinterCtorFn = Fn;
|
2010-02-21 21:53:37 +00:00
|
|
|
}
|
|
|
|
|
2009-09-09 22:49:13 +00:00
|
|
|
/// RegisterMCDisassembler - Register a MCDisassembler implementation for
|
|
|
|
/// the given target.
|
2010-02-21 21:53:37 +00:00
|
|
|
///
|
2009-09-09 22:49:13 +00:00
|
|
|
/// Clients are responsible for ensuring that registration doesn't occur
|
|
|
|
/// while another thread is attempting to access the registry. Typically
|
|
|
|
/// this is done by initializing all targets at program startup.
|
|
|
|
///
|
|
|
|
/// @param T - The target being registered.
|
|
|
|
/// @param Fn - A function to construct an MCDisassembler for the target.
|
2010-02-21 21:53:37 +00:00
|
|
|
static void RegisterMCDisassembler(Target &T,
|
2009-09-09 22:49:13 +00:00
|
|
|
Target::MCDisassemblerCtorTy Fn) {
|
2013-10-16 16:21:40 +00:00
|
|
|
T.MCDisassemblerCtorFn = Fn;
|
2009-09-09 22:49:13 +00:00
|
|
|
}
|
2009-07-15 04:24:58 +00:00
|
|
|
|
2009-10-20 05:15:36 +00:00
|
|
|
/// RegisterMCInstPrinter - Register a MCInstPrinter implementation for the
|
|
|
|
/// given target.
|
2010-02-21 21:53:37 +00:00
|
|
|
///
|
2009-10-20 05:15:36 +00:00
|
|
|
/// Clients are responsible for ensuring that registration doesn't occur
|
|
|
|
/// while another thread is attempting to access the registry. Typically
|
|
|
|
/// this is done by initializing all targets at program startup.
|
|
|
|
///
|
|
|
|
/// @param T - The target being registered.
|
|
|
|
/// @param Fn - A function to construct an MCInstPrinter for the target.
|
2009-09-14 03:02:37 +00:00
|
|
|
static void RegisterMCInstPrinter(Target &T,
|
|
|
|
Target::MCInstPrinterCtorTy Fn) {
|
2013-10-16 16:21:40 +00:00
|
|
|
T.MCInstPrinterCtorFn = Fn;
|
2009-09-14 03:02:37 +00:00
|
|
|
}
|
2010-02-21 21:53:37 +00:00
|
|
|
|
2011-07-26 00:42:34 +00:00
|
|
|
/// RegisterMCCodeEmitter - Register a MCCodeEmitter implementation for the
|
2009-08-27 00:51:57 +00:00
|
|
|
/// given target.
|
2009-10-20 05:15:36 +00:00
|
|
|
///
|
2009-08-27 00:51:57 +00:00
|
|
|
/// Clients are responsible for ensuring that registration doesn't occur
|
|
|
|
/// while another thread is attempting to access the registry. Typically
|
|
|
|
/// this is done by initializing all targets at program startup.
|
|
|
|
///
|
|
|
|
/// @param T - The target being registered.
|
2010-02-21 21:53:37 +00:00
|
|
|
/// @param Fn - A function to construct an MCCodeEmitter for the target.
|
2011-07-26 00:42:34 +00:00
|
|
|
static void RegisterMCCodeEmitter(Target &T,
|
|
|
|
Target::MCCodeEmitterCtorTy Fn) {
|
2013-10-16 16:21:40 +00:00
|
|
|
T.MCCodeEmitterCtorFn = Fn;
|
2009-08-27 00:51:57 +00:00
|
|
|
}
|
|
|
|
|
2011-07-26 00:42:34 +00:00
|
|
|
/// RegisterMCObjectStreamer - Register a object code MCStreamer
|
|
|
|
/// implementation for the given target.
|
2010-05-21 12:54:43 +00:00
|
|
|
///
|
|
|
|
/// Clients are responsible for ensuring that registration doesn't occur
|
|
|
|
/// while another thread is attempting to access the registry. Typically
|
|
|
|
/// this is done by initializing all targets at program startup.
|
|
|
|
///
|
|
|
|
/// @param T - The target being registered.
|
|
|
|
/// @param Fn - A function to construct an MCStreamer for the target.
|
2011-07-26 00:42:34 +00:00
|
|
|
static void RegisterMCObjectStreamer(Target &T,
|
|
|
|
Target::MCObjectStreamerCtorTy Fn) {
|
2013-10-16 16:21:40 +00:00
|
|
|
T.MCObjectStreamerCtorFn = Fn;
|
2010-05-21 12:54:43 +00:00
|
|
|
}
|
|
|
|
|
2010-11-08 02:21:17 +00:00
|
|
|
/// RegisterAsmStreamer - Register an assembly MCStreamer implementation
|
|
|
|
/// for the given target.
|
|
|
|
///
|
|
|
|
/// Clients are responsible for ensuring that registration doesn't occur
|
|
|
|
/// while another thread is attempting to access the registry. Typically
|
|
|
|
/// this is done by initializing all targets at program startup.
|
|
|
|
///
|
|
|
|
/// @param T - The target being registered.
|
|
|
|
/// @param Fn - A function to construct an MCStreamer for the target.
|
|
|
|
static void RegisterAsmStreamer(Target &T, Target::AsmStreamerCtorTy Fn) {
|
2013-10-16 16:21:40 +00:00
|
|
|
T.AsmStreamerCtorFn = Fn;
|
2010-11-08 02:21:17 +00:00
|
|
|
}
|
|
|
|
|
2015-02-19 00:45:02 +00:00
|
|
|
static void
|
|
|
|
RegisterNullTargetStreamer(Target &T, Target::NullTargetStreamerCtorTy Fn) {
|
|
|
|
T.NullTargetStreamerCtorFn = Fn;
|
|
|
|
}
|
|
|
|
|
Add MCSymbolizer for symbolic/annotated disassembly.
This is a basic first step towards symbolization of disassembled
instructions. This used to be done using externally provided (C API)
callbacks. This patch introduces:
- the MCSymbolizer class, that mimics the same functions that were used
in the X86 and ARM disassemblers to symbolize immediate operands and
to annotate loads based off PC (for things like c string literals).
- the MCExternalSymbolizer class, which implements the old C API.
- the MCRelocationInfo class, which provides a way for targets to
translate relocations (either object::RelocationRef, or disassembler
C API VariantKinds) to MCExprs.
- the MCObjectSymbolizer class, which does symbolization using what it
finds in an object::ObjectFile. This makes simple symbolization (with
no fancy relocation stuff) work for all object formats!
- x86-64 Mach-O and ELF MCRelocationInfos.
- A basic ARM Mach-O MCRelocationInfo, that provides just enough to
support the C API VariantKinds.
Most of what works in otool (the only user of the old symbolization API
that I know of) for x86-64 symbolic disassembly (-tvV) works, namely:
- symbol references: call _foo; jmp 15 <_foo+50>
- relocations: call _foo-_bar; call _foo-4
- __cf?string: leaq 193(%rip), %rax ## literal pool for "hello"
Stub support is the main missing part (because libObject doesn't know,
among other things, about mach-o indirect symbols).
As for the MCSymbolizer API, instead of relying on the disassemblers
to call the tryAdding* methods, maybe this could be done automagically
using InstrInfo? For instance, even though PC-relative LEAs are used
to get the address of string literals in a typical Mach-O file, a MOV
would be used in an ELF file. And right now, the explicit symbolization
only recognizes PC-relative LEAs. InstrInfo should have already have
most of what is needed to know what to symbolize, so this can
definitely be improved.
I'd also like to remove object::RelocationRef::getValueString (it seems
only used by relocation printing in objdump), as simply printing the
created MCExpr is definitely enough (and cleaner than string concats).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182625 91177308-0d34-0410-b5e6-96231b3b80d8
2013-05-24 00:39:57 +00:00
|
|
|
/// RegisterMCRelocationInfo - Register an MCRelocationInfo
|
|
|
|
/// implementation for the given target.
|
|
|
|
///
|
|
|
|
/// Clients are responsible for ensuring that registration doesn't occur
|
|
|
|
/// while another thread is attempting to access the registry. Typically
|
|
|
|
/// this is done by initializing all targets at program startup.
|
|
|
|
///
|
|
|
|
/// @param T - The target being registered.
|
|
|
|
/// @param Fn - A function to construct an MCRelocationInfo for the target.
|
|
|
|
static void RegisterMCRelocationInfo(Target &T,
|
|
|
|
Target::MCRelocationInfoCtorTy Fn) {
|
2013-10-16 16:21:40 +00:00
|
|
|
T.MCRelocationInfoCtorFn = Fn;
|
Add MCSymbolizer for symbolic/annotated disassembly.
This is a basic first step towards symbolization of disassembled
instructions. This used to be done using externally provided (C API)
callbacks. This patch introduces:
- the MCSymbolizer class, that mimics the same functions that were used
in the X86 and ARM disassemblers to symbolize immediate operands and
to annotate loads based off PC (for things like c string literals).
- the MCExternalSymbolizer class, which implements the old C API.
- the MCRelocationInfo class, which provides a way for targets to
translate relocations (either object::RelocationRef, or disassembler
C API VariantKinds) to MCExprs.
- the MCObjectSymbolizer class, which does symbolization using what it
finds in an object::ObjectFile. This makes simple symbolization (with
no fancy relocation stuff) work for all object formats!
- x86-64 Mach-O and ELF MCRelocationInfos.
- A basic ARM Mach-O MCRelocationInfo, that provides just enough to
support the C API VariantKinds.
Most of what works in otool (the only user of the old symbolization API
that I know of) for x86-64 symbolic disassembly (-tvV) works, namely:
- symbol references: call _foo; jmp 15 <_foo+50>
- relocations: call _foo-_bar; call _foo-4
- __cf?string: leaq 193(%rip), %rax ## literal pool for "hello"
Stub support is the main missing part (because libObject doesn't know,
among other things, about mach-o indirect symbols).
As for the MCSymbolizer API, instead of relying on the disassemblers
to call the tryAdding* methods, maybe this could be done automagically
using InstrInfo? For instance, even though PC-relative LEAs are used
to get the address of string literals in a typical Mach-O file, a MOV
would be used in an ELF file. And right now, the explicit symbolization
only recognizes PC-relative LEAs. InstrInfo should have already have
most of what is needed to know what to symbolize, so this can
definitely be improved.
I'd also like to remove object::RelocationRef::getValueString (it seems
only used by relocation printing in objdump), as simply printing the
created MCExpr is definitely enough (and cleaner than string concats).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@182625 91177308-0d34-0410-b5e6-96231b3b80d8
2013-05-24 00:39:57 +00:00
|
|
|
}
|
|
|
|
|
2013-05-24 22:51:52 +00:00
|
|
|
/// RegisterMCSymbolizer - Register an MCSymbolizer
|
|
|
|
/// implementation for the given target.
|
|
|
|
///
|
|
|
|
/// Clients are responsible for ensuring that registration doesn't occur
|
|
|
|
/// while another thread is attempting to access the registry. Typically
|
|
|
|
/// this is done by initializing all targets at program startup.
|
|
|
|
///
|
|
|
|
/// @param T - The target being registered.
|
|
|
|
/// @param Fn - A function to construct an MCSymbolizer for the target.
|
|
|
|
static void RegisterMCSymbolizer(Target &T,
|
|
|
|
Target::MCSymbolizerCtorTy Fn) {
|
2013-10-16 16:21:40 +00:00
|
|
|
T.MCSymbolizerCtorFn = Fn;
|
2013-05-24 22:51:52 +00:00
|
|
|
}
|
|
|
|
|
2009-07-15 04:24:58 +00:00
|
|
|
/// @}
|
|
|
|
};
|
|
|
|
|
2009-07-25 06:49:55 +00:00
|
|
|
|
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// RegisterTarget - Helper template for registering a target, for use in the
|
|
|
|
/// target's initialization function. Usage:
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// Target TheFooTarget; // The global target instance.
|
|
|
|
///
|
|
|
|
/// extern "C" void LLVMInitializeFooTargetInfo() {
|
2009-07-26 05:03:33 +00:00
|
|
|
/// RegisterTarget<Triple::foo> X(TheFooTarget, "foo", "Foo description");
|
2009-07-25 06:49:55 +00:00
|
|
|
/// }
|
2012-02-21 03:39:36 +00:00
|
|
|
template<Triple::ArchType TargetArchType = Triple::UnknownArch,
|
2009-07-26 05:03:33 +00:00
|
|
|
bool HasJIT = false>
|
2009-07-25 06:49:55 +00:00
|
|
|
struct RegisterTarget {
|
|
|
|
RegisterTarget(Target &T, const char *Name, const char *Desc) {
|
2013-12-13 16:05:32 +00:00
|
|
|
TargetRegistry::RegisterTarget(T, Name, Desc, &getArchMatch, HasJIT);
|
2009-07-26 05:03:33 +00:00
|
|
|
}
|
|
|
|
|
2013-12-13 16:05:32 +00:00
|
|
|
static bool getArchMatch(Triple::ArchType Arch) {
|
|
|
|
return Arch == TargetArchType;
|
2009-07-25 06:49:55 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2011-07-14 23:50:31 +00:00
|
|
|
/// RegisterMCAsmInfo - Helper template for registering a target assembly info
|
2009-08-12 07:22:17 +00:00
|
|
|
/// implementation. This invokes the static "Create" method on the class to
|
|
|
|
/// actually do the construction. Usage:
|
|
|
|
///
|
|
|
|
/// extern "C" void LLVMInitializeFooTarget() {
|
|
|
|
/// extern Target TheFooTarget;
|
2011-07-14 23:50:31 +00:00
|
|
|
/// RegisterMCAsmInfo<FooMCAsmInfo> X(TheFooTarget);
|
2009-08-12 07:22:17 +00:00
|
|
|
/// }
|
2009-08-22 20:48:53 +00:00
|
|
|
template<class MCAsmInfoImpl>
|
2011-07-14 23:50:31 +00:00
|
|
|
struct RegisterMCAsmInfo {
|
|
|
|
RegisterMCAsmInfo(Target &T) {
|
|
|
|
TargetRegistry::RegisterMCAsmInfo(T, &Allocator);
|
2009-08-12 07:22:17 +00:00
|
|
|
}
|
|
|
|
private:
|
2013-06-10 12:09:30 +00:00
|
|
|
static MCAsmInfo *Allocator(const MCRegisterInfo &/*MRI*/, StringRef TT) {
|
2013-05-10 18:16:59 +00:00
|
|
|
return new MCAsmInfoImpl(TT);
|
2009-08-12 07:22:17 +00:00
|
|
|
}
|
2010-02-21 21:53:37 +00:00
|
|
|
|
2009-08-12 07:22:17 +00:00
|
|
|
};
|
|
|
|
|
2011-07-14 23:50:31 +00:00
|
|
|
/// RegisterMCAsmInfoFn - Helper template for registering a target assembly info
|
2009-08-12 07:22:17 +00:00
|
|
|
/// implementation. This invokes the specified function to do the
|
|
|
|
/// construction. Usage:
|
|
|
|
///
|
|
|
|
/// extern "C" void LLVMInitializeFooTarget() {
|
|
|
|
/// extern Target TheFooTarget;
|
2011-07-14 23:50:31 +00:00
|
|
|
/// RegisterMCAsmInfoFn X(TheFooTarget, TheFunction);
|
2009-08-12 07:22:17 +00:00
|
|
|
/// }
|
2011-07-14 23:50:31 +00:00
|
|
|
struct RegisterMCAsmInfoFn {
|
|
|
|
RegisterMCAsmInfoFn(Target &T, Target::MCAsmInfoCtorFnTy Fn) {
|
|
|
|
TargetRegistry::RegisterMCAsmInfo(T, Fn);
|
2011-06-28 20:29:03 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2011-07-19 06:37:02 +00:00
|
|
|
/// RegisterMCCodeGenInfo - Helper template for registering a target codegen info
|
|
|
|
/// implementation. This invokes the static "Create" method on the class
|
|
|
|
/// to actually do the construction. Usage:
|
|
|
|
///
|
|
|
|
/// extern "C" void LLVMInitializeFooTarget() {
|
|
|
|
/// extern Target TheFooTarget;
|
|
|
|
/// RegisterMCCodeGenInfo<FooMCCodeGenInfo> X(TheFooTarget);
|
|
|
|
/// }
|
|
|
|
template<class MCCodeGenInfoImpl>
|
|
|
|
struct RegisterMCCodeGenInfo {
|
|
|
|
RegisterMCCodeGenInfo(Target &T) {
|
|
|
|
TargetRegistry::RegisterMCCodeGenInfo(T, &Allocator);
|
|
|
|
}
|
|
|
|
private:
|
2013-06-10 12:09:30 +00:00
|
|
|
static MCCodeGenInfo *Allocator(StringRef /*TT*/, Reloc::Model /*RM*/,
|
|
|
|
CodeModel::Model /*CM*/,
|
|
|
|
CodeGenOpt::Level /*OL*/) {
|
2011-07-19 06:37:02 +00:00
|
|
|
return new MCCodeGenInfoImpl();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// RegisterMCCodeGenInfoFn - Helper template for registering a target codegen
|
|
|
|
/// info implementation. This invokes the specified function to do the
|
|
|
|
/// construction. Usage:
|
|
|
|
///
|
|
|
|
/// extern "C" void LLVMInitializeFooTarget() {
|
|
|
|
/// extern Target TheFooTarget;
|
|
|
|
/// RegisterMCCodeGenInfoFn X(TheFooTarget, TheFunction);
|
|
|
|
/// }
|
|
|
|
struct RegisterMCCodeGenInfoFn {
|
|
|
|
RegisterMCCodeGenInfoFn(Target &T, Target::MCCodeGenInfoCtorFnTy Fn) {
|
|
|
|
TargetRegistry::RegisterMCCodeGenInfo(T, Fn);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2011-06-28 20:29:03 +00:00
|
|
|
/// RegisterMCInstrInfo - Helper template for registering a target instruction
|
|
|
|
/// info implementation. This invokes the static "Create" method on the class
|
|
|
|
/// to actually do the construction. Usage:
|
|
|
|
///
|
|
|
|
/// extern "C" void LLVMInitializeFooTarget() {
|
|
|
|
/// extern Target TheFooTarget;
|
|
|
|
/// RegisterMCInstrInfo<FooMCInstrInfo> X(TheFooTarget);
|
|
|
|
/// }
|
|
|
|
template<class MCInstrInfoImpl>
|
|
|
|
struct RegisterMCInstrInfo {
|
|
|
|
RegisterMCInstrInfo(Target &T) {
|
|
|
|
TargetRegistry::RegisterMCInstrInfo(T, &Allocator);
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
static MCInstrInfo *Allocator() {
|
|
|
|
return new MCInstrInfoImpl();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// RegisterMCInstrInfoFn - Helper template for registering a target
|
|
|
|
/// instruction info implementation. This invokes the specified function to
|
|
|
|
/// do the construction. Usage:
|
|
|
|
///
|
|
|
|
/// extern "C" void LLVMInitializeFooTarget() {
|
|
|
|
/// extern Target TheFooTarget;
|
|
|
|
/// RegisterMCInstrInfoFn X(TheFooTarget, TheFunction);
|
|
|
|
/// }
|
|
|
|
struct RegisterMCInstrInfoFn {
|
|
|
|
RegisterMCInstrInfoFn(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
|
|
|
|
TargetRegistry::RegisterMCInstrInfo(T, Fn);
|
2009-08-12 07:22:17 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2011-08-23 20:15:21 +00:00
|
|
|
/// RegisterMCInstrAnalysis - Helper template for registering a target
|
|
|
|
/// instruction analyzer implementation. This invokes the static "Create"
|
|
|
|
/// method on the class to actually do the construction. Usage:
|
|
|
|
///
|
|
|
|
/// extern "C" void LLVMInitializeFooTarget() {
|
|
|
|
/// extern Target TheFooTarget;
|
|
|
|
/// RegisterMCInstrAnalysis<FooMCInstrAnalysis> X(TheFooTarget);
|
|
|
|
/// }
|
|
|
|
template<class MCInstrAnalysisImpl>
|
|
|
|
struct RegisterMCInstrAnalysis {
|
|
|
|
RegisterMCInstrAnalysis(Target &T) {
|
|
|
|
TargetRegistry::RegisterMCInstrAnalysis(T, &Allocator);
|
|
|
|
}
|
|
|
|
private:
|
|
|
|
static MCInstrAnalysis *Allocator(const MCInstrInfo *Info) {
|
|
|
|
return new MCInstrAnalysisImpl(Info);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// RegisterMCInstrAnalysisFn - Helper template for registering a target
|
|
|
|
/// instruction analyzer implementation. This invokes the specified function
|
|
|
|
/// to do the construction. Usage:
|
|
|
|
///
|
|
|
|
/// extern "C" void LLVMInitializeFooTarget() {
|
|
|
|
/// extern Target TheFooTarget;
|
|
|
|
/// RegisterMCInstrAnalysisFn X(TheFooTarget, TheFunction);
|
|
|
|
/// }
|
|
|
|
struct RegisterMCInstrAnalysisFn {
|
|
|
|
RegisterMCInstrAnalysisFn(Target &T, Target::MCInstrAnalysisCtorFnTy Fn) {
|
|
|
|
TargetRegistry::RegisterMCInstrAnalysis(T, Fn);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2011-06-24 20:42:09 +00:00
|
|
|
/// RegisterMCRegInfo - Helper template for registering a target register info
|
|
|
|
/// implementation. This invokes the static "Create" method on the class to
|
|
|
|
/// actually do the construction. Usage:
|
|
|
|
///
|
|
|
|
/// extern "C" void LLVMInitializeFooTarget() {
|
|
|
|
/// extern Target TheFooTarget;
|
|
|
|
/// RegisterMCRegInfo<FooMCRegInfo> X(TheFooTarget);
|
|
|
|
/// }
|
|
|
|
template<class MCRegisterInfoImpl>
|
|
|
|
struct RegisterMCRegInfo {
|
|
|
|
RegisterMCRegInfo(Target &T) {
|
|
|
|
TargetRegistry::RegisterMCRegInfo(T, &Allocator);
|
|
|
|
}
|
|
|
|
private:
|
2013-06-10 12:09:30 +00:00
|
|
|
static MCRegisterInfo *Allocator(StringRef /*TT*/) {
|
2011-06-24 20:42:09 +00:00
|
|
|
return new MCRegisterInfoImpl();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// RegisterMCRegInfoFn - Helper template for registering a target register
|
|
|
|
/// info implementation. This invokes the specified function to do the
|
|
|
|
/// construction. Usage:
|
|
|
|
///
|
|
|
|
/// extern "C" void LLVMInitializeFooTarget() {
|
|
|
|
/// extern Target TheFooTarget;
|
|
|
|
/// RegisterMCRegInfoFn X(TheFooTarget, TheFunction);
|
|
|
|
/// }
|
|
|
|
struct RegisterMCRegInfoFn {
|
|
|
|
RegisterMCRegInfoFn(Target &T, Target::MCRegInfoCtorFnTy Fn) {
|
|
|
|
TargetRegistry::RegisterMCRegInfo(T, Fn);
|
|
|
|
}
|
|
|
|
};
|
2009-08-12 07:22:17 +00:00
|
|
|
|
2011-07-09 05:47:46 +00:00
|
|
|
/// RegisterMCSubtargetInfo - Helper template for registering a target
|
|
|
|
/// subtarget info implementation. This invokes the static "Create" method
|
|
|
|
/// on the class to actually do the construction. Usage:
|
|
|
|
///
|
|
|
|
/// extern "C" void LLVMInitializeFooTarget() {
|
|
|
|
/// extern Target TheFooTarget;
|
|
|
|
/// RegisterMCSubtargetInfo<FooMCSubtargetInfo> X(TheFooTarget);
|
|
|
|
/// }
|
|
|
|
template<class MCSubtargetInfoImpl>
|
|
|
|
struct RegisterMCSubtargetInfo {
|
|
|
|
RegisterMCSubtargetInfo(Target &T) {
|
|
|
|
TargetRegistry::RegisterMCSubtargetInfo(T, &Allocator);
|
|
|
|
}
|
|
|
|
private:
|
2013-06-10 12:09:30 +00:00
|
|
|
static MCSubtargetInfo *Allocator(StringRef /*TT*/, StringRef /*CPU*/,
|
|
|
|
StringRef /*FS*/) {
|
2011-07-09 05:47:46 +00:00
|
|
|
return new MCSubtargetInfoImpl();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// RegisterMCSubtargetInfoFn - Helper template for registering a target
|
|
|
|
/// subtarget info implementation. This invokes the specified function to
|
|
|
|
/// do the construction. Usage:
|
|
|
|
///
|
|
|
|
/// extern "C" void LLVMInitializeFooTarget() {
|
|
|
|
/// extern Target TheFooTarget;
|
|
|
|
/// RegisterMCSubtargetInfoFn X(TheFooTarget, TheFunction);
|
|
|
|
/// }
|
|
|
|
struct RegisterMCSubtargetInfoFn {
|
|
|
|
RegisterMCSubtargetInfoFn(Target &T, Target::MCSubtargetInfoCtorFnTy Fn) {
|
|
|
|
TargetRegistry::RegisterMCSubtargetInfo(T, Fn);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2009-07-25 06:49:55 +00:00
|
|
|
/// RegisterTargetMachine - Helper template for registering a target machine
|
|
|
|
/// implementation, for use in the target machine initialization
|
|
|
|
/// function. Usage:
|
|
|
|
///
|
|
|
|
/// extern "C" void LLVMInitializeFooTarget() {
|
|
|
|
/// extern Target TheFooTarget;
|
|
|
|
/// RegisterTargetMachine<FooTargetMachine> X(TheFooTarget);
|
|
|
|
/// }
|
|
|
|
template<class TargetMachineImpl>
|
|
|
|
struct RegisterTargetMachine {
|
|
|
|
RegisterTargetMachine(Target &T) {
|
|
|
|
TargetRegistry::RegisterTargetMachine(T, &Allocator);
|
|
|
|
}
|
|
|
|
|
2009-08-02 23:37:13 +00:00
|
|
|
private:
|
2011-07-19 06:37:02 +00:00
|
|
|
static TargetMachine *Allocator(const Target &T, StringRef TT,
|
|
|
|
StringRef CPU, StringRef FS,
|
2011-12-02 22:16:29 +00:00
|
|
|
const TargetOptions &Options,
|
2011-07-20 07:51:56 +00:00
|
|
|
Reloc::Model RM,
|
2011-11-16 08:38:26 +00:00
|
|
|
CodeModel::Model CM,
|
|
|
|
CodeGenOpt::Level OL) {
|
2011-12-02 22:16:29 +00:00
|
|
|
return new TargetMachineImpl(T, TT, CPU, FS, Options, RM, CM, OL);
|
2009-08-02 23:37:13 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2011-07-25 23:24:55 +00:00
|
|
|
/// RegisterMCAsmBackend - Helper template for registering a target specific
|
2010-02-21 21:53:53 +00:00
|
|
|
/// assembler backend. Usage:
|
|
|
|
///
|
2011-07-25 23:24:55 +00:00
|
|
|
/// extern "C" void LLVMInitializeFooMCAsmBackend() {
|
2010-02-21 21:53:53 +00:00
|
|
|
/// extern Target TheFooTarget;
|
2011-07-25 23:24:55 +00:00
|
|
|
/// RegisterMCAsmBackend<FooAsmLexer> X(TheFooTarget);
|
2010-02-21 21:53:53 +00:00
|
|
|
/// }
|
2011-07-25 23:24:55 +00:00
|
|
|
template<class MCAsmBackendImpl>
|
|
|
|
struct RegisterMCAsmBackend {
|
|
|
|
RegisterMCAsmBackend(Target &T) {
|
|
|
|
TargetRegistry::RegisterMCAsmBackend(T, &Allocator);
|
2010-02-21 21:53:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2013-09-09 02:37:14 +00:00
|
|
|
static MCAsmBackend *Allocator(const Target &T,
|
|
|
|
const MCRegisterInfo &MRI,
|
|
|
|
StringRef Triple, StringRef CPU) {
|
|
|
|
return new MCAsmBackendImpl(T, MRI, Triple, CPU);
|
2010-02-21 21:53:53 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2011-07-26 00:24:13 +00:00
|
|
|
/// RegisterMCAsmParser - Helper template for registering a target specific
|
2009-07-28 20:47:52 +00:00
|
|
|
/// assembly parser, for use in the target machine initialization
|
|
|
|
/// function. Usage:
|
2009-07-25 06:49:55 +00:00
|
|
|
///
|
2011-07-26 00:24:13 +00:00
|
|
|
/// extern "C" void LLVMInitializeFooMCAsmParser() {
|
2009-07-25 06:49:55 +00:00
|
|
|
/// extern Target TheFooTarget;
|
2011-07-26 00:24:13 +00:00
|
|
|
/// RegisterMCAsmParser<FooAsmParser> X(TheFooTarget);
|
2009-07-25 06:49:55 +00:00
|
|
|
/// }
|
2011-07-26 00:24:13 +00:00
|
|
|
template<class MCAsmParserImpl>
|
|
|
|
struct RegisterMCAsmParser {
|
|
|
|
RegisterMCAsmParser(Target &T) {
|
|
|
|
TargetRegistry::RegisterMCAsmParser(T, &Allocator);
|
2009-07-25 06:49:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2013-09-12 10:28:05 +00:00
|
|
|
static MCTargetAsmParser *Allocator(MCSubtargetInfo &STI, MCAsmParser &P,
|
2014-04-23 11:16:03 +00:00
|
|
|
const MCInstrInfo &MII,
|
|
|
|
const MCTargetOptions &Options) {
|
|
|
|
return new MCAsmParserImpl(STI, P, MII, Options);
|
2009-07-25 06:49:55 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2010-02-21 21:53:37 +00:00
|
|
|
/// RegisterAsmPrinter - Helper template for registering a target specific
|
|
|
|
/// assembly printer, for use in the target machine initialization
|
|
|
|
/// function. Usage:
|
|
|
|
///
|
|
|
|
/// extern "C" void LLVMInitializeFooAsmPrinter() {
|
|
|
|
/// extern Target TheFooTarget;
|
|
|
|
/// RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget);
|
|
|
|
/// }
|
|
|
|
template<class AsmPrinterImpl>
|
|
|
|
struct RegisterAsmPrinter {
|
|
|
|
RegisterAsmPrinter(Target &T) {
|
|
|
|
TargetRegistry::RegisterAsmPrinter(T, &Allocator);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2015-01-18 20:29:04 +00:00
|
|
|
static AsmPrinter *Allocator(TargetMachine &TM,
|
|
|
|
std::unique_ptr<MCStreamer> &&Streamer) {
|
|
|
|
return new AsmPrinterImpl(TM, std::move(Streamer));
|
2010-02-21 21:53:37 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2011-07-26 00:42:34 +00:00
|
|
|
/// RegisterMCCodeEmitter - Helper template for registering a target specific
|
2009-08-27 00:51:57 +00:00
|
|
|
/// machine code emitter, for use in the target initialization
|
|
|
|
/// function. Usage:
|
|
|
|
///
|
2011-07-26 00:42:34 +00:00
|
|
|
/// extern "C" void LLVMInitializeFooMCCodeEmitter() {
|
2009-08-27 00:51:57 +00:00
|
|
|
/// extern Target TheFooTarget;
|
2011-07-26 00:42:34 +00:00
|
|
|
/// RegisterMCCodeEmitter<FooCodeEmitter> X(TheFooTarget);
|
2009-08-27 00:51:57 +00:00
|
|
|
/// }
|
2011-07-26 00:42:34 +00:00
|
|
|
template<class MCCodeEmitterImpl>
|
|
|
|
struct RegisterMCCodeEmitter {
|
|
|
|
RegisterMCCodeEmitter(Target &T) {
|
|
|
|
TargetRegistry::RegisterMCCodeEmitter(T, &Allocator);
|
2009-08-27 00:51:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2015-03-10 22:03:14 +00:00
|
|
|
static MCCodeEmitter *Allocator(const MCInstrInfo & /*II*/,
|
|
|
|
const MCRegisterInfo & /*MRI*/,
|
|
|
|
MCContext & /*Ctx*/) {
|
2011-07-26 00:42:34 +00:00
|
|
|
return new MCCodeEmitterImpl();
|
2009-08-27 00:51:57 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2009-07-15 04:24:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|