Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow all LLVM versions >= 15 and support dynamic linking #55

Merged
merged 5 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 97 additions & 7 deletions .github/workflows/cpp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,119 @@ on:

env:
CARGO_TERM_COLOR: always
NYXSTONE_LLVM_PREFIX: "/usr/lib/llvm-15/"

jobs:
linux:
linux-llvm-15:
runs-on: ubuntu-latest
env:
NYXSTONE_LLVM_PREFIX: "/usr/lib/llvm-15/"
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Packages
run: sudo apt-get install llvm-15 llvm-15-dev zlib1g-dev libzstd-dev libboost-program-options-dev cppcheck clang-tidy clang-format
run: |
sudo apt-get update
sudo apt-get install zlib1g-dev libzstd-dev cppcheck clang-tidy clang-format llvm-15 llvm-15-dev
- name: Code quality - fmt
run: ./tool/format.sh check
run: ./tool/format.sh check
- name: Code quality - cppcheck
run: ./tool/static-analysis-cppcheck.sh
- name: Code quality - clang-tidy
run: ./tool/static-analysis-tidy.sh
- name: Build
run: mkdir build/ && cd build && cmake .. && make
run: |
mkdir build
cd build
cmake ..
make
- name: Test
working-directory: build/
run: make test
- name: cli
working-directory: build/
run: |
./nyxstone "mov rax, rbx"
./nyxstone "jmp label" --labels "label=0x1000"

mac-llvm-15:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Packages
run: brew install llvm@15
- name: Build
run: |
mkdir build
cd build
NYXSTONE_LLVM_PREFIX="$(brew --prefix llvm@15)" cmake ..
make
- name: Test
working-directory: build/
run: make test
- name: cli
working-directory: build/
run: |
./nyxstone "mov rax, rbx" &&
./nyxstone "mov rax, rbx"
./nyxstone "jmp label" --labels "label=0x1000"

mac-llvm-16:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Packages
run: brew install llvm@16
- name: Build
run: |
mkdir build
cd build
NYXSTONE_LLVM_PREFIX="$(brew --prefix llvm@16)" cmake ..
make
- name: Test
working-directory: build/
run: make test
- name: cli
working-directory: build/
run: |
./nyxstone "mov rax, rbx"
./nyxstone "jmp label" --labels "label=0x1000"

mac-llvm-17:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Packages
run: brew install llvm@17
- name: Build
run: |
mkdir build
cd build
NYXSTONE_LLVM_PREFIX="$(brew --prefix llvm@17)" cmake ..
make
- name: Test
working-directory: build/
run: make test
- name: cli
working-directory: build/
run: |
./nyxstone "mov rax, rbx"
./nyxstone "jmp label" --labels "label=0x1000"

mac-llvm-18:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Packages
run: brew install llvm@18
- name: Build
run: |
mkdir build
cd build
NYXSTONE_LLVM_PREFIX="$(brew --prefix llvm@18)" cmake ..
make
- name: Test
working-directory: build/
run: make test
- name: cli
working-directory: build/
run: |
./nyxstone "mov rax, rbx"
./nyxstone "jmp label" --labels "label=0x1000"
2 changes: 1 addition & 1 deletion .github/workflows/doxygen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Packages
run: sudo apt-get install -y doxygen graphviz
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@ on:
pull_request:
branches: [ "main" ]

env:
NYXSTONE_LLVM_PREFIX: "/usr/lib/llvm-15/"

jobs:
build:
runs-on: ubuntu-latest
env:
working-dir: ./bindings/python
NYXSTONE_LLVM_PREFIX: "/usr/lib/llvm-15/"

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Packages
run: sudo apt-get install llvm-15 llvm-15-dev zlib1g-dev libzstd-dev
run: |
sudo apt-get update
sudo apt-get install zlib1g-dev libzstd-dev llvm-15 llvm-15-dev
- name: Build
run: pip install .
working-directory: ${{ env.working-dir }}
Expand Down
70 changes: 61 additions & 9 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,24 @@ on:

env:
CARGO_TERM_COLOR: always
NYXSTONE_LLVM_PREFIX: "/usr/lib/llvm-15/"

jobs:
linux:
linux-llvm-15:
runs-on: ubuntu-latest
env:
working-dir: ./bindings/rust
NYXSTONE_LLVM_PREFIX: "/usr/lib/llvm-15/"
NYXSTONE_LINK_FFI: "1"
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Packages
run: sudo apt-get install llvm-15 llvm-15-dev zlib1g-dev libzstd-dev
run: |
sudo apt-get update
sudo apt-get install llvm-15 llvm-15-dev zlib1g-dev libzstd-dev
- name: Code quality
run: cargo fmt --all -- --check && cargo clippy -- -D warnings
run: |
cargo fmt --all -- --check
cargo clippy -- -D warnings
working-directory: ${{ env.working-dir }}
- name: Build
run: cargo build
Expand All @@ -29,16 +34,63 @@ jobs:
run: cargo test
working-directory: ${{ env.working-dir }}

