aya_rustc_llvm_proxy/
init.rs1use super::SHARED_LIB;
2use llvm_sys::prelude::LLVMBool;
3
4use std::io::{BufRead, BufReader, Result};
5use std::process::Command;
6
7const POSSIBLE_BACKENDS: &[&str] = &[
8 "AArch64", "AMDGPU", "ARM", "BPF", "Hexagon", "Lanai", "Mips", "MSP430", "NVPTX", "PowerPC",
9 "Sparc", "SystemZ", "X86", "XCore",
10];
11
12fn get_native_arch() -> Result<String> {
13 let output = Command::new("rustc").args(["--print", "cfg"]).output()?;
14 let buf = BufReader::new(output.stdout.as_slice());
15 for line in buf.lines() {
16 let line = line?;
17 if !line.starts_with("target_arch") {
18 continue;
19 }
20 return Ok(line.split('"').nth(1).unwrap().into());
22 }
23 unreachable!("`rustc --print cfg` result is wrong");
24}
25
26fn arch2backend(arch: &str) -> String {
27 match arch {
28 "aarch64" => "AArch64".into(),
29 "arm" => "ARM".into(),
30 "mips" | "mips64" => "Mips".into(),
31 "powerpc" | "powerpc64" => "PowerPC".into(),
32 "sparc" | "sparc64" => "Sparc".into(),
33 "x86" | "x86_64" => "X86".into(),
34 _ => panic!("Unknown backend: {}", arch),
35 }
36}
37
38fn get_native_backend() -> String {
39 let arch = get_native_arch().expect("Fail to get native arch");
40 arch2backend(&arch)
41}
42
43unsafe fn init_all(postfix: &str) {
44 for backend in POSSIBLE_BACKENDS {
45 let name = format!("LLVMInitialize{}{}", backend, postfix);
46 if let Ok(entrypoint) = SHARED_LIB.get::<unsafe extern "C" fn()>(name.as_bytes()) {
47 entrypoint();
48 }
49 }
50}
51
52#[no_mangle]
53pub unsafe extern "C" fn LLVM_InitializeAllTargetInfos() {
54 init_all("TargetInfo");
55}
56#[no_mangle]
57pub unsafe extern "C" fn LLVM_InitializeAllTargets() {
58 init_all("Target");
59}
60#[no_mangle]
61pub unsafe extern "C" fn LLVM_InitializeAllTargetMCs() {
62 init_all("TargetMC");
63}
64#[no_mangle]
65pub unsafe extern "C" fn LLVM_InitializeAllAsmParsers() {
66 init_all("AsmParser");
67}
68#[no_mangle]
69pub unsafe extern "C" fn LLVM_InitializeAllAsmPrinters() {
70 init_all("AsmPrinter");
71}
72
73unsafe fn init_native(postfix: &str) -> LLVMBool {
74 let backend = get_native_backend();
75 let name = format!("LLVMInitialize{}{}", backend, postfix);
76 if let Ok(entrypoint) = SHARED_LIB.get::<unsafe extern "C" fn()>(name.as_bytes()) {
77 entrypoint();
78 0
79 } else {
80 1
81 }
82}
83
84#[no_mangle]
85pub unsafe extern "C" fn LLVM_InitializeNativeTarget() -> LLVMBool {
86 init_native("Target")
87}
88#[no_mangle]
89pub unsafe extern "C" fn LLVM_InitializeNativeAsmParser() -> LLVMBool {
90 init_native("AsmParser")
91}
92#[no_mangle]
93pub unsafe extern "C" fn LLVM_InitializeNativeAsmPrinter() -> LLVMBool {
94 init_native("AsmPrinter")
95}
96#[no_mangle]
97pub unsafe extern "C" fn LLVM_InitializeNativeDisassembler() -> LLVMBool {
98 init_native("Disassembler")
99}