mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
Add llvm-c-test tool for testing llvm-c
This provides rudimentary testing of the llvm-c api. The following commands are implemented: * --module-dump Read bytecode from stdin - print ir * --module-list-functions Read bytecode from stdin - list summary of functions * --module-list-globals Read bytecode from stdin - list summary of globals * --targets-list List available targets * --object-list-sections Read object file from stdin - list sections * --object-list-symbols Read object file from stdin - list symbols (like nm) * --disassemble Read lines of triple, hex ascii machine code from stdin - print disassembly * --calc Read lines of name, rpn from stdin - print generated module ir Differential-Revision: http://llvm-reviews.chandlerc.com/D1776 llvm-svn: 193233
This commit is contained in:
parent
3d22dc6eef
commit
94fc29186e
15
test/Bindings/llvm-c/calc.test
Normal file
15
test/Bindings/llvm-c/calc.test
Normal file
@ -0,0 +1,15 @@
|
||||
; RUN: llvm-c-test --calc <%s | FileCheck %s
|
||||
|
||||
; constant folding
|
||||
test 100 200 +
|
||||
;CHECK: ModuleID = 'test'
|
||||
;CHECK: define i64 @test
|
||||
;CHECK: {
|
||||
;CHECK: ret i64 300
|
||||
;CHECK: }
|
||||
|
||||
arg1 0 @ 0 @ * 1 @ 1 @ * +
|
||||
;CHECK: ModuleID = 'arg1'
|
||||
;CHECK: getelementptr
|
||||
;CHECK: load
|
||||
;CHECK: ret
|
29
test/Bindings/llvm-c/disassemble.test
Normal file
29
test/Bindings/llvm-c/disassemble.test
Normal file
@ -0,0 +1,29 @@
|
||||
; RUN: llvm-c-test --disassemble < %s | FileCheck %s
|
||||
|
||||
|
||||
arm-linux-android 44 26 1f e5 0c 10 4b e2 02 20 81 e0
|
||||
;CHECK: triple: arm-linux-android
|
||||
;CHECK: ldr r2, [pc, #-1604]
|
||||
;CHECK: sub r1, r11, #12
|
||||
;CHECK: 02 20 81 e0
|
||||
;CHECK: add r2, r1, r2
|
||||
|
||||
x86_64-linux-unknown 48 83 c4 38 5b 5d 41 5c 41 5d 41 5e 41 5f c3
|
||||
;CHECK: triple: x86_64-linux-unknown
|
||||
;CHECK: addq $56, %rsp
|
||||
;CHECK: popq %rbx
|
||||
;CHECK: popq %rbp
|
||||
;CHECK: popq %r12
|
||||
;CHECK: popq %r13
|
||||
;CHECK: popq %r14
|
||||
;CHECK: popq %r15
|
||||
;CHECK: ret
|
||||
|
||||
i686-apple-darwin 0f b7 4c 24 0a e8 29 ce ff ff
|
||||
;CHECK: movzwl 10(%esp), %ecx
|
||||
;CHECK: calll -12759
|
||||
|
||||
i686-linux-unknown dd 44 24 04 d9 e1 c3
|
||||
;CHECK: fldl 4(%esp)
|
||||
;CHECK: fabs
|
||||
;CHECK: ret
|
31
test/Bindings/llvm-c/functions.ll
Normal file
31
test/Bindings/llvm-c/functions.ll
Normal file
@ -0,0 +1,31 @@
|
||||
; RUN: llvm-as < %s | llvm-c-test --module-list-functions | FileCheck %s
|
||||
|
||||
define i32 @X() {
|
||||
entry:
|
||||
br label %l1
|
||||
|
||||
l1:
|
||||
br label %l2
|
||||
|
||||
l2:
|
||||
br label %l3
|
||||
|
||||
l3:
|
||||
ret i32 1234
|
||||
}
|
||||
;CHECK: FunctionDefinition: X [#bb=4]
|
||||
|
||||
|
||||
define i32 @Z(i32 %a) {
|
||||
entry:
|
||||
%0 = tail call i32 @Y(i32 %a)
|
||||
ret i32 %0
|
||||
}
|
||||
|
||||
;CHECK: FunctionDefinition: Z [#bb=1]
|
||||
;CHECK: calls: Y
|
||||
;CHECK: #isn: 2
|
||||
|
||||
declare i32 @Y(i32)
|
||||
;CHECK: FunctionDeclaration: Y
|
||||
|
7
test/Bindings/llvm-c/globals.ll
Normal file
7
test/Bindings/llvm-c/globals.ll
Normal file
@ -0,0 +1,7 @@
|
||||
; RUN: llvm-as < %s | llvm-c-test --module-list-globals | FileCheck %s
|
||||
|
||||
@foo = constant [7 x i8] c"foobar\00", align 1
|
||||
;CHECK: GlobalDefinition: foo [7 x i8]*
|
||||
|
||||
@bar = common global i32 0, align 4
|
||||
;CHECK: GlobalDefinition: bar i32*
|
3
test/Bindings/llvm-c/lit.local.cfg
Normal file
3
test/Bindings/llvm-c/lit.local.cfg
Normal file
@ -0,0 +1,3 @@
|
||||
targets = set(config.root.targets_to_build.split())
|
||||
if not (targets & set(["X86", "ARM"])):
|
||||
config.unsupported = True
|
@ -232,6 +232,7 @@ for pattern in [r"\bbugpoint\b(?!-)",
|
||||
r"\bllvm-shlib\b",
|
||||
r"\bllvm-size\b",
|
||||
r"\bllvm-tblgen\b",
|
||||
r"\bllvm-c-test\b",
|
||||
# Match llvmc but not -llvmc
|
||||
NOHYPHEN + r"\bllvmc\b",
|
||||
# Match lto but not -lto
|
||||
|
@ -39,6 +39,12 @@ add_llvm_tool_subdirectory(llvm-mcmarkup)
|
||||
|
||||
add_llvm_tool_subdirectory(llvm-symbolizer)
|
||||
|
||||
if( NOT MSVC )
|
||||
add_llvm_tool_subdirectory(llvm-c-test)
|
||||
else()
|
||||
ignore_llvm_tool_subdirectory(llvm-c-test)
|
||||
endif( NOT MSVC )
|
||||
|
||||
add_llvm_tool_subdirectory(obj2yaml)
|
||||
add_llvm_tool_subdirectory(yaml2obj)
|
||||
|
||||
|
@ -31,7 +31,7 @@ PARALLEL_DIRS := opt llvm-as llvm-dis llc llvm-ar llvm-nm llvm-link \
|
||||
lli llvm-extract llvm-mc bugpoint llvm-bcanalyzer llvm-diff \
|
||||
macho-dump llvm-objdump llvm-readobj llvm-rtdyld \
|
||||
llvm-dwarfdump llvm-cov llvm-size llvm-stress llvm-mcmarkup \
|
||||
llvm-symbolizer obj2yaml yaml2obj
|
||||
llvm-symbolizer obj2yaml yaml2obj llvm-c-test
|
||||
|
||||
# If Intel JIT Events support is configured, build an extra tool to test it.
|
||||
ifeq ($(USE_INTEL_JITEVENTS), 1)
|
||||
|
16
tools/llvm-c-test/CMakeLists.txt
Normal file
16
tools/llvm-c-test/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
||||
set(LLVM_LINK_COMPONENTS all)
|
||||
|
||||
if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wstrict-prototypes")
|
||||
endif ()
|
||||
|
||||
add_llvm_tool(llvm-c-test
|
||||
calc.c
|
||||
disassemble.c
|
||||
helpers.c
|
||||
include-all.c
|
||||
main.c
|
||||
module.c
|
||||
object.c
|
||||
targets.c
|
||||
)
|
29
tools/llvm-c-test/Makefile
Normal file
29
tools/llvm-c-test/Makefile
Normal file
@ -0,0 +1,29 @@
|
||||
##===- tools/llvm-c-test -----------------------------------*- Makefile -*-===##
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
# This file is distributed under the University of Illinois Open Source
|
||||
# License. See LICENSE.TXT for details.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
LEVEL = ../..
|
||||
TOOLNAME = llvm-c-test
|
||||
|
||||
TOOL_NO_EXPORTS = 1
|
||||
NO_INSTALL = 1
|
||||
|
||||
|
||||
# If there is no shared lib, link all components...
|
||||
ifneq ($(ENABLE_SHARED),1)
|
||||
LINK_COMPONENTS = all
|
||||
endif
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
||||
|
||||
CFLAGS += -std=c99 -Wall -Wstrict-prototypes
|
||||
|
||||
# ...but if it is built - use it
|
||||
ifeq ($(ENABLE_SHARED),1)
|
||||
LIBS = -lLLVM-$(LLVMVersion)
|
||||
endif
|
143
tools/llvm-c-test/calc.c
Normal file
143
tools/llvm-c-test/calc.c
Normal file
@ -0,0 +1,143 @@
|
||||
/*===-- calc.c - tool for testing libLLVM and llvm-c API ------------------===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This file implements the --calc command in llvm-c-test. --calc reads lines *|
|
||||
|* from stdin, parses them as a name and an expression in reverse polish *|
|
||||
|* notation and prints a module with a function with the expression. *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#include "llvm-c-test.h"
|
||||
#include "llvm-c/Core.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
typedef LLVMValueRef (*binop_func_t)(LLVMBuilderRef, LLVMValueRef LHS,
|
||||
LLVMValueRef RHS, const char *Name);
|
||||
|
||||
static LLVMOpcode op_to_opcode(char op) {
|
||||
switch (op) {
|
||||
case '+': return LLVMAdd;
|
||||
case '-': return LLVMSub;
|
||||
case '*': return LLVMMul;
|
||||
case '/': return LLVMSDiv;
|
||||
case '&': return LLVMAnd;
|
||||
case '|': return LLVMOr;
|
||||
case '^': return LLVMXor;
|
||||
}
|
||||
assert(0 && "unknown operation");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MAX_DEPTH 32
|
||||
|
||||
static LLVMValueRef build_from_tokens(char **tokens, int ntokens,
|
||||
LLVMBuilderRef builder,
|
||||
LLVMValueRef param) {
|
||||
LLVMValueRef stack[MAX_DEPTH];
|
||||
int depth = 0;
|
||||
|
||||
for (int i = 0; i < ntokens; i++) {
|
||||
char tok = tokens[i][0];
|
||||
switch (tok) {
|
||||
case '+':
|
||||
case '-':
|
||||
case '*':
|
||||
case '/':
|
||||
case '&':
|
||||
case '|':
|
||||
case '^':
|
||||
if (depth < 2) {
|
||||
printf("stack underflow\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
stack[depth - 2] = LLVMBuildBinOp(builder, op_to_opcode(tok),
|
||||
stack[depth - 1], stack[depth - 2], "");
|
||||
depth--;
|
||||
|
||||
break;
|
||||
|
||||
case '@':
|
||||
if (depth < 1) {
|
||||
printf("stack underflow\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LLVMValueRef off = LLVMBuildGEP(builder, param, &stack[depth - 1], 1, "");
|
||||
stack[depth - 1] = LLVMBuildLoad(builder, off, "");
|
||||
|
||||
break;
|
||||
|
||||
default: {
|
||||
char *end;
|
||||
long val = strtol(tokens[i], &end, 0);
|
||||
if (end[0] != '\0') {
|
||||
printf("error parsing number\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (depth >= MAX_DEPTH) {
|
||||
printf("stack overflow\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
stack[depth++] = LLVMConstInt(LLVMInt64Type(), val, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (depth < 1) {
|
||||
printf("stack underflow at return\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LLVMBuildRet(builder, stack[depth - 1]);
|
||||
|
||||
return stack[depth - 1];
|
||||
}
|
||||
|
||||
static void handle_line(char **tokens, int ntokens) {
|
||||
char *name = tokens[0];
|
||||
|
||||
LLVMModuleRef M = LLVMModuleCreateWithName(name);
|
||||
|
||||
LLVMTypeRef I64ty = LLVMInt64Type();
|
||||
LLVMTypeRef I64Ptrty = LLVMPointerType(I64ty, 0);
|
||||
LLVMTypeRef Fty = LLVMFunctionType(I64ty, &I64Ptrty, 1, 0);
|
||||
|
||||
LLVMValueRef F = LLVMAddFunction(M, name, Fty);
|
||||
LLVMBuilderRef builder = LLVMCreateBuilder();
|
||||
LLVMPositionBuilderAtEnd(builder, LLVMAppendBasicBlock(F, "entry"));
|
||||
|
||||
LLVMValueRef param;
|
||||
LLVMGetParams(F, ¶m);
|
||||
LLVMSetValueName(param, "in");
|
||||
|
||||
LLVMValueRef res = build_from_tokens(tokens + 1, ntokens - 1, builder, param);
|
||||
if (res) {
|
||||
char *irstr = LLVMPrintModuleToString(M);
|
||||
puts(irstr);
|
||||
LLVMDisposeMessage(irstr);
|
||||
}
|
||||
|
||||
LLVMDisposeBuilder(builder);
|
||||
|
||||
LLVMDisposeModule(M);
|
||||
}
|
||||
|
||||
int calc(void) {
|
||||
|
||||
tokenize_stdin(handle_line);
|
||||
|
||||
return 0;
|
||||
}
|
85
tools/llvm-c-test/disassemble.c
Normal file
85
tools/llvm-c-test/disassemble.c
Normal file
@ -0,0 +1,85 @@
|
||||
/*===-- disassemble.c - tool for testing libLLVM and llvm-c API -----------===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This file implements the --disassemble command in llvm-c-test. *|
|
||||
|* --disassemble reads lines from stdin, parses them as a triple and hex *|
|
||||
|* machine code, and prints disassembly of the machine code. *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#include "llvm-c-test.h"
|
||||
#include "llvm-c/Disassembler.h"
|
||||
#include "llvm-c/Target.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static void pprint(int pos, unsigned char *buf, int len, const char *disasm) {
|
||||
printf("%04x: ", pos);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (i < len) {
|
||||
printf("%02x ", buf[i]);
|
||||
} else {
|
||||
printf(" ");
|
||||
}
|
||||
}
|
||||
|
||||
printf(" %s\n", disasm);
|
||||
}
|
||||
|
||||
static void do_disassemble(const char *triple, unsigned char *buf, int siz) {
|
||||
LLVMDisasmContextRef D = LLVMCreateDisasm(triple, NULL, 0, NULL, NULL);
|
||||
|
||||
if (!D) {
|
||||
printf("ERROR: Couldn't create disassebler for triple %s\n", triple);
|
||||
return;
|
||||
}
|
||||
|
||||
char outline[1024];
|
||||
int pos = 0;
|
||||
while (pos < siz) {
|
||||
size_t l = LLVMDisasmInstruction(D, buf + pos, siz - pos, 0, outline,
|
||||
sizeof(outline));
|
||||
if (!l) {
|
||||
pprint(pos, buf + pos, 1, "\t???");
|
||||
pos++;
|
||||
} else {
|
||||
pprint(pos, buf + pos, l, outline);
|
||||
pos += l;
|
||||
}
|
||||
}
|
||||
|
||||
LLVMDisasmDispose(D);
|
||||
}
|
||||
|
||||
static void handle_line(char **tokens, int ntokens) {
|
||||
unsigned char disbuf[128];
|
||||
size_t disbuflen = 0;
|
||||
char *triple = tokens[0];
|
||||
|
||||
printf("triple: %s\n", triple);
|
||||
|
||||
for (int i = 1; i < ntokens; i++) {
|
||||
disbuf[disbuflen++] = strtol(tokens[i], NULL, 16);
|
||||
if (disbuflen >= sizeof(disbuf)) {
|
||||
fprintf(stderr, "Warning: Too long line, truncating\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
do_disassemble(triple, disbuf, disbuflen);
|
||||
}
|
||||
|
||||
int disassemble(void) {
|
||||
LLVMInitializeAllTargetInfos();
|
||||
LLVMInitializeAllTargetMCs();
|
||||
LLVMInitializeAllDisassemblers();
|
||||
|
||||
tokenize_stdin(handle_line);
|
||||
|
||||
return 0;
|
||||
}
|
40
tools/llvm-c-test/helpers.c
Normal file
40
tools/llvm-c-test/helpers.c
Normal file
@ -0,0 +1,40 @@
|
||||
/*===-- helpers.c - tool for testing libLLVM and llvm-c API ---------------===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* Helper functions *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#include "llvm-c-test.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAX_TOKENS 512
|
||||
#define MAX_LINE_LEN 1024
|
||||
|
||||
void tokenize_stdin(void (*cb)(char **tokens, int ntokens)) {
|
||||
char line[MAX_LINE_LEN];
|
||||
char *tokbuf[MAX_TOKENS];
|
||||
|
||||
while (fgets(line, sizeof(line), stdin)) {
|
||||
int c = 0;
|
||||
|
||||
if (line[0] == ';' || line[0] == '\n')
|
||||
continue;
|
||||
|
||||
while (c < MAX_TOKENS) {
|
||||
tokbuf[c] = strtok(c ? NULL : line, " \n");
|
||||
if (!tokbuf[c])
|
||||
break;
|
||||
c++;
|
||||
}
|
||||
if (c)
|
||||
cb(tokbuf, c);
|
||||
}
|
||||
}
|
33
tools/llvm-c-test/include-all.c
Normal file
33
tools/llvm-c-test/include-all.c
Normal file
@ -0,0 +1,33 @@
|
||||
/*===-- include-all.c - tool for testing libLLVM and llvm-c API -----------===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This file doesn't have any actual code. It just make sure that all *|
|
||||
|* the llvm-c include files are good and doesn't generate any warnings *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
// FIXME: Autogenerate this list
|
||||
|
||||
#include "llvm-c/Analysis.h"
|
||||
#include "llvm-c/BitReader.h"
|
||||
#include "llvm-c/BitWriter.h"
|
||||
#include "llvm-c/Core.h"
|
||||
#include "llvm-c/Disassembler.h"
|
||||
#include "llvm-c/ExecutionEngine.h"
|
||||
#include "llvm-c/Initialization.h"
|
||||
#include "llvm-c/LinkTimeOptimizer.h"
|
||||
#include "llvm-c/Linker.h"
|
||||
#include "llvm-c/Object.h"
|
||||
#include "llvm-c/Target.h"
|
||||
#include "llvm-c/TargetMachine.h"
|
||||
#include "llvm-c/Transforms/IPO.h"
|
||||
#include "llvm-c/Transforms/PassManagerBuilder.h"
|
||||
#include "llvm-c/Transforms/Scalar.h"
|
||||
#include "llvm-c/Transforms/Vectorize.h"
|
||||
#include "llvm-c/lto.h"
|
37
tools/llvm-c-test/llvm-c-test.h
Normal file
37
tools/llvm-c-test/llvm-c-test.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*===-- llvm-c-test.h - tool for testing libLLVM and llvm-c API -----------===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* Header file for llvm-c-test *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
#ifndef LLVM_C_TEST_H
|
||||
#define LLVM_C_TEST_H
|
||||
|
||||
// helpers.c
|
||||
void tokenize_stdin(void (*cb)(char **tokens, int ntokens));
|
||||
|
||||
// module.c
|
||||
int module_dump(void);
|
||||
int module_list_functions(void);
|
||||
int module_list_globals(void);
|
||||
|
||||
// calc.c
|
||||
int calc(void);
|
||||
|
||||
// disassemble.c
|
||||
int disassemble(void);
|
||||
|
||||
// object.c
|
||||
int object_list_sections(void);
|
||||
int object_list_symbols(void);
|
||||
|
||||
// targets.c
|
||||
int targets_list(void);
|
||||
|
||||
#endif
|
73
tools/llvm-c-test/main.c
Normal file
73
tools/llvm-c-test/main.c
Normal file
@ -0,0 +1,73 @@
|
||||
/*===-- main.c - tool for testing libLLVM and llvm-c API ------------------===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* Main file for llvm-c-tests. "Parses" arguments and dispatches. *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#include "llvm-c-test.h"
|
||||
#include "llvm-c/BitReader.h"
|
||||
#include "llvm-c/Core.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static void print_usage(void) {
|
||||
fprintf(stderr, "llvm-c-test command\n\n");
|
||||
fprintf(stderr, " Commands:\n");
|
||||
fprintf(stderr, " * --module-dump\n");
|
||||
fprintf(stderr, " Read bytecode from stdin - print disassembly\n\n");
|
||||
fprintf(stderr, " * --module-list-functions\n");
|
||||
fprintf(stderr,
|
||||
" Read bytecode from stdin - list summary of functions\n\n");
|
||||
fprintf(stderr, " * --module-list-globals\n");
|
||||
fprintf(stderr, " Read bytecode from stdin - list summary of globals\n\n");
|
||||
fprintf(stderr, " * --targets-list\n");
|
||||
fprintf(stderr, " List available targets\n\n");
|
||||
fprintf(stderr, " * --object-list-sections\n");
|
||||
fprintf(stderr, " Read object file form stdin - list sections\n\n");
|
||||
fprintf(stderr, " * --object-list-symbols\n");
|
||||
fprintf(stderr,
|
||||
" Read object file form stdin - list symbols (like nm)\n\n");
|
||||
fprintf(stderr, " * --disassemble\n");
|
||||
fprintf(stderr, " Read lines of triple, hex ascii machine code from stdin "
|
||||
"- print disassembly\n\n");
|
||||
fprintf(stderr, " * --calc\n");
|
||||
fprintf(
|
||||
stderr,
|
||||
" Read lines of name, rpn from stdin - print generated module\n\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
LLVMPassRegistryRef pr = LLVMGetGlobalPassRegistry();
|
||||
|
||||
LLVMInitializeCore(pr);
|
||||
|
||||
if (argc == 2 && !strcmp(argv[1], "--module-dump")) {
|
||||
return module_dump();
|
||||
} else if (argc == 2 && !strcmp(argv[1], "--module-list-functions")) {
|
||||
return module_list_functions();
|
||||
} else if (argc == 2 && !strcmp(argv[1], "--module-list-globals")) {
|
||||
return module_list_globals();
|
||||
} else if (argc == 2 && !strcmp(argv[1], "--targets-list")) {
|
||||
return targets_list();
|
||||
} else if (argc == 2 && !strcmp(argv[1], "--object-list-sections")) {
|
||||
return object_list_sections();
|
||||
} else if (argc == 2 && !strcmp(argv[1], "--object-list-symbols")) {
|
||||
return object_list_symbols();
|
||||
} else if (argc == 2 && !strcmp(argv[1], "--disassemble")) {
|
||||
return disassemble();
|
||||
} else if (argc == 2 && !strcmp(argv[1], "--calc")) {
|
||||
return calc();
|
||||
} else {
|
||||
print_usage();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
112
tools/llvm-c-test/module.c
Normal file
112
tools/llvm-c-test/module.c
Normal file
@ -0,0 +1,112 @@
|
||||
/*===-- module.c - tool for testing libLLVM and llvm-c API ----------------===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This file implements the --module-dump, --module-list-functions and *|
|
||||
|* --module-list-globals commands in llvm-c-test. *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#include "llvm-c-test.h"
|
||||
#include "llvm-c/BitReader.h"
|
||||
#include "llvm-c/Core.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static LLVMModuleRef load_module(void) {
|
||||
LLVMMemoryBufferRef MB;
|
||||
LLVMModuleRef M;
|
||||
char *msg = NULL;
|
||||
|
||||
if (LLVMCreateMemoryBufferWithSTDIN(&MB, &msg)) {
|
||||
fprintf(stderr, "Error reading file: %s\n", msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (LLVMParseBitcode(MB, &M, &msg)) {
|
||||
fprintf(stderr, "Error parsing bitcode: %s\n", msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return M;
|
||||
}
|
||||
|
||||
int module_dump(void) {
|
||||
LLVMModuleRef M = load_module();
|
||||
|
||||
char *irstr = LLVMPrintModuleToString(M);
|
||||
puts(irstr);
|
||||
LLVMDisposeMessage(irstr);
|
||||
|
||||
LLVMDisposeModule(M);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int module_list_functions(void) {
|
||||
LLVMModuleRef M = load_module();
|
||||
LLVMValueRef f;
|
||||
|
||||
f = LLVMGetFirstFunction(M);
|
||||
while (f) {
|
||||
if (LLVMIsDeclaration(f)) {
|
||||
printf("FunctionDeclaration: %s\n", LLVMGetValueName(f));
|
||||
} else {
|
||||
unsigned nisn = 0;
|
||||
unsigned nbb = 0;
|
||||
|
||||
printf("FunctionDefinition: %s [#bb=%u]\n", LLVMGetValueName(f),
|
||||
LLVMCountBasicBlocks(f));
|
||||
|
||||
for (LLVMBasicBlockRef bb = LLVMGetFirstBasicBlock(f); bb;
|
||||
bb = LLVMGetNextBasicBlock(bb)) {
|
||||
nbb++;
|
||||
for (LLVMValueRef isn = LLVMGetFirstInstruction(bb); isn;
|
||||
isn = LLVMGetNextInstruction(isn)) {
|
||||
nisn++;
|
||||
if (LLVMIsACallInst(isn)) {
|
||||
LLVMValueRef callee =
|
||||
LLVMGetOperand(isn, LLVMGetNumOperands(isn) - 1);
|
||||
printf(" calls: %s\n", LLVMGetValueName(callee));
|
||||
}
|
||||
}
|
||||
}
|
||||
printf(" #isn: %u\n", nisn);
|
||||
printf(" #bb: %u\n\n", nbb);
|
||||
}
|
||||
f = LLVMGetNextFunction(f);
|
||||
}
|
||||
|
||||
LLVMDisposeModule(M);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int module_list_globals(void) {
|
||||
LLVMModuleRef M = load_module();
|
||||
LLVMValueRef g;
|
||||
|
||||
g = LLVMGetFirstGlobal(M);
|
||||
while (g) {
|
||||
LLVMTypeRef T = LLVMTypeOf(g);
|
||||
char *s = LLVMPrintTypeToString(T);
|
||||
|
||||
printf("Global%s: %s %s\n",
|
||||
LLVMIsDeclaration(g) ? "Declaration" : "Definition",
|
||||
LLVMGetValueName(g), s);
|
||||
|
||||
LLVMDisposeMessage(s);
|
||||
|
||||
g = LLVMGetNextGlobal(g);
|
||||
}
|
||||
|
||||
LLVMDisposeModule(M);
|
||||
|
||||
return 0;
|
||||
}
|
85
tools/llvm-c-test/object.c
Normal file
85
tools/llvm-c-test/object.c
Normal file
@ -0,0 +1,85 @@
|
||||
/*===-- object.c - tool for testing libLLVM and llvm-c API ----------------===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This file implements the --object-list-sections and --object-list-symbols *|
|
||||
|* commands in llvm-c-test. *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#include "llvm-c-test.h"
|
||||
#include "llvm-c/Object.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int object_list_sections(void) {
|
||||
LLVMMemoryBufferRef MB;
|
||||
LLVMObjectFileRef O;
|
||||
char *msg = NULL;
|
||||
|
||||
if (LLVMCreateMemoryBufferWithSTDIN(&MB, &msg)) {
|
||||
fprintf(stderr, "Error reading file: %s\n", msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
O = LLVMCreateObjectFile(MB);
|
||||
if (!O) {
|
||||
fprintf(stderr, "Error reading object\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
LLVMSectionIteratorRef sect = LLVMGetSections(O);
|
||||
while (!LLVMIsSectionIteratorAtEnd(O, sect)) {
|
||||
printf("'%s': @0x%08" PRIx64 " +%" PRIu64 "\n", LLVMGetSectionName(sect),
|
||||
LLVMGetSectionAddress(sect), LLVMGetSectionSize(sect));
|
||||
|
||||
LLVMMoveToNextSection(sect);
|
||||
}
|
||||
|
||||
LLVMDisposeSectionIterator(sect);
|
||||
|
||||
LLVMDisposeObjectFile(O);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int object_list_symbols(void) {
|
||||
LLVMMemoryBufferRef MB;
|
||||
LLVMObjectFileRef O;
|
||||
char *msg = NULL;
|
||||
|
||||
if (LLVMCreateMemoryBufferWithSTDIN(&MB, &msg)) {
|
||||
fprintf(stderr, "Error reading file: %s\n", msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
O = LLVMCreateObjectFile(MB);
|
||||
if (!O) {
|
||||
fprintf(stderr, "Error reading object\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
LLVMSectionIteratorRef sect = LLVMGetSections(O);
|
||||
LLVMSymbolIteratorRef sym = LLVMGetSymbols(O);
|
||||
while (!LLVMIsSymbolIteratorAtEnd(O, sym)) {
|
||||
|
||||
LLVMMoveToContainingSection(sect, sym);
|
||||
printf("%s @0x%08" PRIx64 "/0x%08" PRIx64 " +%" PRIu64 " (%s)\n",
|
||||
LLVMGetSymbolName(sym), LLVMGetSymbolAddress(sym),
|
||||
LLVMGetSymbolFileOffset(sym), LLVMGetSymbolSize(sym),
|
||||
LLVMGetSectionName(sect));
|
||||
|
||||
LLVMMoveToNextSymbol(sym);
|
||||
}
|
||||
|
||||
LLVMDisposeSymbolIterator(sym);
|
||||
|
||||
LLVMDisposeObjectFile(O);
|
||||
|
||||
return 0;
|
||||
}
|
29
tools/llvm-c-test/targets.c
Normal file
29
tools/llvm-c-test/targets.c
Normal file
@ -0,0 +1,29 @@
|
||||
/*===-- targets.c - tool for testing libLLVM and llvm-c API ---------------===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This file implements the --targets command in llvm-c-test. *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#include "llvm-c/TargetMachine.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int targets_list(void) {
|
||||
LLVMInitializeAllTargetInfos();
|
||||
LLVMInitializeAllTargets();
|
||||
|
||||
for (LLVMTargetRef t = LLVMGetFirstTarget(); t; t = LLVMGetNextTarget(t)) {
|
||||
printf("%s", LLVMGetTargetName(t));
|
||||
if (LLVMTargetHasJIT(t))
|
||||
printf(" (+jit)");
|
||||
printf("\n - %s\n", LLVMGetTargetDescription(t));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user