Skip to content

Commit f0d9b56

Browse files
committed
WIP: Fix undefined symbol for allocator functions
1 parent ae84d25 commit f0d9b56

File tree

4 files changed

+53
-25
lines changed

4 files changed

+53
-25
lines changed

build_system/src/test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1031,7 +1031,7 @@ where
10311031
&"always",
10321032
&"--stage",
10331033
&"0",
1034-
&format!("tests/{}", test_type),
1034+
&format!("tests/{}/codegen/virtual-function-elimination.rs", test_type),
10351035
&"--compiletest-rustc-args",
10361036
&rustc_args,
10371037
],

src/allocator.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#[cfg(feature = "master")]
2-
use gccjit::FnAttribute;
2+
use gccjit::{FnAttribute, VarAttribute};
33
use gccjit::{Context, FunctionType, GlobalKind, ToRValue, Type};
44
use rustc_ast::expand::allocator::{
55
ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE,
@@ -9,6 +9,7 @@ use rustc_middle::bug;
99
use rustc_middle::ty::TyCtxt;
1010
use rustc_session::config::OomStrategy;
1111

12+
use crate::base::symbol_visibility_to_gcc;
1213
use crate::GccContext;
1314

1415
pub(crate) unsafe fn codegen(
@@ -70,12 +71,16 @@ pub(crate) unsafe fn codegen(
7071

7172
let name = OomStrategy::SYMBOL.to_string();
7273
let global = context.new_global(None, GlobalKind::Exported, i8, name);
74+
#[cfg(feature = "master")]
75+
global.add_attribute(VarAttribute::Visibility(symbol_visibility_to_gcc(tcx.sess.default_visibility())));
7376
let value = tcx.sess.opts.unstable_opts.oom.should_panic();
7477
let value = context.new_rvalue_from_int(i8, value as i32);
7578
global.global_set_initializer_rvalue(value);
7679

7780
let name = NO_ALLOC_SHIM_IS_UNSTABLE.to_string();
7881
let global = context.new_global(None, GlobalKind::Exported, i8, name);
82+
#[cfg(feature = "master")]
83+
global.add_attribute(VarAttribute::Visibility(symbol_visibility_to_gcc(tcx.sess.default_visibility())));
7984
let value = context.new_rvalue_from_int(i8, 0);
8085
global.global_set_initializer_rvalue(value);
8186
}
@@ -104,16 +109,10 @@ fn create_wrapper_function(
104109
false,
105110
);
106111

112+
println!("{} -> {}: {:?}", from_name, to_name, tcx.sess.default_visibility());
113+
107114
#[cfg(feature = "master")]
108-
match tcx.sess.default_visibility() {
109-
rustc_target::spec::SymbolVisibility::Hidden => {
110-
func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden))
111-
}
112-
rustc_target::spec::SymbolVisibility::Protected => {
113-
func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Protected))
114-
}
115-
rustc_target::spec::SymbolVisibility::Interposable => {}
116-
}
115+
func.add_attribute(FnAttribute::Visibility(symbol_visibility_to_gcc(tcx.sess.default_visibility())));
117116

