| 3298 | } |
| 3299 | |
| 3300 | pub fn llvm_assemble( |
| 3301 | code: &str, |
| 3302 | dialect: LlvmServicesDialect, |
| 3303 | arch_triple: &str, |
| 3304 | code_model: LlvmServicesCodeModel, |
| 3305 | reloc_mode: LlvmServicesRelocMode, |
| 3306 | ) -> Result<Vec<u8>, String> { |
| 3307 | let code = CString::new(code).map_err(|_| "Invalid encoding in code string".to_string())?; |
| 3308 | let arch_triple = CString::new(arch_triple) |
| 3309 | .map_err(|_| "Invalid encoding in architecture triple string".to_string())?; |
| 3310 | let mut out_bytes: *mut c_char = std::ptr::null_mut(); |
| 3311 | let mut out_bytes_len: c_int = 0; |
| 3312 | let mut err_bytes: *mut c_char = std::ptr::null_mut(); |
| 3313 | let mut err_len: c_int = 0; |
| 3314 | |
| 3315 | unsafe { |
| 3316 | BNLlvmServicesInit(); |
| 3317 | } |
| 3318 | |
| 3319 | let result = unsafe { |
| 3320 | BNLlvmServicesAssemble( |
| 3321 | code.as_ptr(), |
| 3322 | dialect as i32, |
| 3323 | arch_triple.as_ptr(), |
| 3324 | code_model as i32, |
| 3325 | reloc_mode as i32, |
| 3326 | &mut out_bytes as *mut *mut c_char, |
| 3327 | &mut out_bytes_len as *mut c_int, |
| 3328 | &mut err_bytes as *mut *mut c_char, |
| 3329 | &mut err_len as *mut c_int, |
| 3330 | ) |
| 3331 | }; |
| 3332 | |
| 3333 | let out = if out_bytes_len == 0 { |
| 3334 | Vec::new() |
| 3335 | } else { |
| 3336 | unsafe { |
| 3337 | std::slice::from_raw_parts( |
| 3338 | out_bytes as *const c_char as *const u8, |
| 3339 | out_bytes_len as usize, |
| 3340 | ) |
| 3341 | } |
| 3342 | .to_vec() |
| 3343 | }; |
| 3344 | |
| 3345 | let errors = if err_len == 0 { |
| 3346 | "".into() |
| 3347 | } else { |
| 3348 | String::from_utf8_lossy(unsafe { |
| 3349 | std::slice::from_raw_parts(err_bytes as *const c_char as *const u8, err_len as usize) |
| 3350 | }) |
| 3351 | .into_owned() |
| 3352 | }; |
| 3353 | |
| 3354 | unsafe { |
| 3355 | BNLlvmServicesAssembleFree(out_bytes, err_bytes); |
| 3356 | } |
| 3357 | |