about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAntoni Boucher <bouanto@zoho.com>2024-12-14 08:51:44 -0500
committerAntoni Boucher <bouanto@zoho.com>2024-12-14 08:51:44 -0500
commitf0d9b56e7287416b4c0a537c9a5ff50e48051ca0 (patch)
tree046b963a07fd912c5d2ec3e6036cc88c4cc7762d /src
parentae84d258c94e1db9d77fb447f2c7ba2559b67d5d (diff)
downloadrust-f0d9b56e7287416b4c0a537c9a5ff50e48051ca0.tar.gz
rust-f0d9b56e7287416b4c0a537c9a5ff50e48051ca0.zip
WIP: Fix undefined symbol for allocator functions
Diffstat (limited to 'src')
-rw-r--r--src/allocator.rs19
-rw-r--r--src/back/lto.rs42
-rw-r--r--src/base.rs15
3 files changed, 52 insertions, 24 deletions
diff --git a/src/allocator.rs b/src/allocator.rs
index f13a75648ae..6df56693ce1 100644
--- a/src/allocator.rs
+++ b/src/allocator.rs
@@ -1,5 +1,5 @@
 #[cfg(feature = "master")]
-use gccjit::FnAttribute;
+use gccjit::{FnAttribute, VarAttribute};
 use gccjit::{Context, FunctionType, GlobalKind, ToRValue, Type};
 use rustc_ast::expand::allocator::{
     ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE,
@@ -9,6 +9,7 @@ use rustc_middle::bug;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::config::OomStrategy;
 
+use crate::base::symbol_visibility_to_gcc;
 use crate::GccContext;
 
 pub(crate) unsafe fn codegen(
@@ -70,12 +71,16 @@ pub(crate) unsafe fn codegen(
 
     let name = OomStrategy::SYMBOL.to_string();
     let global = context.new_global(None, GlobalKind::Exported, i8, name);
+    #[cfg(feature = "master")]
+    global.add_attribute(VarAttribute::Visibility(symbol_visibility_to_gcc(tcx.sess.default_visibility())));
     let value = tcx.sess.opts.unstable_opts.oom.should_panic();
     let value = context.new_rvalue_from_int(i8, value as i32);
     global.global_set_initializer_rvalue(value);
 
     let name = NO_ALLOC_SHIM_IS_UNSTABLE.to_string();
     let global = context.new_global(None, GlobalKind::Exported, i8, name);
+    #[cfg(feature = "master")]
+    global.add_attribute(VarAttribute::Visibility(symbol_visibility_to_gcc(tcx.sess.default_visibility())));
     let value = context.new_rvalue_from_int(i8, 0);
     global.global_set_initializer_rvalue(value);
 }
@@ -104,16 +109,10 @@ fn create_wrapper_function(
         false,
     );
 
+    println!("{} -> {}: {:?}", from_name, to_name, tcx.sess.default_visibility());
+
     #[cfg(feature = "master")]
-    match tcx.sess.default_visibility() {
-        rustc_target::spec::SymbolVisibility::Hidden => {
-            func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden))
-        }
-        rustc_target::spec::SymbolVisibility::Protected => {
-            func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Protected))
-        }
-        rustc_target::spec::SymbolVisibility::Interposable => {}
-    }
+    func.add_attribute(FnAttribute::Visibility(symbol_visibility_to_gcc(tcx.sess.default_visibility())));
 
     if tcx.sess.must_emit_unwind_tables() {
         // TODO(antoyo): emit unwind tables.
diff --git a/src/back/lto.rs b/src/back/lto.rs
index 11c984774b7..b0b89bf588b 100644
--- a/src/back/lto.rs
+++ b/src/back/lto.rs
@@ -21,7 +21,7 @@ use std::fs::{self, File};
 use std::path::{Path, PathBuf};
 use std::sync::Arc;
 
-use gccjit::{Context, OutputKind};
+use gccjit::{Context, FnAttribute, FunctionType, GlobalKind, OutputKind};
 use object::read::archive::ArchiveFile;
 use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule, ThinShared};
 use rustc_codegen_ssa::back::symbol_export;
