Skip to content

feat: add llvm 20 support #28

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

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
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
6 changes: 3 additions & 3 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ jobs:
runs-on: ubuntu-latest
env:
LLVM_INSTALL_PATH: ~/llvm
LLVM_VERSION: "18"
LLVM_VERSION_IN_FEATURE: "18-1"
LLVM_LIB_NAME: "libLLVM.so.18.1"
LLVM_VERSION: "19"
LLVM_VERSION_IN_FEATURE: "19-1"
LLVM_LIB_NAME: "libLLVM.so.19.1"
steps:
- name: Checkout Repo
uses: actions/checkout@v2
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ jobs:
strategy:
matrix:
llvm-version:
- ["10", "10-0", "v10.0.1-rust-1.46/llvm-10.0.1-rust-1.46-linux-x86_64.tar.gz", "libLLVM-10.so"]
- ["11", "11-0", "v11.0.1-rust-1.51/llvm-lld-11.0.1-rust-1.51-linux-x86_64.tar.gz", "libLLVM-11.so"]
- ["12", "12-0", "v12.0.1-rust-1.55/llvm-lld-12.0.1-rust-1.55-linux-x86_64.tar.gz", "libLLVM-12.so"]
- ["13", "13-0", "v13.0.0-rust-1.59/llvm-lld-13.0.0-rust-1.59-linux-x86_64.tar.gz", "libLLVM-13.so"]
Expand All @@ -24,6 +23,8 @@ jobs:
- ["16", "16-0", "v16.0.2-rust-1.71/llvm-lld-16.0.2-rust-1.71-linux-x86_64.tar.gz", "libLLVM-16.so"]
- ["17", "17-0", "v17.0.6-rust-1.75/llvm-lld-17.0.6-rust-1.75-linux-x86_64.tar.gz", "libLLVM-17.so"]
- ["18", "18-1", "v18.1.2-rust-1.78/llvm-lld-18.1.2-rust-1.78-linux-x86_64.tar.gz", "libLLVM.so.18.1"]
- ["19", "19-1", "v19.1.5-rust-1.84/llvm-lld-19.1.5-rust-1.84-linux-x86_64.tar.gz", "libLLVM.so.19.1"]
- ["20", "20-1", "v20.1.1-rust-1.87/llvm-lld-20.1.1-rust-1.87-linux-x86_64.tar.gz", "libLLVM.so.20.1"]
steps:
- name: Checkout Repo
uses: actions/checkout@v2
Expand Down Expand Up @@ -114,6 +115,8 @@ jobs:
- ["16", "16-0", "1.71", "v16.0.2-rust-1.71/llvm-lld-16.0.2-rust-1.71-linux-x86_64.tar.gz", "libLLVM-16.so"]
- ["17", "17-0", "1.75", "v17.0.6-rust-1.75/llvm-lld-17.0.6-rust-1.75-linux-x86_64.tar.gz", "libLLVM-17.so"]
- ["18", "18-1", "1.78", "v18.1.2-rust-1.78/llvm-lld-18.1.2-rust-1.78-linux-x86_64.tar.gz", "libLLVM.so.18.1"]
- ["19", "19-1", "1.84", "v19.1.5-rust-1.84/llvm-lld-19.1.5-rust-1.84-linux-x86_64.tar.gz", "libLLVM.so.19.1"]
- ["20", "20-1", "1.87", "v20.1.1-rust-1.87/llvm-lld-20.1.1-rust-1.87-linux-x86_64.tar.gz", "libLLVM.so.20.1"]
steps:
- name: Checkout Repo
uses: actions/checkout@v2
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ jobs:
- ["16", "16-0", "v16.0.2-rust-1.71/llvm-lld-16.0.2-rust-1.71-macos-x86_64.tar.gz", "macos-13"]
- ["17", "17-0", "v17.0.6-rust-1.75/llvm-lld-17.0.6-rust-1.75-macos-x86_64.tar.gz", "macos-13"]
- ["18", "18-1", "v18.1.2-rust-1.78/llvm-lld-18.1.2-rust-1.78-macos-arm64.tar.gz", "macos-latest"]
- ["19", "19-1", "v19.1.5-rust-1.84/llvm-lld-19.1.5-rust-1.84-macos-arm64.tar.gz", "macos-latest"]
- ["20", "20-1", "v20.1.1-rust-1.87/llvm-lld-20.1.1-rust-1.87-macos-arm64.tar.gz", "macos-latest"]
steps:
- name: Checkout Repo
uses: actions/checkout@v2
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ jobs:
runs-on: ubuntu-latest
env:
LLVM_INSTALL_PATH: ~/llvm
LLVM_VERSION: "18"
LLVM_VERSION_IN_FEATURE: "18-1"
LLVM_LIB_NAME: "libLLVM.so.18.1"
LLVM_VERSION: "19"
LLVM_VERSION_IN_FEATURE: "19-1"
LLVM_LIB_NAME: "libLLVM.so.19.1"
steps:
- name: Checkout the repository
uses: actions/checkout@v4
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ jobs:
- ["16", "16-0", "v16.0.2-rust-1.71/llvm-lld-16.0.2-rust-1.71-windows-x86_64.7z"]
- ["17", "17-0", "v17.0.6-rust-1.75/llvm-lld-17.0.6-rust-1.75-windows-x86_64.7z"]
- ["18", "18-1", "v18.1.2-rust-1.78/llvm-lld-18.1.2-rust-1.78-windows-x86_64.7z"]
- ["19", "19-1", "v19.1.5-rust-1.84/llvm-lld-19.1.5-rust-1.84-windows-x86_64.7z"]
- ["20", "20-1", "v20.1.1-rust-1.87/llvm-lld-20.1.1-rust-1.87-windows-x86_64.7z"]
steps:
- name: Checkout Repo
uses: actions/checkout@v2
Expand Down Expand Up @@ -112,6 +114,8 @@ jobs:
- ["16", "16-0", "1.71", "v16.0.2-rust-1.71/llvm-lld-16.0.2-rust-1.71-windows-x86_64.7z"]
- ["17", "17-0", "1.75", "v17.0.6-rust-1.75/llvm-lld-17.0.6-rust-1.75-windows-x86_64.7z"]
- ["18", "18-1", "1.78", "v18.1.2-rust-1.78/llvm-lld-18.1.2-rust-1.78-windows-x86_64.7z"]
- ["19", "19-1", "1.84", "v19.1.5-rust-1.84/llvm-lld-19.1.5-rust-1.84-windows-x86_64.7z"]
- ["20", "20-1", "1.87", "v20.1.1-rust-1.87/llvm-lld-20.1.1-rust-1.87-windows-x86_64.7z"]
steps:
- name: Checkout Repo
uses: actions/checkout@v2
Expand Down
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[workspace]
resolver = "2"
members = ["llvm-plugin", "llvm-plugin-macros"]