mac:
mac-llvm-15:
runs-on: macos-latest
env:
working-dir: ./bindings/rust
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Packages
run: brew install llvm@15
- name: Build
run: RUSTFLAGS="-L$(brew --prefix zstd)/lib" NYXSTONE_LLVM_PREFIX="$(brew --prefix llvm@15)" NYXSTONE_LINK_FFI=1 cargo build
working-directory: ${{ env.working-dir }}
- name: Run tests
run: RUSTFLAGS="-L$(brew --prefix zstd)/lib" RUSTDOCFLAGS="-L$(brew --prefix zstd)/lib" NYXSTONE_LLVM_PREFIX="$(brew --prefix llvm@15)" NYXSTONE_LINK_FFI=1 cargo test
working-directory: ${{ env.working-dir }}

mac-llvm-16:
runs-on: macos-latest
env:
working-dir: ./bindings/rust
steps:
- uses: actions/checkout@v4
- name: Packages
run: brew install llvm@16
- name: Build
run: RUSTFLAGS="-L$(brew --prefix zstd)/lib" NYXSTONE_LLVM_PREFIX="$(brew --prefix llvm@16)" NYXSTONE_LINK_FFI=1 cargo build
working-directory: ${{ env.working-dir }}
- name: Run tests
run: RUSTFLAGS="-L$(brew --prefix zstd)/lib" RUSTDOCFLAGS="-L$(brew --prefix zstd)/lib" NYXSTONE_LLVM_PREFIX="$(brew --prefix llvm@16)" NYXSTONE_LINK_FFI=1 cargo test
working-directory: ${{ env.working-dir }}

mac-llvm-17:
runs-on: macos-latest
env:
working-dir: ./bindings/rust
steps:
- uses: actions/checkout@v4
- name: Packages
run: brew install llvm@17
- name: Build
run: RUSTFLAGS="-L$(brew --prefix zstd)/lib" NYXSTONE_LLVM_PREFIX="$(brew --prefix llvm@17)" NYXSTONE_LINK_FFI=1 cargo build
working-directory: ${{ env.working-dir }}
- name: Run tests
run: RUSTFLAGS="-L$(brew --prefix zstd)/lib" RUSTDOCFLAGS="-L$(brew --prefix zstd)/lib" NYXSTONE_LLVM_PREFIX="$(brew --prefix llvm@17)" NYXSTONE_LINK_FFI=1 cargo test
working-directory: ${{ env.working-dir }}

mac-llvm-18:
runs-on: macos-latest
env:
working-dir: ./bindings/rust
steps:
- uses: actions/checkout@v4
- name: Packages
run: brew install llvm@18
- name: Build
run: RUSTFLAGS="-L$(brew --prefix zstd)/lib" NYXSTONE_LLVM_PREFIX=$(brew --prefix llvm@15) cargo build
run: RUSTFLAGS="-L$(brew --prefix zstd)/lib" NYXSTONE_LLVM_PREFIX="$(brew --prefix llvm@18)" NYXSTONE_LINK_FFI=1 cargo build
working-directory: ${{ env.working-dir }}
- name: Run tests
run: RUSTFLAGS="-L$(brew --prefix zstd)/lib" RUSTDOCFLAGS="-L$(brew --prefix zstd)/lib" NYXSTONE_LLVM_PREFIX=$(brew --prefix llvm@15) cargo test
run: RUSTFLAGS="-L$(brew --prefix zstd)/lib" RUSTDOCFLAGS="-L$(brew --prefix zstd)/lib" NYXSTONE_LLVM_PREFIX="$(brew --prefix llvm@18)" NYXSTONE_LINK_FFI=1 cargo test
working-directory: ${{ env.working-dir }}

4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ option(NYXSTONE_SANITIZERS "Enable sanitizers" OFF)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

if(DEFINED $ENV{NYXSTONE_LLVM_PREFIX})
if(DEFINED ENV{NYXSTONE_LLVM_PREFIX})
# Ignore LLVM_ROOT variables
set(CMAKE_FIND_USE_PACKAGE_ROOT_PATH OFF)
set(CMAKE_PREFIX_PATH $ENV{NYXSTONE_LLVM_PREFIX})
endif()

