Skip to content

Commit 747924a

Browse files
committed
Debug global variable not initialized bug
1 parent 02198d8 commit 747924a

File tree

6 files changed

+154
-6
lines changed

6 files changed

+154
-6
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build_system/src/build.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ pub fn build_sysroot(env: &HashMap<String, String>, config: &ConfigInfo) -> Resu
130130
if config.no_default_features {
131131
rustflags.push_str(" -Csymbol-mangling-version=v0");
132132
}
133+
rustflags.push_str(" --print link-args");
133134

134135
let mut args: Vec<&dyn AsRef<OsStr>> = vec![&"cargo", &"build", &"--target", &config.target];
135136
for feature in &config.features {
@@ -156,7 +157,19 @@ pub fn build_sysroot(env: &HashMap<String, String>, config: &ConfigInfo) -> Resu
156157
}
157158

158159
let mut env = env.clone();
160+
/*rustflags.push_str(" -C link-arg=-Wl,--verbose");
161+
rustflags.push_str(" -C link-arg=-Wl,--warn-ifunc-textrel");
162+
rustflags.push_str(" -C link-arg=-Wl,--warn-unresolved-symbols");
163+
rustflags.push_str(" -C link-arg=-Wl,--fatal-warnings");
164+
rustflags.push_str(" -C link-arg=-Wl,--warn-backrefs");
165+
rustflags.push_str(" -C link-arg=-Wl,-znotext");
166+
//rustflags.push_str(" -C link-arg=-Wl,--emit-relocs");
167+
//rustflags.push_str(" -C link-arg=-Wl,--trace-symbol=memchr::arch::x86_64::memchr::memchr_raw::FN");
168+
//rustflags.push_str(" -C link-arg=-Wl,--trace-symbol=_ZN6memchr4arch6x86_646memchr10memchr_raw2FN17haaf621f7b8ca567eE");
169+
//rustflags.push_str(" -C link-arg=-Wl,--print-map");
170+
//rustflags.push_str(" -C link-arg=-Wl,");
159171
env.insert("RUSTFLAGS".to_string(), rustflags);
172+
env.insert("RUSTC_LOG".to_string(), "rustc_codegen_ssa::back::link=info".to_string());*/
160173
run_command_with_output_and_env(&args, Some(&start_dir), Some(&env))?;
161174

162175
// Copy files to sysroot

build_system/src/test.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,24 @@ fn test_libcore(env: &Env, args: &TestArg) -> Result<(), String> {
692692
println!("[TEST] libcore");
693693
let path = get_sysroot_dir().join("sysroot_src/library/core/tests");
694694
let _ = remove_dir_all(path.join("target"));
695-
run_cargo_command(&[&"test"], Some(&path), env, args)?;
695+
let mut env = env.clone();
696+
env.insert("RUSTC_LOG".to_string(), "rustc_codegen_ssa::back::link=info".to_string());
697+
let rustflags =
698+
env.entry("RUSTFLAGS".to_string())
699+
.or_default();
700+
rustflags.push_str(" -C link-arg=-Wl,--verbose");
701+
rustflags.push_str(" -C link-arg=-Wl,--warn-ifunc-textrel");
702+
rustflags.push_str(" -C link-arg=-Wl,--warn-unresolved-symbols");
703+
rustflags.push_str(" -C link-arg=-Wl,--fatal-warnings");
704+
rustflags.push_str(" -C link-arg=-Wl,--warn-backrefs");
705+
rustflags.push_str(" -C link-arg=-Wl,-znotext");
706+
rustflags.push_str(" -C link-arg=-Wl,--emit-relocs");
707+
rustflags.push_str(" -C link-arg=-Wl,--trace-symbol=memchr::arch::x86_64::memchr::memchr_raw::FN");
708+
// FIXME FIXME: seems like RUSTFLAGS is not set here.
709+
//rustflags.push_str(" -C link-arg=-Wl,--trace-symbol=_ZN6memchr4arch6x86_646memchr10memchr_raw2FN17haaf621f7b8ca567eE");
710+
//rustflags.push_str(" -C link-arg=-Wl,--print-map");
711+
//rustflags.push_str(" -Clink-arg=-not-an-arg");
712+
run_cargo_command(&[&"test"], Some(&path), &env, args)?;
696713
Ok(())
697714
}
698715

