From f1e97beb160c2e325af66e25412adeb7d6989da5 Mon Sep 17 00:00:00 2001 From: Agent Smith Date: Wed, 28 Aug 2024 17:01:26 +0800 Subject: [PATCH] fix: cannot lgcc on linux --- pl_linker/src/linker.rs | 32 ++++++++++++++++++++++++++++++-- src/ast/builder/llvmbuilder.rs | 25 +++++++++++++++++++++++++ vm/build.rs | 9 +++------ vm/dso_handle.c | 6 ++++++ vm/src/lib.rs | 7 +++++++ 5 files changed, 71 insertions(+), 8 deletions(-) create mode 100644 vm/dso_handle.c diff --git a/pl_linker/src/linker.rs b/pl_linker/src/linker.rs index 36551329..6654c368 100644 --- a/pl_linker/src/linker.rs +++ b/pl_linker/src/linker.rs @@ -100,6 +100,22 @@ fn get_linux_lib_paths() -> Vec { paths } +// fn get_libgcc_path() -> Result { +// let base_path = "/usr/lib/gcc/x86_64-linux-gnu"; +// let entries = std::fs::read_dir(base_path).map_err(|e| format!("Failed to read directory {}: {}", base_path, e))?; + +// for entry in entries { +// let entry = entry.map_err(|e| format!("Failed to read directory entry: {}", e))?; +// if entry.path().is_dir() { +// let version = entry.file_name().into_string().map_err(|e| format!("Failed to convert OsString to String: {:?}", e))?; +// return Ok(format!("{}/{}", base_path, version)); +// } +// } + +// Err("No valid gcc version directory found".to_string()) +// } + + impl Linker for LdLinker { fn add_object(&mut self, path: &Path) -> Result<(), LinkerError> { let path_str = path @@ -115,9 +131,21 @@ impl Linker for LdLinker { paths.iter().for_each(|lib| { self.push_args(&format!("-L{}", lib.as_str())); }); + // // Add the path to the libgcc library + // match get_libgcc_path() { + // Ok(libgcc_dir) => { + // self.push_args(&format!("-L{}", libgcc_dir)); + // } + // Err(e) => { + // return Err(LinkerError::LinkError(format!( + // "Failed to get libgcc path: {}", + // e + // ))); + // } + // } // libs and link args [ - "-pie", + "-no-pie", "-zrelro", "--hash-style=gnu", "--build-id", @@ -133,7 +161,7 @@ impl Linker for LdLinker { "-lunwind", "--no-as-needed", "-ldl", - "-lgcc", + // "-lgcc", // "/usr/lib/gcc/x86_64-linux-gnu//crtendS.o", "/lib/x86_64-linux-gnu/crtn.o", ] diff --git a/src/ast/builder/llvmbuilder.rs b/src/ast/builder/llvmbuilder.rs index 4c745cf0..d74819ab 100644 --- a/src/ast/builder/llvmbuilder.rs +++ b/src/ast/builder/llvmbuilder.rs @@ -2280,6 +2280,31 @@ impl<'a, 'ctx> IRBuilder<'a, 'ctx> for LLVMBuilder<'a, 'ctx> { self.builder.position_at(v.get_parent().unwrap(), &v); } fn finalize_debug(&self) { + #[cfg(target_os = "linux")] + { + // add __dso_handle defination + let dso = self.module.add_global( + self.context.i8_type().array_type(0), + Some(AddressSpace::from(0)), + "__dso_handle", + ); + dso.set_initializer(&self.context.i8_type().array_type(0).const_zero()); + dso.set_linkage(Linkage::WeakAny); + let dso = self.module.add_global( + self.context.i8_type().array_type(0), + Some(AddressSpace::from(0)), + "_dso_handle", + ); + dso.set_initializer(&self.context.i8_type().array_type(0).const_zero()); + dso.set_linkage(Linkage::WeakAny); + let dso = self.module.add_global( + self.context.i8_type().array_type(0), + Some(AddressSpace::from(0)), + "dso_handle", + ); + dso.set_initializer(&self.context.i8_type().array_type(0).const_zero()); + dso.set_linkage(Linkage::WeakAny); + } self.dibuilder.finalize(); } fn print_to_file(&self, file: &Path) -> Result<(), String> { diff --git a/vm/build.rs b/vm/build.rs index 2c088385..86ca6ff0 100644 --- a/vm/build.rs +++ b/vm/build.rs @@ -45,8 +45,6 @@ use std::process::Command; // format!("{}.{}.0", &LIBUV_VERSION[..dotidx], next_minor_version) // } - - fn build>(source_path: &P) { let src_path = source_path.as_ref().join("src"); let unix_path = src_path.join("unix"); @@ -298,9 +296,7 @@ fn main() { let mut uv_src = PathBuf::from(out_dir); uv_src.push(LIBUV_DIR); if !uv_src.exists() { - run("git", |cmd| { - cmd.arg("clone").arg(LIBUV_REPO).arg(&uv_src) - }); + run("git", |cmd| cmd.arg("clone").arg(LIBUV_REPO).arg(&uv_src)); // run("git", |cmd| { // cmd.arg("clone") @@ -316,7 +312,8 @@ fn main() { } build(&uv_src); - + #[cfg(target_os = "linux")] + cc::Build::new().file("dso_handle.c").compile("dso_handle"); // println!("cargo:rustc-link-lib=static:+whole-archive=uv"); } diff --git a/vm/dso_handle.c b/vm/dso_handle.c new file mode 100644 index 00000000..2b6eed73 --- /dev/null +++ b/vm/dso_handle.c @@ -0,0 +1,6 @@ +// dso_handle.c +#include + +const void *const __dso_handle __attribute__((weak)) = &__dso_handle; +const void *const _dso_handle __attribute__((weak)) = &__dso_handle; +const void *const dso_handle __attribute__((weak)) = &__dso_handle; \ No newline at end of file diff --git a/vm/src/lib.rs b/vm/src/lib.rs index f3857f53..4aa6e3af 100644 --- a/vm/src/lib.rs +++ b/vm/src/lib.rs @@ -344,3 +344,10 @@ fn millitime() -> i64 { #[cfg(all(windows, feature = "jitdylib"))] mod compiler_rt; + +// (.data._rust_extern_with_linkage___dso_handle+0x0): undefined reference to `__dso_handle' +// I want to define it manually +#[cfg(target_os = "linux")] +extern "C" { + pub static __dso_handle: *const u8; +}