find_package(LLVM-Wrapper 15 REQUIRED COMPONENTS
find_package(LLVM-Wrapper COMPONENTS
core
mc
AllTargetsCodeGens
Expand Down
38 changes: 25 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Nyxstone is a powerful assembly and disassembly library based on LLVM. It doesn

## Core Features

* Assembles and disassembles code for all architectures supported by LLVM 15, including x86, ARM, MIPS, RISC-V and others.
* Assembles and disassembles code for all architectures supported by the linked LLVM, including x86, ARM, MIPS, RISC-V and others.

* C++ library based on LLVM with Rust and Python bindings.

Expand All @@ -50,38 +50,47 @@ This section provides instructions on how to get started with Nyxstone, covering

### Prerequisites

Before building Nyxstone, ensure clang and LLVM 15 are present as statically linked libraries. Nyxstone looks for `llvm-config` in your system's `$PATH` or the specified environment variable `$NYXSTONE_LLVM_PREFIX/bin`.
Before building Nyxstone, ensure clang and LLVM are present on your system. Nyxstone supports LLVM major versions 15-18.
When building it looks for `llvm-config` in your system's `$PATH` or the specified environment variable `$NYXSTONE_LLVM_PREFIX/bin`.

Installation Options for LLVM 15:
Installation Options for LLVM versions 15-18:

* Debian/Ubuntu
* Ubuntu
```bash
sudo apt install llvm-15 llvm-15-dev
export NYXSTONE_LLVM_PREFIX=/usr/lib/llvm-15/
sudo apt install llvm-${version} llvm-${version}-dev
```

* Debian
LLVM version 15 and 16 are available through debian repositories. Installation is the same as for Ubuntu.
For versions 17 or 18 refer to [https://apt.llvm.org/](https://apt.llvm.org/) for installation instructions.

* Arch
```bash
sudo pacman -S llvm llvm-libs
```

* Homebrew (macOS, Linux and others):
```bash
brew install llvm@15
export NYXSTONE_LLVM_PREFIX=/opt/homebrew/opt/llvm@15
brew install llvm@18
export NYXSTONE_LLVM_PREFIX=/opt/homebrew/opt/llvm@18
```

* From LLVM Source:

_Note_: On Windows you need to run these commands from a Visual Studio 2022 x64 command prompt. Additionally replace `~lib/my-llvm-15` with a different path.
_Note_: On Windows you need to run these commands from a Visual Studio 2022 x64 command prompt. Additionally replace `~lib/my-llvm-18` with a different path.

```bash
# checkout llvm
git clone -b release/15.x --single-branch https://github.com/llvm/llvm-project.git
git clone -b release/18.x --single-branch https://github.com/llvm/llvm-project.git
cd llvm-project

# build LLVM with custom installation directory
cmake -S llvm -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DLLVM_PARALLEL_LINK_JOBS=1
cmake --build build
cmake --install build --prefix ~/lib/my-llvm-15
cmake --install build --prefix ~/lib/my-llvm-18

# export path
export NYXSTONE_LLVM_PREFIX=~/lib/my-llvm-15
export NYXSTONE_LLVM_PREFIX=~/lib/my-llvm-18
```

Also make sure to install any system dependent libraries needed by your LLVM version for static linking. They can be viewed with the command `llvm-config --system-libs`; the list can be empty. On Ubuntu/Debian, you will need the packages `zlib1g-dev` and `zlibstd-dev`.
Expand Down Expand Up @@ -168,7 +177,7 @@ $ ./nyxstone -p "0x1000" -l ".label=0x1238" "jmp .label"

### C++ Library

To use Nyxstone as a C++ library, your C++ code has to be linked against Nyxstone and LLVM 15.
To use Nyxstone as a C++ library, your C++ code has to be linked against Nyxstone and LLVM.

The following cmake example assumes Nyxstone in a subdirectory `nyxstone` in your project:

Expand Down Expand Up @@ -320,3 +329,6 @@ The current contributors are:
* Marc Fyrbiak (emproof)
* Tim Blazytko (emproof)

## Acknowledgements

To ensure that we link LLVM correctly with proper versioning in Rust, we adapted the build.rs from [llvm-sys](https://gitlab.com/taricorp/llvm-sys.rs/).
2 changes: 1 addition & 1 deletion bindings/python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

## Installation

You need to have LLVM 15 (with static library support) installed to build the nyxstone bindings. The `setup.py` searches for LLVM in the `PATH` or in the directory set in the environment variable `NYXSTONE_LLVM_PREFIX`. Specifically, it searches for the binary `$NYXSTONE_LLVM_PREFIX/bin/llvm-config` and uses it to set the required libraries and cpp flags.
You need to have LLVM (with major version in the range 15-18) installed to build the nyxstone bindings. The `setup.py` searches for LLVM in the `PATH` or in the directory set in the environment variable `NYXSTONE_LLVM_PREFIX`. Specifically, it searches for the binary `$NYXSTONE_LLVM_PREFIX/bin/llvm-config` and uses it to set the required libraries and cpp flags.

Running

Expand Down
Loading
Loading