diff options
-rw-r--r-- | test/Bindings/llvm-c/calc.test | 15 | ||||
-rw-r--r-- | test/Bindings/llvm-c/disassemble.test | 29 | ||||
-rw-r--r-- | test/Bindings/llvm-c/functions.ll | 31 | ||||
-rw-r--r-- | test/Bindings/llvm-c/globals.ll | 7 | ||||
-rw-r--r-- | test/Bindings/llvm-c/lit.local.cfg | 3 | ||||
-rw-r--r-- | test/lit.cfg | 1 | ||||
-rw-r--r-- | tools/CMakeLists.txt | 6 | ||||
-rw-r--r-- | tools/Makefile | 2 | ||||
-rw-r--r-- | tools/llvm-c-test/CMakeLists.txt | 16 | ||||
-rw-r--r-- | tools/llvm-c-test/Makefile | 29 | ||||
-rw-r--r-- | tools/llvm-c-test/calc.c | 143 | ||||
-rw-r--r-- | tools/llvm-c-test/disassemble.c | 85 | ||||
-rw-r--r-- | tools/llvm-c-test/helpers.c | 40 | ||||
-rw-r--r-- | tools/llvm-c-test/include-all.c | 33 | ||||
-rw-r--r-- | tools/llvm-c-test/llvm-c-test.h | 37 | ||||
-rw-r--r-- | tools/llvm-c-test/main.c | 73 | ||||
-rw-r--r-- | tools/llvm-c-test/module.c | 112 | ||||
-rw-r--r-- | tools/llvm-c-test/object.c | 85 | ||||
-rw-r--r-- | tools/llvm-c-test/targets.c | 29 |
19 files changed, 775 insertions, 1 deletions
diff --git a/test/Bindings/llvm-c/calc.test b/test/Bindings/llvm-c/calc.test new file mode 100644 index 0000000..36a76e6 --- /dev/null +++ b/test/Bindings/llvm-c/calc.test @@ -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 diff --git a/test/Bindings/llvm-c/disassemble.test b/test/Bindings/llvm-c/disassemble.test new file mode 100644 index 0000000..201e914 --- /dev/null +++ b/test/Bindings/llvm-c/disassemble.test @@ -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 diff --git a/test/Bindings/llvm-c/functions.ll b/test/Bindings/llvm-c/functions.ll new file mode 100644 index 0000000..4503fb1 --- /dev/null +++ b/test/Bindings/llvm-c/functions.ll @@ -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 + diff --git a/test/Bindings/llvm-c/globals.ll b/test/Bindings/llvm-c/globals.ll new file mode 100644 index 0000000..a38f08b --- /dev/null +++ b/test/Bindings/llvm-c/globals.ll @@ -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* diff --git a/test/Bindings/llvm-c/lit.local.cfg b/test/Bindings/llvm-c/lit.local.cfg new file mode 100644 index 0000000..270a7f2 --- /dev/null +++ b/test/Bindings/llvm-c/lit.local.cfg @@ -0,0 +1,3 @@ +targets = set(config.root.targets_to_build.split()) +if not (targets & set(["X86", "ARM"])): + config.unsupported = True diff --git a/test/lit.cfg b/test/lit.cfg index 9e590a8..1b6fa54 100644 --- a/test/lit.cfg +++ b/test/lit.cfg @@ -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 diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 69c4050..54f849c 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -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) diff --git a/tools/Makefile b/tools/Makefile index 5fa5bf2..be87254 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -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) diff --git a/tools/llvm-c-test/CMakeLists.txt b/tools/llvm-c-test/CMakeLists.txt new file mode 100644 index 0000000..2926d9d --- /dev/null +++ b/tools/llvm-c-test/CMakeLists.txt @@ -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 + ) diff --git a/tools/llvm-c-test/Makefile b/tools/llvm-c-test/Makefile new file mode 100644 index 0000000..08be7c3 --- /dev/null +++ b/tools/llvm-c-test/Makefile @@ -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 diff --git a/tools/llvm-c-test/calc.c b/tools/llvm-c-test/calc.c new file mode 100644 index 0000000..c34ff7b --- /dev/null +++ b/tools/llvm-c-test/calc.c @@ -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; +} diff --git a/tools/llvm-c-test/disassemble.c b/tools/llvm-c-test/disassemble.c new file mode 100644 index 0000000..4b3d37b --- /dev/null +++ b/tools/llvm-c-test/disassemble.c @@ -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; +} diff --git a/tools/llvm-c-test/helpers.c b/tools/llvm-c-test/helpers.c new file mode 100644 index 0000000..1ea8a4f --- /dev/null +++ b/tools/llvm-c-test/helpers.c @@ -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); + } +} diff --git a/tools/llvm-c-test/include-all.c b/tools/llvm-c-test/include-all.c new file mode 100644 index 0000000..17b9917 --- /dev/null +++ b/tools/llvm-c-test/include-all.c @@ -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" diff --git a/tools/llvm-c-test/llvm-c-test.h b/tools/llvm-c-test/llvm-c-test.h new file mode 100644 index 0000000..0a25aa6 --- /dev/null +++ b/tools/llvm-c-test/llvm-c-test.h @@ -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 diff --git a/tools/llvm-c-test/main.c b/tools/llvm-c-test/main.c new file mode 100644 index 0000000..72f8b04 --- /dev/null +++ b/tools/llvm-c-test/main.c @@ -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; +} diff --git a/tools/llvm-c-test/module.c b/tools/llvm-c-test/module.c new file mode 100644 index 0000000..50e6e9c --- /dev/null +++ b/tools/llvm-c-test/module.c @@ -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; +} diff --git a/tools/llvm-c-test/object.c b/tools/llvm-c-test/object.c new file mode 100644 index 0000000..c94e3af --- /dev/null +++ b/tools/llvm-c-test/object.c @@ -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; +} diff --git a/tools/llvm-c-test/targets.c b/tools/llvm-c-test/targets.c new file mode 100644 index 0000000..fccea09 --- /dev/null +++ b/tools/llvm-c-test/targets.c @@ -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; +} |