118117
if tcx.sess.must_emit_unwind_tables() {
119118
// TODO(antoyo): emit unwind tables.

src/back/lto.rs

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use std::fs::{self, File};
2121
use std::path::{Path, PathBuf};
2222
use std::sync::Arc;
2323

24-
use gccjit::{Context, OutputKind};
24+
use gccjit::{Context, FnAttribute, FunctionType, GlobalKind, OutputKind};
2525
use object::read::archive::ArchiveFile;
2626
use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule, ThinShared};
2727
use rustc_codegen_ssa::back::symbol_export;
@@ -50,7 +50,7 @@ pub fn crate_type_allows_lto(crate_type: CrateType) -> bool {
5050

5151
struct LtoData {
5252
// TODO(antoyo): use symbols_below_threshold.
53-
//symbols_below_threshold: Vec<CString>,
53+
symbols_below_threshold: Vec<String>,
5454
upstream_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>,
5555
tmp_path: TempDir,
5656
}
@@ -79,18 +79,21 @@ fn prepare_lto(
7979

8080
let symbol_filter = &|&(ref name, info): &(String, SymbolExportInfo)| {
8181
if info.level.is_below_threshold(export_threshold) || info.used {
82-
Some(CString::new(name.as_str()).unwrap())
82+
Some(name.clone())
8383
} else {
8484
None
8585
}
8686
};
8787
let exported_symbols = cgcx.exported_symbols.as_ref().expect("needs exported symbols for LTO");
88+
//println!("1. {:?}", exported_symbols);
8889
let mut symbols_below_threshold = {
8990
let _timer = cgcx.prof.generic_activity("GCC_lto_generate_symbols_below_threshold");
90-
exported_symbols[&LOCAL_CRATE].iter().filter_map(symbol_filter).collect::<Vec<CString>>()
91+
exported_symbols[&LOCAL_CRATE].iter().filter_map(symbol_filter).collect::<Vec<String>>()
9192
};
9293
info!("{} symbols to preserve in this crate", symbols_below_threshold.len());
9394

95+
//println!("2. {:?}", symbols_below_threshold);
96+
9497
// If we're performing LTO for the entire crate graph, then for each of our
9598
// upstream dependencies, find the corresponding rlib and load the bitcode
9699
// from the archive.
@@ -119,6 +122,7 @@ fn prepare_lto(
119122
for &(cnum, ref path) in cgcx.each_linked_rlib_for_lto.iter() {
120123
let exported_symbols =
121124
cgcx.exported_symbols.as_ref().expect("needs exported symbols for LTO");
125+
//println!("3. {:?}", exported_symbols);
122126
{
123127
let _timer = cgcx.prof.generic_activity("GCC_lto_generate_symbols_below_threshold");
124128
symbols_below_threshold
@@ -155,8 +159,9 @@ fn prepare_lto(
155159
}
156160
}
157161

162+
println!("**** 4. {:?}", symbols_below_threshold);
158163
Ok(LtoData {
159-
//symbols_below_threshold,
164+
symbols_below_threshold,
160165
upstream_modules,
161166
tmp_path,
162167
})
@@ -187,7 +192,7 @@ pub(crate) fn run_fat(
187192
cached_modules,
188193
lto_data.upstream_modules,
189194
lto_data.tmp_path,
190-
//&symbols_below_threshold,
195+
&lto_data.symbols_below_threshold,
191196
)
192197
}
193198

@@ -198,7 +203,7 @@ fn fat_lto(
198203
cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
199204
mut serialized_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>,
200205
tmp_path: TempDir,
201-
//symbols_below_threshold: &[*const libc::c_char],
206+
symbols_below_threshold: &[String],
202207
) -> Result<LtoModuleCodegen<GccCodegenBackend>, FatalError> {
203208
let _timer = cgcx.prof.generic_activity("GCC_fat_lto_build_monolithic_module");
204209
info!("going for a fat lto");
@@ -323,6 +328,14 @@ fn fat_lto(
323328
ptr as *const *const libc::c_char,
324329
symbols_below_threshold.len() as libc::size_t,
325330
);*/
331+
let int_type = module.module_llvm.context.new_type::<i32>();
332+
for symbol in symbols_below_threshold {
333+
println!("*** Keeping symbol: {}", symbol);
334+
module.module_llvm.context.new_global(None, GlobalKind::Imported, int_type, symbol);
335+
}
336+
let void_type = module.module_llvm.context.new_type::<()>();
337+
let func = module.module_llvm.context.new_function(None, FunctionType::Extern, void_type, &[], "__rust_alloc", false);
338+
func.add_attribute(FnAttribute::Used);
326339
save_temp_bitcode(cgcx, &module, "lto.after-restriction");
327340
//}
328341
}
@@ -359,8 +372,6 @@ pub(crate) fn run_thin(
359372
let dcx = cgcx.create_dcx();
360373
let dcx = dcx.handle();
361374
let lto_data = prepare_lto(cgcx, dcx)?;
362-
/*let symbols_below_threshold =
363-
symbols_below_threshold.iter().map(|c| c.as_ptr()).collect::<Vec<_>>();*/
364375
if cgcx.opts.cg.linker_plugin_lto.enabled() {
365376
unreachable!(
366377
"We should never reach this case if the LTO step \
@@ -373,7 +384,8 @@ pub(crate) fn run_thin(
373384
modules,
374385
lto_data.upstream_modules,
375386
lto_data.tmp_path,
376-
cached_modules, /*, &symbols_below_threshold*/
387+
cached_modules,
388+
&lto_data.symbols_below_threshold,
377389
)
378390
}
379391

@@ -424,8 +436,10 @@ fn thin_lto(
424436
serialized_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>,
425437
tmp_path: TempDir,
426438
cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
427-
//symbols_below_threshold: &[*const libc::c_char],
439+
symbols_below_threshold: &[String],
428440
) -> Result<(Vec<LtoModuleCodegen<GccCodegenBackend>>, Vec<WorkProduct>), FatalError> {
441+
println!("********* Thin LTO");
442+
429443
let _timer = cgcx.prof.generic_activity("LLVM_thin_lto_global_analysis");
430444
info!("going for that thin, thin LTO");
431445

@@ -495,6 +509,12 @@ fn thin_lto(
495509
}
496510
}
497511

512+
/*for symbol in symbols_below_threshold {
513+
module.module_llvm.context.new_global(symbol);
514+
}*/
515+
516+
println!("**** Name: {:?}\n******", name);
517+
498518
serialized.push(module);
499519
module_names.push(name);
500520
}

src/base.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,30 @@ use rustc_middle::mir::mono::Visibility;
1515
use rustc_middle::ty::TyCtxt;
1616
use rustc_session::config::DebugInfo;
1717
use rustc_span::Symbol;
18-
use rustc_target::spec::PanicStrategy;
18+
use rustc_target::spec::{PanicStrategy, SymbolVisibility};
1919

2020
use crate::builder::Builder;
2121
use crate::context::CodegenCx;
2222
use crate::{GccContext, LockedTargetInfo, SyncContext, gcc_util, new_context};
2323

2424
#[cfg(feature = "master")]
25-
pub fn visibility_to_gcc(linkage: Visibility) -> gccjit::Visibility {
26-
match linkage {
25+
pub fn visibility_to_gcc(visibility: Visibility) -> gccjit::Visibility {
26+
match visibility {
2727
Visibility::Default => gccjit::Visibility::Default,
2828
Visibility::Hidden => gccjit::Visibility::Hidden,
2929
Visibility::Protected => gccjit::Visibility::Protected,
3030
}
3131
}
3232

33+
#[cfg(feature = "master")]
34+
pub fn symbol_visibility_to_gcc(visibility: SymbolVisibility) -> gccjit::Visibility {
35+
match visibility {
36+
SymbolVisibility::Hidden => gccjit::Visibility::Hidden,
37+
SymbolVisibility::Protected => gccjit::Visibility::Protected,
38+
SymbolVisibility::Interposable => gccjit::Visibility::Default,
39+
}
40+
}
41+
3342
pub fn global_linkage_to_gcc(linkage: Linkage) -> GlobalKind {
3443
match linkage {
3544
Linkage::External => GlobalKind::Imported,

0 commit comments

Comments
 (0)