src/back/write.rs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::{env, fs};
22

3-
use gccjit::OutputKind;
3+
use gccjit::{Context, OutputKind};
44
use rustc_codegen_ssa::back::link::ensure_removed;
55
use rustc_codegen_ssa::back::write::{BitcodeSection, CodegenContext, EmitObj, ModuleConfig};
66
use rustc_codegen_ssa::{CompiledModule, ModuleCodegen};
@@ -34,6 +34,11 @@ pub(crate) unsafe fn codegen(
3434
// TODO: remove this environment variable.
3535
let fat_lto = env::var("EMBED_LTO_BITCODE").as_deref() == Ok("1");
3636

37+
if cgcx.msvc_imps_needed {
38+
println!("************************************************** Imps needed");
39+
create_msvc_imps(cgcx, context);
40+
}
41+
3742
let bc_out = cgcx.output_filenames.temp_path(OutputType::Bitcode, module_name);
3843
let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, module_name);
3944

@@ -196,3 +201,39 @@ pub(crate) fn save_temp_bitcode(
196201
llvm::LLVMWriteBitcodeToFile(llmod, cstr.as_ptr());
197202
}*/
198203
}
204+
205+
fn create_msvc_imps<'gcc>(
206+
cgcx: &CodegenContext<GccCodegenBackend>,
207+
context: &Context<'gcc>,
208+
) {
209+
if !cgcx.msvc_imps_needed {
210+
return;
211+
}
212+
// The x86 ABI seems to require that leading underscores are added to symbol
213+
// names, so we need an extra underscore on x86. There's also a leading
214+
// '\x01' here which disables LLVM's symbol mangling (e.g., no extra
215+
// underscores added in front).
216+
let prefix = if cgcx.target_arch == "x86" { "\x01__imp__" } else { "\x01__imp_" };
217+
218+
/*unsafe {
219+
let ptr_ty = Type::ptr_llcx(llcx);
220+
let globals = base::iter_globals(llmod)
221+
.filter(|&val| {
222+
llvm::get_linkage(val) == llvm::Linkage::ExternalLinkage
223+
&& llvm::LLVMIsDeclaration(val) == 0
224+
})
225+
.map(move |(val, name)| {
226+
let mut imp_name = prefix.as_bytes().to_vec();
227+
imp_name.extend(name);
228+
let imp_name = CString::new(imp_name).unwrap();
229+
(imp_name, val)
230+
})
231+
.collect::<Vec<_>>();
232+
233+
for (imp_name, val) in globals {
234+
let imp = llvm::LLVMAddGlobal(llmod, ptr_ty, imp_name.as_ptr());
235+
llvm::LLVMSetInitializer(imp, val);
236+
llvm::set_linkage(imp, llvm::Linkage::ExternalLinkage);
237+
}
238+
}*/
239+
}

src/common.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
247247
if !matches!(layout.primitive(), Pointer(_)) {
248248
self.const_bitcast(ptr.dereference(None).to_rvalue(), ty)
249249
} else {
250-
self.const_bitcast(ptr, ty)
250+
self.context.new_cast(None, ptr, ty)
251251
}
252252
}
253253
}

src/consts.rs

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#[cfg(feature = "master")]
22
use gccjit::{FnAttribute, VarAttribute, Visibility};
3-
use gccjit::{Function, GlobalKind, LValue, RValue, ToRValue, Type};
3+
use gccjit::{Function, FunctionType, GlobalKind, LValue, RValue, ToRValue, Type};
44
use rustc_codegen_ssa::traits::{
55
BaseTypeCodegenMethods, ConstCodegenMethods, StaticCodegenMethods,
66
};
@@ -92,7 +92,84 @@ impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> {
9292
}
9393
set_global_alignment(self, global, alloc.align);
9494