[patch.crates-io]
inkwell = { git = "https://github.com/stevefan1999-personal/inkwell" }
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ When importing this crate in your `Cargo.toml`, you will need to specify the LLV

```toml
[dependencies]
llvm-plugin = { version = "0.6", features = ["llvm18-1"] }
llvm-plugin = { version = "0.6", features = ["llvm20-1"] }
```

Supported versions: LLVM 10-18 mapping to a cargo feature flag `llvmX-Y` where `X` and `Y` are the LLVM major and minor versions.
Supported versions: LLVM 11-20 mapping to a cargo feature flag `llvmX-Y` where `X` and `Y` are the LLVM major and minor versions.

## Getting Started

Expand Down
10 changes: 5 additions & 5 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ achieved with simple LLVM passes.
<summary><em>Execute the example</em></summary>

```shell
$ cargo b --example hello-world --features llvm10-0
$ cargo b --example hello-world --features llvm20-1
$ opt --load-pass-plugin=target/debug/examples/libhello_world.so --passes=hello-world in.ll -S -o out.ll
```

Expand All @@ -21,7 +21,7 @@ achieved with simple LLVM passes.
<summary><em>Execute the example</em></summary>

```shell
$ cargo b --example opcode-counter --features llvm10-0
$ cargo b --example opcode-counter --features llvm20-1
$ opt --load-pass-plugin=target/debug/examples/libopcode_counter.so --passes=opcode-counter-printer in.ll -S -o out.ll
```