@@ -50,7 +50,7 @@ pub fn crate_type_allows_lto(crate_type: CrateType) -> bool {
 
 struct LtoData {
     // TODO(antoyo): use symbols_below_threshold.
-    //symbols_below_threshold: Vec<CString>,
+    symbols_below_threshold: Vec<String>,
     upstream_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>,
     tmp_path: TempDir,
 }
@@ -79,18 +79,21 @@ fn prepare_lto(
 
     let symbol_filter = &|&(ref name, info): &(String, SymbolExportInfo)| {
         if info.level.is_below_threshold(export_threshold) || info.used {
-            Some(CString::new(name.as_str()).unwrap())
+            Some(name.clone())
         } else {
             None
         }
     };
     let exported_symbols = cgcx.exported_symbols.as_ref().expect("needs exported symbols for LTO");
+    //println!("1. {:?}", exported_symbols);
     let mut symbols_below_threshold = {
         let _timer = cgcx.prof.generic_activity("GCC_lto_generate_symbols_below_threshold");
-        exported_symbols[&LOCAL_CRATE].iter().filter_map(symbol_filter).collect::<Vec<CString>>()
+        exported_symbols[&LOCAL_CRATE].iter().filter_map(symbol_filter).collect::<Vec<String>>()
     };
     info!("{} symbols to preserve in this crate", symbols_below_threshold.len());
 
+    //println!("2. {:?}", symbols_below_threshold);
+
     // If we're performing LTO for the entire crate graph, then for each of our
     // upstream dependencies, find the corresponding rlib and load the bitcode
     // from the archive.
@@ -119,6 +122,7 @@ fn prepare_lto(
         for &(cnum, ref path) in cgcx.each_linked_rlib_for_lto.iter() {
             let exported_symbols =
                 cgcx.exported_symbols.as_ref().expect("needs exported symbols for LTO");
+            //println!("3. {:?}", exported_symbols);
             {
                 let _timer = cgcx.prof.generic_activity("GCC_lto_generate_symbols_below_threshold");
                 symbols_below_threshold
@@ -155,8 +159,9 @@ fn prepare_lto(
         }
     }
 
+    println!("**** 4. {:?}", symbols_below_threshold);
     Ok(LtoData {
-        //symbols_below_threshold,
+        symbols_below_threshold,
         upstream_modules,
         tmp_path,
     })
@@ -187,7 +192,7 @@ pub(crate) fn run_fat(
         cached_modules,
         lto_data.upstream_modules,
         lto_data.tmp_path,
-        //&symbols_below_threshold,
+        &lto_data.symbols_below_threshold,
     )
 }
 
@@ -198,7 +203,7 @@ fn fat_lto(
     cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
     mut serialized_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>,
     tmp_path: TempDir,
-    //symbols_below_threshold: &[*const libc::c_char],
+    symbols_below_threshold: &[String],
 ) -> Result<LtoModuleCodegen<GccCodegenBackend>, FatalError> {
     let _timer = cgcx.prof.generic_activity("GCC_fat_lto_build_monolithic_module");
     info!("going for a fat lto");
@@ -323,6 +328,14 @@ fn fat_lto(
             ptr as *const *const libc::c_char,
             symbols_below_threshold.len() as libc::size_t,
         );*/
+        let int_type = module.module_llvm.context.new_type::<i32>();
+        for symbol in symbols_below_threshold {
+            println!("*** Keeping symbol: {}", symbol);
+            module.module_llvm.context.new_global(None, GlobalKind::Imported, int_type, symbol);
+        }
+        let void_type = module.module_llvm.context.new_type::<()>();
+        let func = module.module_llvm.context.new_function(None, FunctionType::Extern, void_type, &[], "__rust_alloc", false);
+        func.add_attribute(FnAttribute::Used);
         save_temp_bitcode(cgcx, &module, "lto.after-restriction");
         //}
     }
@@ -359,8 +372,6 @@ pub(crate) fn run_thin(
     let dcx = cgcx.create_dcx();
     let dcx = dcx.handle();
     let lto_data = prepare_lto(cgcx, dcx)?;
-    /*let symbols_below_threshold =
-    symbols_below_threshold.iter().map(|c| c.as_ptr()).collect::<Vec<_>>();*/
     if cgcx.opts.cg.linker_plugin_lto.enabled() {
         unreachable!(
             "We should never reach this case if the LTO step \
@@ -373,7 +384,8 @@ pub(crate) fn run_thin(
         modules,
         lto_data.upstream_modules,
         lto_data.tmp_path,
-        cached_modules, /*, &symbols_below_threshold*/
+        cached_modules,
+        &lto_data.symbols_below_threshold,
     )
 }
 
@@ -424,8 +436,10 @@ fn thin_lto(
     serialized_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>,
     tmp_path: TempDir,
     cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
-    //symbols_below_threshold: &[*const libc::c_char],
+    symbols_below_threshold: &[String],
 ) -> Result<(Vec<LtoModuleCodegen<GccCodegenBackend>>, Vec<WorkProduct>), FatalError> {
+    println!("********* Thin LTO");
+
     let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_global_analysis");
     info!("going for that thin, thin LTO");
 
@@ -495,6 +509,12 @@ fn thin_lto(
             }
         }
 
+        /*for symbol in symbols_below_threshold {
+            module.module_llvm.context.new_global(symbol);
+        }*/
+
+        println!("**** Name: {:?}\n******", name);
+
         serialized.push(module);
         module_names.push(name);
     }
diff --git a/src/base.rs b/src/base.rs
index 508cb74ff64..76699da3275 100644
--- a/src/base.rs
+++ b/src/base.rs
@@ -15,21 +15,30 @@ use rustc_middle::mir::mono::Visibility;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::config::DebugInfo;
 use rustc_span::Symbol;
-use rustc_target::spec::PanicStrategy;
+use rustc_target::spec::{PanicStrategy, SymbolVisibility};
 
 use crate::builder::Builder;
 use crate::context::CodegenCx;
 use crate::{GccContext, LockedTargetInfo, SyncContext, gcc_util, new_context};
 
 #[cfg(feature = "master")]
-pub fn visibility_to_gcc(linkage: Visibility) -> gccjit::Visibility {
-    match linkage {
+pub fn visibility_to_gcc(visibility: Visibility) -> gccjit::Visibility {
+    match visibility {
         Visibility::Default => gccjit::Visibility::Default,
         Visibility::Hidden => gccjit::Visibility::Hidden,
         Visibility::Protected => gccjit::Visibility::Protected,
     }
 }
 
+#[cfg(feature = "master")]
+pub fn symbol_visibility_to_gcc(visibility: SymbolVisibility) -> gccjit::Visibility {
+    match visibility {
+        SymbolVisibility::Hidden => gccjit::Visibility::Hidden,
+        SymbolVisibility::Protected => gccjit::Visibility::Protected,
+        SymbolVisibility::Interposable => gccjit::Visibility::Default,
+    }
+}
+
 pub fn global_linkage_to_gcc(linkage: Linkage) -> GlobalKind {
     match linkage {
         Linkage::External => GlobalKind::Imported,