2个版本

0.2.1 2022年1月5日
0.2.0 2022年1月5日

#1162编程语言

MIT 协议

205KB
6K SLoC

Vicis

CI codecov

Vicis 允许您在纯Rust中操作LLVM IR(无需LLVM!)。

请随意创建问题和拉取请求!

要求

  • 测试中使用 llvm (== 12.0.0)
    • 您不再需要它了!

示例

  • 读取 *.ll 文件
cargo run --example parse FILE.ll
  • 解释 *.ll 文件
cargo run --example interpreter FILE.ll
  • 迭代指令
fn main() {
    let asm = r#"
      source_filename = "asm"
      target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"     
      target triple = "x86_64-pc-linux-gnu"  

      ; Function Attrs: noinline nounwind optnone uwtable
      define dso_local i32 @main() #0 {
        %1 = alloca i32, align 4
        store i32 42, i32* %1
        ret i32 0
      }

      attributes #0 = { noinline nounwind optnone uwtable }
    "#;

    // Parse the assembly and get a module
    let module = module::parse_assembly(asm).unwrap();

    run_on_module(&module);
}

fn run_on_module(module: &Module) {
    for (_, function) in module.functions() {
        run_on_function(function);
    }
}

fn run_on_function(func: &Function) {
    for block_id in func.layout.block_iter() {
        for inst_id in func.layout.inst_iter(block_id) {
            let inst = func.data.inst_ref(inst_id);
            // Do something with `inst` ....
        }
    }
}
  • 将LLVM IR编译成机器代码
// LLVM Assembly
let asm = r#"
  source_filename = "asm"
  target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"     
  target triple = "x86_64-pc-linux-gnu"  

  ; Function Attrs: noinline nounwind optnone uwtable
  define dso_local i32 @main() #0 {
    %a = alloca i32, align 4
    store i32 2, i32* %a
    %b = load i32, i32* %a
    %c = add i32 %b, 1 ; 3
    %d = add i32 %b, 2 ; 4
    %e = add i32 %c, %d ; 7
    ret i32 %e
  }

  attributes #0 = { noinline nounwind optnone uwtable }
"#;

// Parse the assembly and get a module
let module = module::parse_assembly(asm).unwrap();

// Compile the module for x86 and get a machine module
let mach_module = compile_module(X86_64, module);

// Display the machine module as assembly
assert_eq!(
  format!("{}", mach_module),
  "  .text
  .intel_syntax noprefix
  .globl main
main:
.LBL0:
  push rbp
  mov rbp, rsp
  sub rsp, 16
  mov dword ptr [rbp-4], 2
  mov eax, dword ptr [rbp-4]
  mov ecx, eax
  add ecx, 1
  add eax, 2
  add ecx, eax
  mov eax, ecx
  add rsp, 16
  pop rbp
  ret 
"
);

依赖项

~2.5MB
~48K SLoC