Expand All @@ -33,7 +33,7 @@ achieved with simple LLVM passes.
<summary><em>Execute the example</em></summary>

```shell
$ cargo b --example inject-printf --features llvm10-0
$ cargo b --example inject-printf --features llvm20-1
$ opt --load-pass-plugin=target/debug/examples/libinject_printf.so --passes=inject-func-call in.ll -S -o out.ll
```

Expand All @@ -45,7 +45,7 @@ achieved with simple LLVM passes.
<summary><em>Execute the example</em></summary>

```shell
$ cargo b --example static-call-counter --features llvm10-0
$ cargo b --example static-call-counter --features llvm20-1
$ opt --load-pass-plugin=target/debug/examples/libstatic_call_counter.so --passes=static-cc-printer in.ll -S -o out.ll
```

Expand All @@ -57,7 +57,7 @@ achieved with simple LLVM passes.
<summary><em>Execute the example</em></summary>

```shell
$ cargo b --example string-obf --features llvm10-0
$ cargo b --example string-obf --features llvm20-1
$ opt --load-pass-plugin=target/debug/examples/libstring_obf.so --passes=string-obfuscator-pass in.ll -S -o out.ll
```

Expand Down
16 changes: 14 additions & 2 deletions examples/strings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,12 @@ fn encode_global_strings<'a>(module: &mut Module<'a>) -> Vec<GlobalString<'a>> {
_ => None,
})
.filter(|(_, _, arr)| {
// needs to be called before `get_string_constant`, otherwise it may crash
// needs to be called before `as_const_string`, otherwise it may crash
arr.is_const_string()
})
.filter_map(|(global, stru, arr)| {
// we ignore non-UTF8 strings, since they are probably not human-readable
let s = arr.get_string_constant().and_then(|s| s.to_str().ok())?;
let s = arr.as_const_string().and_then(|s| str::from_utf8(s).ok())?;
let encoded_str = s.bytes().map(|c| c + 1).collect::<Vec<_>>();
Some((global, stru, encoded_str))
})
Expand Down Expand Up @@ -156,6 +156,8 @@ fn create_decode_fn<'a>(module: &mut Module<'a>) -> FunctionValue<'a> {
feature = "llvm16-0",
feature = "llvm17-0",
feature = "llvm18-1",
feature = "llvm19-1",
feature = "llvm20-1",
)))]
let var10 = unsafe {
builder.build_gep(
Expand All @@ -170,6 +172,8 @@ fn create_decode_fn<'a>(module: &mut Module<'a>) -> FunctionValue<'a> {
feature = "llvm16-0",
feature = "llvm17-0",
feature = "llvm18-1",
feature = "llvm19-1",
feature = "llvm20-1",
))]
let var10 = unsafe {
builder.build_gep(
Expand All @@ -185,13 +189,17 @@ fn create_decode_fn<'a>(module: &mut Module<'a>) -> FunctionValue<'a> {
feature = "llvm16-0",
feature = "llvm17-0",
feature = "llvm18-1",
feature = "llvm19-1",
feature = "llvm20-1",
)))]
let var11 = builder.build_load(phi1.as_basic_value().into_pointer_value(), "");
#[cfg(any(
feature = "llvm15-0",
feature = "llvm16-0",
feature = "llvm17-0",
feature = "llvm18-1",
feature = "llvm19-1",
feature = "llvm20-1",
))]
let var11 = builder
.build_load(cx.i8_type(), phi1.as_basic_value().into_pointer_value(), "")
Expand Down Expand Up @@ -254,6 +262,8 @@ fn create_decode_stub<'a>(
feature = "llvm16-0",
feature = "llvm17-0",
feature = "llvm18-1",
feature = "llvm19-1",
feature = "llvm20-1",
)))]
let s = builder
.build_struct_gep(gs.as_pointer_value(), id, "")
Expand All @@ -263,6 +273,8 @@ fn create_decode_stub<'a>(
feature = "llvm16-0",
feature = "llvm17-0",
feature = "llvm18-1",
feature = "llvm19-1",
feature = "llvm20-1",
))]
let s = {
let i8_ty_ptr = cx.i8_type().ptr_type(AddressSpace::default());
Expand Down
9 changes: 5 additions & 4 deletions llvm-plugin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ readme = "README.md"
repository = "https://github.com/jamesmth/llvm-plugin-rs"

[package.metadata.docs.rs]
features = ["llvm15-0"] # any version >10 will do
features = ["llvm15-0"]
rustdoc-args = ["--cfg", "docsrs"]

[features]
Expand All @@ -24,15 +24,16 @@ macros = ["llvm-plugin-macros"]
win-link-opt = []
win-link-lld = []

llvm10-0 = ["inkwell/llvm10-0-no-llvm-linking"]
llvm11-0 = ["inkwell/llvm11-0-no-llvm-linking"]
llvm12-0 = ["inkwell/llvm12-0-no-llvm-linking"]
llvm13-0 = ["inkwell/llvm13-0-no-llvm-linking"]
llvm14-0 = ["inkwell/llvm14-0-no-llvm-linking"]
llvm15-0 = ["inkwell/llvm15-0-no-llvm-linking"]
llvm16-0 = ["inkwell/llvm16-0-no-llvm-linking"]
llvm17-0 = ["inkwell/llvm17-0-no-llvm-linking"]
llvm18-1 = ["inkwell/llvm18-0-no-llvm-linking"]
llvm18-1 = ["inkwell/llvm18-1-no-llvm-linking"]
llvm19-1 = ["inkwell/llvm19-1-no-llvm-linking"]
llvm20-1 = ["inkwell/llvm20-1-no-llvm-linking"]

target-x86 = ["inkwell/target-x86"]
target-arm = ["inkwell/target-arm"]
Expand All @@ -53,7 +54,7 @@ target-riscv = ["inkwell/target-riscv"]
target-all = ["inkwell/target-all"]

[dependencies]
inkwell = "0.5"
inkwell = "0.6"
llvm-plugin-macros = { path = "../llvm-plugin-macros", version = "0.2", optional = true }

[build-dependencies]
Expand Down
8 changes: 5 additions & 3 deletions llvm-plugin/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,7 @@ mod llvm_sys {
}

fn llvm_version_from_features() -> (u32, u32) {
if cfg!(feature = "llvm10-0") {
(10, 0)
} else if cfg!(feature = "llvm11-0") {
if cfg!(feature = "llvm11-0") {
(11, 0)
} else if cfg!(feature = "llvm12-0") {
(12, 0)
Expand All @@ -217,6 +215,10 @@ mod llvm_sys {
(17, 0)
} else if cfg!(feature = "llvm18-1") {
(18, 1)
} else if cfg!(feature = "llvm19-1") {
(19, 1)
} else if cfg!(feature = "llvm20-1") {
(20, 1)
} else {
panic!("Missing llvm* feature")
}
Expand Down
6 changes: 5 additions & 1 deletion llvm-plugin/cpp/.clang-tidy
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
# https://github.com/llvm/llvm-project/blob/main/.clang-tidy
Checks: '-*,clang-diagnostic-*,llvm-*,misc-*,-misc-unused-parameters,-misc-non-private-member-variables-in-classes,-misc-no-recursion,readability-identifier-naming'
Checks: '-*,clang-diagnostic-*,llvm-*,misc-*,-misc-const-correctness,-misc-unused-parameters,-misc-non-private-member-variables-in-classes,-misc-no-recursion,-misc-use-anonymous-namespace,readability-identifier-naming,-misc-include-cleaner'
CheckOptions:
- key: readability-identifier-naming.ClassCase
value: CamelCase
- key: readability-identifier-naming.EnumCase
value: CamelCase
- key: readability-identifier-naming.FunctionCase
value: camelBack
# Exclude from scanning as this is an exported symbol used for fuzzing
# throughout the code base.
- key: readability-identifier-naming.FunctionIgnoredRegexp
value: "LLVMFuzzerTestOneInput"
- key: readability-identifier-naming.MemberCase
value: CamelCase
- key: readability-identifier-naming.ParameterCase
Expand Down
35 changes: 15 additions & 20 deletions llvm-plugin/cpp/ffi.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,6 @@ enum class OptimizationLevel { kO0, kO1, kO2, kO3, kOs, kOz };

namespace {
auto getFFIOptimizationLevel(LlvmOptLevel Opt) -> OptimizationLevel {
#if defined(LLVM_VERSION_MAJOR) && (LLVM_VERSION_MAJOR == 10)
if (Opt == LlvmOptLevel::O0) {
return OptimizationLevel::kO0;
}
if (Opt == LlvmOptLevel::O1) {
return OptimizationLevel::kO1;
}
if (Opt == LlvmOptLevel::O2) {
return OptimizationLevel::kO2;
}
if (Opt == LlvmOptLevel::O3) {
return OptimizationLevel::kO3;
}
if (Opt == LlvmOptLevel::Os) {
return OptimizationLevel::kOs;
}
#else
// Starting from LLVM-11, llvm::OptimizationLevel::Ox is no longer
// an enum but a global static. Using these global statics on Windows
// would not compile, because an LLVM plugin links to opt.exe. The
Expand All @@ -64,7 +47,6 @@ auto getFFIOptimizationLevel(LlvmOptLevel Opt) -> OptimizationLevel {
if (Opt.getSpeedupLevel() == 2 && Opt.getSizeLevel() == 2) {
return OptimizationLevel::kOz;
}
#endif
return OptimizationLevel::kOz;
}
} // namespace
Expand Down Expand Up @@ -127,7 +109,6 @@ auto passBuilderAddFullLinkTimeOptimizationEarlyEPCallback(
}
#endif

#if defined(LLVM_VERSION_MAJOR) && (LLVM_VERSION_MAJOR >= 11)
auto passBuilderAddOptimizerLastEPCallback(
llvm::PassBuilder &Builder, const void *DataPtr,
void (*Deleter)(const void *),
Expand All @@ -137,12 +118,16 @@ auto passBuilderAddOptimizerLastEPCallback(

Builder.registerOptimizerLastEPCallback(
[Data = std::move(Data), Callback](llvm::ModulePassManager &PassManager,
#if (LLVM_VERSION_MAJOR >= 20)
LlvmOptLevel Opt,
llvm::ThinOrFullLTOPhase) {
#else
LlvmOptLevel Opt) {
#endif
const auto OptFFI = getFFIOptimizationLevel(Opt);
Callback(Data.get(), PassManager, OptFFI);
});
}
#endif

#if defined(LLVM_VERSION_MAJOR) && (LLVM_VERSION_MAJOR >= 15)
auto passBuilderAddOptimizerEarlyEPCallback(
Expand All @@ -154,7 +139,12 @@ auto passBuilderAddOptimizerEarlyEPCallback(

Builder.registerOptimizerEarlyEPCallback(
[Data = std::move(Data), Callback](llvm::ModulePassManager &PassManager,
#if (LLVM_VERSION_MAJOR >= 20)
LlvmOptLevel Opt,
llvm::ThinOrFullLTOPhase) {
#else
LlvmOptLevel Opt) {
#endif
const auto OptFFI = getFFIOptimizationLevel(Opt);
Callback(Data.get(), PassManager, OptFFI);
});
Expand All @@ -171,7 +161,12 @@ auto passBuilderAddPipelineEarlySimplificationEPCallback(

Builder.registerPipelineEarlySimplificationEPCallback(
[Data = std::move(Data), Callback](llvm::ModulePassManager &PassManager,
#if (LLVM_VERSION_MAJOR >= 20)
LlvmOptLevel Opt,
llvm::ThinOrFullLTOPhase) {
#else
LlvmOptLevel Opt) {
#endif
const auto OptFFI = getFFIOptimizationLevel(Opt);
Callback(Data.get(), PassManager, OptFFI);
});
Expand Down
Loading