Other articles

  1. OCaml LLVM bindings tutorial, part 3

    See also:

    The previous articles explain how to build applications using the OCaml-LLVM bindings, and how to use the API to manipulate the LLVM objects. This was the “read-only” part of the tutorial, which can be used to analyze LLVM IR.

    This part explains how to create LLVM IR, and write a simple application from scratch, and see how to build and run it.

    Modules

    As in the previous tutorial, we need to create a context and a module:

    let llctx = global_context () in
    let llm = create_module llctx "mymodule" in
    

    Functions

    There are two actions that can be done on functions:

    • declare_function to give only a declaration of the prototype,
    • define_function to give both the declaration and the implementation.

    In both cases, we need to give the signature (return type, number and type of arguments) of the function.

    This is pretty similar to C. We’ll use this to declare the function int main(void).

    The int type is a bit problematic in LLVM (and in C, but for other reasons): integer types must have a known size in LLVM. While this does not change the architecture-independent property …

    read more
  2. OCaml LLVM bindings tutorial, part 2

    See also:

    In the previous tutorial, we’ve seen how to use ocamlbuild and make to build a simple application. In this part, we’ll start exploring the API, and see how to access values and attributes of LLVM objects.

    The base of the code is the same as in part 1: it reads an existing LLVM bitcode file, for example one generated by clang.

    As in previous tutorial part, knowing the LLVM C++ API is not required (but can help).

    LLVM objects

    The top-level container is a module (llmodule). The module contains global variables, types and functions, which in turn contains basic blocks, and basic blocks contain instructions.

    Values

    In the OCaml bindings, all objects (variables, functions, instructions) are instances of the opaque type llvalue.

    A value has a type, a name, a definition, a list of users, and other things like attributes (for ex. visibility or linkage options) or aliases.

    Each value has a type (lltype), which is a composite object to define the type of a value and its arguments. To match the real type, it needs to be converted to a TypeKind.t:

    let rec print_type llty =
      let ty = Llvm …
    read more
  3. OCaml LLVM bindings tutorial, part 1

    LLVM

    OCaml

    This is the first part of a tutorial series, on how to use the OCaml bindings for LLVM. Why use OCaml bindings ? Because you can avoid using the C++ API, spending huge amounts of time compiling Clang sources, then your plugin, then debugging the segfaults again and again. The bindings are stable, cover most of the API, and are quite simple to use, thanks to the Debian packages.

    This tutorial is written based on a Debian Sid, things may differ but should stay similar on other distributions.

    The objectives of this first part are:

    • install the required packages
    • setup a build environment for ocamlbuild
    • build a simple application that reads an LLVM bitcode file and prints it

    Installation

    The required packages are:

    • llvm-3.5-dev
    • libllvm-3.5-ocaml-dev
    • the LLVM and OCaml compilers (llvm-3.5, ocaml)
    • optionally, clang

    The current LLVM version is 3.6, however the OCaml bindings are currently disabled (See Debian bug #783919), because of changes in the required dependencies.

    Project Layout

    The sources are organized as follows:

    part1/
    ├── build
    ├── Makefile
    └── src
        └── tutorial01.ml
    

    First application

    First, create file src/tutorial01.ml:

    let _ =
      let llctx = Llvm.global_context () in
      let llmem = Llvm.MemoryBuffer.of_file Sys.argv.(1) in
      let …
    read more

Page 1 / 1