@@ -3,6 +3,7 @@ use rustc_codegen_ssa::traits::BaseTypeMethods;
3
3
use rustc_middle:: ty:: Ty ;
4
4
use rustc_span:: Symbol ;
5
5
use rustc_target:: abi:: call:: FnAbi ;
6
+ use rustc_symbol_mangling:: symbol_name_for_instance_in_crate;
6
7
7
8
use crate :: abi:: FnAbiGccExt ;
8
9
use crate :: context:: { CodegenCx , unit_name} ;
@@ -53,19 +54,17 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
53
54
54
55
pub fn declare_global ( & self , name : & str , ty : Type < ' gcc > , is_tls : bool , link_section : Option < Symbol > ) -> RValue < ' gcc > {
55
56
//debug!("declare_global(name={:?})", name);
56
- let mut initializer = None ;
57
- // NOTE: hack to initialize ARGC_INIT_ARRAY before libc tries to call the function it
58
- // points to.
59
57
// FIXME: correctly support global variable initialization.
60
- if name == ARGV_INIT_ARRAY {
61
- let return_type = self . type_void ( ) ;
62
- let params = [
63
- self . context . new_parameter ( None , self . int_type , "argc" ) ,
64
- self . context . new_parameter ( None , self . u8_type . make_pointer ( ) . make_pointer ( ) , "argv" ) ,
65
- self . context . new_parameter ( None , self . u8_type . make_pointer ( ) . make_pointer ( ) , "envp" ) ,
66
- ] ;
67
- let function = self . context . new_function ( None , FunctionType :: Extern , return_type, & params, ARGV_INIT_WRAPPER , false ) ;
68
- initializer = Some ( function. get_address ( None ) ) ;
58
+ if name. starts_with ( ARGV_INIT_ARRAY ) {
59
+ // NOTE: hack to avoid having to update the names in mangled_std_symbols: we save the
60
+ // name of the variable now to actually declare it later.
61
+ * self . init_argv_var . borrow_mut ( ) = name. to_string ( ) ;
62
+
63
+ let global = self . context . new_global ( None , GlobalKind :: Imported , ty, name) ;
64
+ if let Some ( link_section) = link_section {
65
+ global. set_link_section ( & link_section. as_str ( ) ) ;
66
+ }
67
+ return global. get_address ( None ) ;
69
68
}
70
69
let global = self . context . new_global ( None , GlobalKind :: Exported , ty, name) ;
71
70
if is_tls {
@@ -74,9 +73,6 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
74
73
if let Some ( link_section) = link_section {
75
74
global. set_link_section ( & link_section. as_str ( ) ) ;
76
75
}
77
- if let Some ( initializer) = initializer {
78
- global. global_set_initializer_value ( initializer) ;
79
- }
80
76
let global = global. get_address ( None ) ;
81
77
self . globals . borrow_mut ( ) . insert ( name. to_string ( ) , global) ;
82
78
// NOTE: global seems to only be global in a module. So save the name instead of the value
@@ -100,6 +96,38 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
100
96
}
101
97
102
98
pub fn declare_fn ( & self , name : & str , fn_abi : & FnAbi < ' tcx , Ty < ' tcx > > ) -> RValue < ' gcc > {
99
+ // NOTE: hack to avoid having to update the names in mangled_std_symbols: we found the name
100
+ // of the variable earlier, so we declare it now.
101
+ // Since we don't correctly support initializers yet, we initialize this variable manually
102
+ // for now.
103
+ if name. starts_with ( ARGV_INIT_WRAPPER ) && !self . argv_initialized . get ( ) {
104
+ let global_name = & * self . init_argv_var . borrow ( ) ;
105
+ let return_type = self . type_void ( ) ;
106
+ let params = [
107
+ self . context . new_parameter ( None , self . int_type , "argc" ) ,
108
+ self . context . new_parameter ( None , self . u8_type . make_pointer ( ) . make_pointer ( ) , "argv" ) ,
109
+ self . context . new_parameter ( None , self . u8_type . make_pointer ( ) . make_pointer ( ) , "envp" ) ,
110
+ ] ;
111
+ let function = self . context . new_function ( None , FunctionType :: Extern , return_type, & params, name, false ) ;
112
+ let initializer = function. get_address ( None ) ;
113
+
114
+ let param_types = [
115
+ self . int_type ,
116
+ self . u8_type . make_pointer ( ) . make_pointer ( ) ,
117
+ self . u8_type . make_pointer ( ) . make_pointer ( ) ,
118
+ ] ;
119
+ let ty = self . context . new_function_pointer_type ( None , return_type, & param_types, false ) ;
120
+
121
+ let global = self . context . new_global ( None , GlobalKind :: Exported , ty, global_name) ;
122
+ global. set_link_section ( ".init_array.00099" ) ;
123
+ global. global_set_initializer_value ( initializer) ;
124
+ let global = global. get_address ( None ) ;
125
+ self . globals . borrow_mut ( ) . insert ( global_name. to_string ( ) , global) ;
126
+ // NOTE: global seems to only be global in a module. So save the name instead of the value
127
+ // to import it later.
128
+ self . global_names . borrow_mut ( ) . insert ( global, global_name. to_string ( ) ) ;
129
+ self . argv_initialized . set ( true ) ;
130
+ }
103
131
//debug!("declare_rust_fn(name={:?}, fn_abi={:?})", name, fn_abi);
104
132
let ( return_type, params, variadic) = fn_abi. gcc_type ( self ) ;
105
133
let func = declare_raw_fn ( self , name, ( ) /*fn_abi.llvm_cconv()*/ , return_type, & params, variadic) ;
0 commit comments