95-
global.global_set_initializer_rvalue(value);
95+
96+
// TODO: if I still use this code, find the name of the variable in a better way (using
97+
// def_id).
98+
let var_name = format!("{:?}", global);
99+
if var_name.contains("FN") && var_name.contains("memchr") {
100+
println!("Var name: {:?}", var_name);
101+
102+
let ptr_type = value.get_type().make_pointer();
103+
104+
// TODO: remove \x01
105+
//let prefix = if self.cgcx.target_arch == "x86" { "\x01__imp__" } else { "\x01__imp_" };
106+
let prefix = "__imp__";
107+
let mut imp_name = prefix.to_string();
108+
imp_name.push_str(&var_name);
109+
110+
// FIXME: if I understand correctly the code in cg_llvm, the kind should be Imported.
111+
/*let imp_global = self.context.new_global(None, GlobalKind::Exported, ptr_type, &imp_name);
112+
imp_global.global_set_initializer_rvalue(global.get_address(None));*/
113+
114+
/*
115+
/*let context = gccjit::Context::default();
116+
let global = context.new_global(None, GlobalKind::Exported, val_llty, &var_name);
117+
global.global_set_initializer_rvalue(value);
118+
context.compile_to_file(gccjit::OutputKind::ObjectFile, format!("{}.o", var_name));*/
119+
120+
let void_type = self.context.new_type::<()>();
121+
let fn_ptr_type = self.context.new_function_pointer_type(None, void_type, &[], false);
122+
let my_name = format!("MY_NAME${}", var_name);
123+
//let global = self.context.new_global(None, GlobalKind::Exported, fn_ptr_type, my_name);
124+
//global.add_attribute(VarAttribute::Used);
125+
println!("{:?} = {:?}", var_name, value);
126+
127+
let my_func_name = format!("MY_FUNC${}", var_name);
128+
let func = self.context.new_function(None, FunctionType::Exported, void_type, &[], &my_func_name, false);
129+
func.add_attribute(FnAttribute::Used);
130+
let block = func.new_block("start");
131+
block.end_with_void_return(None);
132+
133+
//let func = self.context.new_function(None, FunctionType::Extern, void_type, &[], "puts", false);
134+
let value = func.get_address(None);
135+
//let global = self.context.new_global(None, GlobalKind::Exported, value.get_type(), my_name);
136+
//let value = self.context.new_bitcast(None, func.get_address(None), fn_ptr_type);
137+
/*
138+
* TODO: Check if the hard-coded function has the correct name.
139+
* ===> It seems so.
140+
* TODO: try with a function we know exists.
141+
* ===> It doesn't seem to help.
142+
* TODO: check if the .o contains the value (before linking into the .so).
143+
* ===> It seems the object file doesn't contain the value either.
144+
* ======> This is because there are relocations.
145+
* TODO: check if fold in GCC erases the value.
146+
* ===> It doesn't seem so.
147+
*
148+
* TODO TODO: try again this code with using the used attribute.
149+
*/
150+
151+
/*let var_type = global.to_rvalue().get_type();
152+
let struct_type = var_type.is_struct().unwrap();
153+
/*let field1_type = struct_type.get_field(0).get_type();
154+
let field2_type = struct_type.get_field(1).get_type();*/
155+
156+
let field1 = value;
157+
let field2 = self.context.new_rvalue_zero(self.int_type);
158+
159+
let struct_val = self.context.new_struct_constructor(None, var_type, None, &[field1, field2]);
160+
let value = struct_val;*/
161+
162+
//let value = self.context.new_bitcast(None, func.get_address(None), val_llty);
163+
164+
//let value = self.context.new_rvalue_from_int(self.usize_type, 10293);
165+
//let value = self.context.new_cast(None, value, fn_ptr_type); // WORKS
166+
//let value = self.context.new_bitcast(None, value, fn_ptr_type); // Also WORKS
167+
let value = self.context.new_bitcast(None, value, val_llty);*/
168+
global.global_set_initializer_rvalue(value);
169+
}
170+
else {
171+
global.global_set_initializer_rvalue(value);
172+
}
96173

97174
// As an optimization, all shared statics which do not have interior
98175
// mutability are placed into read-only memory.

0 commit comments

Comments
 (0)