Extend C disassembler API to allow specifying target features

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218682 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bradley Smith 2014-09-30 16:31:40 +00:00
parent 8a6f79e58d
commit 95b3e168c5
4 changed files with 66 additions and 26 deletions

View File

@ -174,8 +174,8 @@ extern "C" {
* by passing a block of information in the DisInfo parameter and specifying the * by passing a block of information in the DisInfo parameter and specifying the
* TagType and callback functions as described above. These can all be passed * TagType and callback functions as described above. These can all be passed
* as NULL. If successful, this returns a disassembler context. If not, it * as NULL. If successful, this returns a disassembler context. If not, it
* returns NULL. This function is equivalent to calling LLVMCreateDisasmCPU() * returns NULL. This function is equivalent to calling
* with an empty CPU name. * LLVMCreateDisasmCPUFeatures() with an empty CPU name and feature set.
*/ */
LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo, LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo,
int TagType, LLVMOpInfoCallback GetOpInfo, int TagType, LLVMOpInfoCallback GetOpInfo,
@ -186,13 +186,27 @@ LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo,
* disassembly is supported by passing a block of information in the DisInfo * disassembly is supported by passing a block of information in the DisInfo
* parameter and specifying the TagType and callback functions as described * parameter and specifying the TagType and callback functions as described
* above. These can all be passed * as NULL. If successful, this returns a * above. These can all be passed * as NULL. If successful, this returns a
* disassembler context. If not, it returns NULL. * disassembler context. If not, it returns NULL. This function is equivalent
* to calling LLVMCreateDisasmCPUFeatures() with an empty feature set.
*/ */
LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU, LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU,
void *DisInfo, int TagType, void *DisInfo, int TagType,
LLVMOpInfoCallback GetOpInfo, LLVMOpInfoCallback GetOpInfo,
LLVMSymbolLookupCallback SymbolLookUp); LLVMSymbolLookupCallback SymbolLookUp);
/**
* Create a disassembler for the TripleName, a specific CPU and specific feature
* string. Symbolic disassembly is supported by passing a block of information
* in the DisInfo parameter and specifying the TagType and callback functions as
* described above. These can all be passed * as NULL. If successful, this
* returns a disassembler context. If not, it returns NULL.
*/
LLVMDisasmContextRef
LLVMCreateDisasmCPUFeatures(const char *Triple, const char *CPU,
const char *Features, void *DisInfo, int TagType,
LLVMOpInfoCallback GetOpInfo,
LLVMSymbolLookupCallback SymbolLookUp);
/** /**
* Set the disassembler's options. Returns 1 if it can set the Options and 0 * Set the disassembler's options. Returns 1 if it can set the Options and 0
* otherwise. * otherwise.

View File

@ -33,8 +33,9 @@ using namespace llvm;
// functions can all be passed as NULL. If successful, this returns a // functions can all be passed as NULL. If successful, this returns a
// disassembler context. If not, it returns NULL. // disassembler context. If not, it returns NULL.
// //
LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU, LLVMDisasmContextRef
void *DisInfo, int TagType, LLVMCreateDisasmCPUFeatures(const char *Triple, const char *CPU,
const char *Features, void *DisInfo, int TagType,
LLVMOpInfoCallback GetOpInfo, LLVMOpInfoCallback GetOpInfo,
LLVMSymbolLookupCallback SymbolLookUp) { LLVMSymbolLookupCallback SymbolLookUp) {
// Get the target. // Get the target.
@ -56,11 +57,8 @@ LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU,
if (!MII) if (!MII)
return nullptr; return nullptr;
// Package up features to be passed to target/subtarget
std::string FeaturesStr;
const MCSubtargetInfo *STI = TheTarget->createMCSubtargetInfo(Triple, CPU, const MCSubtargetInfo *STI = TheTarget->createMCSubtargetInfo(Triple, CPU,
FeaturesStr); Features);
if (!STI) if (!STI)
return nullptr; return nullptr;
@ -101,11 +99,19 @@ LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU,
return DC; return DC;
} }
LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU,
void *DisInfo, int TagType,
LLVMOpInfoCallback GetOpInfo,
LLVMSymbolLookupCallback SymbolLookUp){
return LLVMCreateDisasmCPUFeatures(Triple, CPU, "", DisInfo, TagType,
GetOpInfo, SymbolLookUp);
}
LLVMDisasmContextRef LLVMCreateDisasm(const char *Triple, void *DisInfo, LLVMDisasmContextRef LLVMCreateDisasm(const char *Triple, void *DisInfo,
int TagType, LLVMOpInfoCallback GetOpInfo, int TagType, LLVMOpInfoCallback GetOpInfo,
LLVMSymbolLookupCallback SymbolLookUp) { LLVMSymbolLookupCallback SymbolLookUp) {
return LLVMCreateDisasmCPU(Triple, "", DisInfo, TagType, GetOpInfo, return LLVMCreateDisasmCPUFeatures(Triple, "", "", DisInfo, TagType,
SymbolLookUp); GetOpInfo, SymbolLookUp);
} }
// //

View File

@ -1,15 +1,27 @@
; RUN: llvm-c-test --disassemble < %s | FileCheck %s ; RUN: llvm-c-test --disassemble < %s | FileCheck %s
armv8-linux-gnu +crypto 02 00 81 e0 02 03 b0 f3
;CHECK: triple: armv8-linux-gnu, features: +crypto
;CHECK: 02 00 81 e0 add r0, r1, r2
;CHECK: 02 03 b0 f3 aese.8 q0, q1
arm-linux-android 44 26 1f e5 0c 10 4b e2 02 20 81 e0 armv8-linux-gnu -crypto 02 00 81 e0 02 03 b0 f3
;CHECK: triple: arm-linux-android ;CHECK: triple: armv8-linux-gnu, features: -crypto
;CHECK: 02 00 81 e0 add r0, r1, r2
;CHECK: 02 ???
;CHECK: 03 ???
;CHECK: b0 ???
;CHECK: f3 ???
arm-linux-android NULL 44 26 1f e5 0c 10 4b e2 02 20 81 e0
;CHECK: triple: arm-linux-android, features: NULL
;CHECK: ldr r2, [pc, #-1604] ;CHECK: ldr r2, [pc, #-1604]
;CHECK: sub r1, r11, #12 ;CHECK: sub r1, r11, #12
;CHECK: 02 20 81 e0 ;CHECK: 02 20 81 e0
;CHECK: add r2, r1, r2 ;CHECK: add r2, r1, r2
x86_64-linux-unknown 48 83 c4 38 5b 5d 41 5c 41 5d 41 5e 41 5f c3 x86_64-linux-unknown NULL 48 83 c4 38 5b 5d 41 5c 41 5d 41 5e 41 5f c3
;CHECK: triple: x86_64-linux-unknown ;CHECK: triple: x86_64-linux-unknown, features: NULL
;CHECK: addq $56, %rsp ;CHECK: addq $56, %rsp
;CHECK: popq %rbx ;CHECK: popq %rbx
;CHECK: popq %rbp ;CHECK: popq %rbp
@ -19,11 +31,13 @@ x86_64-linux-unknown 48 83 c4 38 5b 5d 41 5c 41 5d 41 5e 41 5f c3
;CHECK: popq %r15 ;CHECK: popq %r15
;CHECK: ret ;CHECK: ret
i686-apple-darwin 0f b7 4c 24 0a e8 29 ce ff ff i686-apple-darwin NULL 0f b7 4c 24 0a e8 29 ce ff ff
;CHECK: triple: i686-apple-darwin, features: NULL
;CHECK: movzwl 10(%esp), %ecx ;CHECK: movzwl 10(%esp), %ecx
;CHECK: calll -12759 ;CHECK: calll -12759
i686-linux-unknown dd 44 24 04 d9 e1 c3 i686-linux-unknown NULL dd 44 24 04 d9 e1 c3
;CHECK: triple: i686-linux-unknown, features: NULL
;CHECK: fldl 4(%esp) ;CHECK: fldl 4(%esp)
;CHECK: fabs ;CHECK: fabs
;CHECK: ret ;CHECK: ret

View File

@ -18,6 +18,7 @@
#include "llvm-c/Target.h" #include "llvm-c/Target.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
static void pprint(int pos, unsigned char *buf, int len, const char *disasm) { static void pprint(int pos, unsigned char *buf, int len, const char *disasm) {
int i; int i;
@ -33,13 +34,15 @@ static void pprint(int pos, unsigned char *buf, int len, const char *disasm) {
printf(" %s\n", disasm); printf(" %s\n", disasm);
} }
static void do_disassemble(const char *triple, unsigned char *buf, int siz) { static void do_disassemble(const char *triple, const char *features,
LLVMDisasmContextRef D = LLVMCreateDisasm(triple, NULL, 0, NULL, NULL); unsigned char *buf, int siz) {
LLVMDisasmContextRef D = LLVMCreateDisasmCPUFeatures(triple, "", features,
NULL, 0, NULL, NULL);
char outline[1024]; char outline[1024];
int pos; int pos;
if (!D) { if (!D) {
printf("ERROR: Couldn't create disassebler for triple %s\n", triple); printf("ERROR: Couldn't create disassembler for triple %s\n", triple);
return; return;
} }
@ -62,19 +65,22 @@ static void do_disassemble(const char *triple, unsigned char *buf, int siz) {
static void handle_line(char **tokens, int ntokens) { static void handle_line(char **tokens, int ntokens) {
unsigned char disbuf[128]; unsigned char disbuf[128];
size_t disbuflen = 0; size_t disbuflen = 0;
char *triple = tokens[0]; const char *triple = tokens[0];
const char *features = tokens[1];
int i; int i;
printf("triple: %s\n", triple); printf("triple: %s, features: %s\n", triple, features);
if (!strcmp(features, "NULL"))
features = "";
for (i = 1; i < ntokens; i++) { for (i = 2; i < ntokens; i++) {
disbuf[disbuflen++] = strtol(tokens[i], NULL, 16); disbuf[disbuflen++] = strtol(tokens[i], NULL, 16);
if (disbuflen >= sizeof(disbuf)) { if (disbuflen >= sizeof(disbuf)) {
fprintf(stderr, "Warning: Too long line, truncating\n"); fprintf(stderr, "Warning: Too long line, truncating\n");
break; break;
} }
} }
do_disassemble(triple, disbuf, disbuflen); do_disassemble(triple, features, disbuf, disbuflen);
} }
int disassemble(void) { int disassemble(void) {