Skip to content
This repository has been archived by the owner on Mar 20, 2024. It is now read-only.

Commit

Permalink
Add Dwarf test (#390)
Browse files Browse the repository at this point in the history
  • Loading branch information
jcivlin authored Oct 25, 2023
1 parent 84574fc commit d237c03
Show file tree
Hide file tree
Showing 11 changed files with 453 additions and 79 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ target-out-docker
**/move-mv-llvm-compiler/**/cli-tests/**/*.ll.actual
**/move-mv-llvm-compiler/**/cli-tests/basic-coin-build/absolute_path_results/*
**/move-mv-llvm-compiler/**/cli-tests/basic-coin-build/relative_path_results/*
**/move-mv-llvm-compiler/**/dwarf-tests/basic-coin-build/stored_results/*
**/move-mv-llvm-compiler/**/rbpf-tests/**/*.mv
**/move-mv-llvm-compiler/**/rbpf-tests/**/*.o
**/move-mv-llvm-compiler/**/rbpf-tests/**/*.so
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

158 changes: 81 additions & 77 deletions language/solana/move-to-solana/src/stackless/dwarf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,17 @@
use llvm_sys::{
core::*,
debuginfo::{
LLVMDIBuilderCreateCompileUnit, LLVMDIBuilderCreateModule, LLVMDIBuilderFinalize,
LLVMDWARFEmissionKind, LLVMDWARFSourceLanguage::LLVMDWARFSourceLanguageRust,
LLVMCreateDIBuilder, LLVMDIBuilderCreateCompileUnit, LLVMDIBuilderCreateFile,
LLVMDIBuilderCreateModule, LLVMDIBuilderFinalize, LLVMDWARFEmissionKind,
LLVMDWARFSourceLanguage::LLVMDWARFSourceLanguageRust,
},
prelude::*,
};

use std::{
ffi::{CStr, CString},
ptr,
};
use std::{env, ffi::CStr, ptr};

use crate::stackless::Module;

pub use llvm_sys::{
debuginfo::{LLVMCreateDIBuilder, LLVMDIBuilderCreateFile, LLVMDisposeDIBuilder},
LLVMAttributeFunctionIndex, LLVMAttributeIndex, LLVMAttributeReturnIndex, LLVMIntPredicate,
LLVMLinkage,
LLVMLinkage::LLVMInternalLinkage,
LLVMTypeKind::LLVMIntegerTypeKind,
};

#[derive(Clone, Debug)]
pub struct DIBuilderCore {
module_di: LLVMModuleRef,
Expand All @@ -52,41 +42,14 @@ pub struct DIBuilderCore {
#[derive(Clone, Debug)]
pub struct DIBuilder(Option<DIBuilderCore>);

/// Convert &str to a CString
fn str_to_c_params(s: &str) -> (*const ::libc::c_char, ::libc::size_t) {
(s.as_ptr() as *const libc::c_char, s.len())
}

/// Convert the Rust String to a CString (null-terminated C-style string)
fn string_to_c_params(s: String) -> (*const ::libc::c_char, ::libc::size_t) {
let cstr = match CString::new(s) {
Ok(cstr) => cstr,
Err(_) => CString::new("").expect("Failed to create an empty CString"),
};
(cstr.as_ptr(), cstr.as_bytes().len())
}
fn path_to_c_params(
file_path: &str,
) -> (
*const ::libc::c_char,
::libc::size_t,
*const ::libc::c_char,
::libc::size_t,
) {
let path = std::path::Path::new(&file_path);
let directory = path
.parent()
.expect("Failed to get directory")
.to_str()
.expect("Failed to convert to string");
let (dir_ptr, dir_len) = str_to_c_params(directory);
let file = path
.file_name()
.expect("Failed to get file name")
.to_str()
.expect("Failed to convert to string");
let (filename_ptr, filename_len) = str_to_c_params(file);
(filename_ptr, filename_len, dir_ptr, dir_len)
macro_rules! to_cstring {
($x:expr) => {{
let cstr = match std::ffi::CString::new($x) {
Ok(cstr) => cstr,
Err(_) => std::ffi::CString::new("unknown").expect("Failed to create CString"),
};
cstr
}};
}

pub fn from_raw_slice_to_string(raw_ptr: *const i8, raw_len: ::libc::size_t) -> String {
Expand All @@ -96,44 +59,88 @@ pub fn from_raw_slice_to_string(raw_ptr: *const i8, raw_len: ::libc::size_t) ->
String::from_utf8_lossy(byte_slice).to_string()
}

fn relative_to_absolute(relative_path: &str) -> std::io::Result<String> {
let current_dir = env::current_dir()?;
let absolute_path = current_dir
.join(relative_path)
.canonicalize()
.expect("Cannot canonicanize path");

Ok(absolute_path.to_string_lossy().to_string())
}

impl DIBuilder {
pub fn new(module: &mut Module, source: &str, debug: bool) -> DIBuilder {
use log::debug;
if debug {
let module_ref_name = module.get_module_id();
let module_ref = module.as_mut();

// create module
let module_name = format!("{}.dbg_info", module_ref_name);
let (mod_nm_ptr, _mod_nm_len) = str_to_c_params(module_name.as_str());
let module_di = unsafe { LLVMModuleCreateWithName(mod_nm_ptr) };
// create new module
let module_name = module_ref_name + ".dbg_info";
let cstr = to_cstring!(module_name.as_str());
let (mut mod_nm_ptr, mut mod_nm_len) = (cstr.as_ptr(), cstr.as_bytes().len());
let module_di =
unsafe { LLVMModuleCreateWithName(mod_nm_ptr as *const ::libc::c_char) };

// check dbg module name
mod_nm_ptr = unsafe { LLVMGetModuleIdentifier(module_di, &mut mod_nm_len) };
let module_di_name = &from_raw_slice_to_string(mod_nm_ptr, mod_nm_len);
debug!(target: "dwarf", "Created dbg module {:#?}", module_di_name);

// set source to created module
let (src_ptr, src_len) = str_to_c_params(source);
unsafe { LLVMSetSourceFileName(module_di, src_ptr, src_len) };
// check the name
let source = relative_to_absolute(source).expect("Must be the legal path");
let cstr = to_cstring!(source.as_str());
unsafe { LLVMSetSourceFileName(module_di, cstr.as_ptr(), cstr.as_bytes().len()) };

// check the source name
let mut src_len: ::libc::size_t = 0;
let src_ptr = unsafe { LLVMGetSourceFileName(module_di, &mut src_len) };
let src0 = from_raw_slice_to_string(src_ptr, src_len);
debug!(target: "dwarf", "Module {:#?} has source {:#?}", module_name, src0);
let module_src = &from_raw_slice_to_string(src_ptr, src_len);
debug!(target: "dwarf", "Module {:#?} has source {:#?}", module_name, module_src);

// create builder
let builder_ref = unsafe { LLVMCreateDIBuilder(module_di) };

// create builder file
let (mod_nm_ptr, mod_nm_len, dir_ptr, dir_len) = path_to_c_params(source);
// create file
let path = std::path::Path::new(&source);
let directory = path
.parent()
.expect("Failed to get directory")
.to_str()
.expect("Failed to convert to string");
let cstr = to_cstring!(directory);
let (dir_ptr, dir_len) = (cstr.as_ptr(), cstr.as_bytes().len());

let file = path
.file_name()
.expect("Failed to get file name")
.to_str()
.expect("Failed to convert to string");
let cstr = to_cstring!(file);
let (filename_ptr, filename_len) = (cstr.as_ptr(), cstr.as_bytes().len());
let (mod_nm_ptr, mod_nm_len, dir_ptr, dir_len) =
(filename_ptr, filename_len, dir_ptr, dir_len);

let builder_file = unsafe {
LLVMDIBuilderCreateFile(builder_ref, mod_nm_ptr, mod_nm_len, dir_ptr, dir_len)
};

// create compile unit
let producer = "move-mv-llvm-compiler".to_string();
let (producer_ptr, producer_len) = str_to_c_params(producer.as_str());
let cstr = to_cstring!(producer);
let (producer_ptr, producer_len) = (cstr.as_ptr(), cstr.as_bytes().len());

let flags = "".to_string();
let (flags_ptr, flags_len) = str_to_c_params(flags.as_str());
let cstr = to_cstring!(flags);
let (flags_ptr, flags_len) = (cstr.as_ptr(), cstr.as_bytes().len());

let slash = "/".to_string();
let (slash_ptr, slash_len) = str_to_c_params(slash.as_str());
let cstr = to_cstring!(slash);
let (slash_ptr, slash_len) = (cstr.as_ptr(), cstr.as_bytes().len());

let none = String::new();
let (none_ptr, none_len) = str_to_c_params(none.as_str());
let cstr = to_cstring!(none);
let (none_ptr, none_len) = (cstr.as_ptr(), cstr.as_bytes().len());

let compiled_unit = unsafe {
LLVMDIBuilderCreateCompileUnit(
Expand All @@ -159,19 +166,15 @@ impl DIBuilder {
)
};

// check the name
let mut src_len: ::libc::size_t = 0;
let src_ptr = unsafe { LLVMGetSourceFileName(module_di, &mut src_len) };
let src1 = from_raw_slice_to_string(src_ptr, src_len);
debug!(target: "dwarf", "Self-check: module {:#?} has source {:#?}", module_name, src1);

// create compiled unit
// create di module
let parent_scope = compiled_unit;
let name = module_name;
let (name_ptr, name_len) = str_to_c_params(name.as_str());
let (config_macros_ptr, config_macros_len) = str_to_c_params(none.as_str());
let (include_path_ptr, include_path_len) = str_to_c_params(none.as_str());
let (api_notes_file_ptr, api_notes_file_len) = str_to_c_params(none.as_str());
let cstr = to_cstring!(name);
let (name_ptr, name_len) = (cstr.as_ptr(), cstr.as_bytes().len());

let (config_macros_ptr, config_macros_len) = (none_ptr, none_len);
let (include_path_ptr, include_path_len) = (none_ptr, none_len);
let (api_notes_file_ptr, api_notes_file_len) = (none_ptr, none_len);
let compiled_module = unsafe {
LLVMDIBuilderCreateModule(
builder_ref,
Expand Down Expand Up @@ -235,7 +238,8 @@ impl DIBuilder {
pub fn print_module_to_file(&self, file_path: String) {
if let Some(x) = &self.0 {
let mut err_string = ptr::null_mut();
let (filename_ptr, _filename_ptr_len) = string_to_c_params(file_path);
let cstr = to_cstring!(file_path);
let (filename_ptr, _filename_ptr_len) = (cstr.as_ptr(), cstr.as_bytes().len());
unsafe {
let res = LLVMPrintModuleToFile(x.module_di, filename_ptr, &mut err_string);
if res != 0 {
Expand Down
5 changes: 5 additions & 0 deletions language/tools/move-mv-llvm-compiler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ once_cell = "1.10"
parking_lot = "0.11"
toml = "0.5.8"
regex = "1.1.9"
rand = "0.8"
move-bytecode-verifier = { path = "../../move-bytecode-verifier" }
move-bytecode-source-map = { path = "../../move-ir-compiler/move-bytecode-source-map" }
move-command-line-common = { path = "../../move-command-line-common" }
Expand Down Expand Up @@ -87,3 +88,7 @@ harness = false
[[test]]
name = "cli-tests"
harness = false

[[test]]
name = "dwarf-tests"
harness = false
18 changes: 18 additions & 0 deletions language/tools/move-mv-llvm-compiler/docs/Development.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,24 @@ Install [CodeLLDB plugin](https://marketplace.visualstudio.com/items?itemName=va

- lldb with gdbserver

To debug in VS Code add this config:
{
"type": "lldb",
"request": "launch",
"name": "dwarf-tests direct call",
"env": {
"RUST_BACKTRACE": "all",
"RUST_LOG": "debug",
"CARGO_MANIFEST_DIR": "something like /home/sol/work/git/move/language/tools/move-mv-llvm-compiler",
"LLVM_SYS_150_PREFIX": "something like /home/sol/work/git/platform-tools/out/rust/build/x86_64-unknown-linux-gnu/llvm",
"PLATFORM_TOOLS_ROOT": "something like /home/sol/work/git/platform-tools/out/deploy"
},
"program": "something like /home/sol/work/git/move/target/debug/deps/dwarf_tests-XXXXXXXXXXXXXXXX",
"args": ["--test"],
"cwd": "something like /home/sol/work/git/move/language/tools/move-mv-llvm-compiler",
"stopOnEntry": false
}

### Protip

----
Expand Down
Loading

0 comments on commit d237c03

Please sign in to comment.