소스 검색

Invoke constructors and destructors

Huge thanks to @xtibor for both discovering that this was still an issue, and also providing information with how to fix it
jD91mZM2 6 년 전
부모
커밋
1f3154b45c
2개의 변경된 파일27개의 추가작업 그리고 0개의 파일을 삭제
  1. 10 0
      src/header/stdlib/mod.rs
  2. 17 0
      src/start.rs

+ 10 - 0
src/header/stdlib/mod.rs

@@ -220,6 +220,9 @@ pub extern "C" fn erand(xsubi: [c_ushort; 3]) -> c_double {
 #[no_mangle]
 pub unsafe extern "C" fn exit(status: c_int) {
     extern "C" {
+        static __fini_array_start: extern "C" fn();
+        static __fini_array_end: extern "C" fn();
+
         fn _fini();
     }
 
@@ -229,6 +232,13 @@ pub unsafe extern "C" fn exit(status: c_int) {
         }
     }
 
+    // Look for the neighbor functions in memory until the end
+    let mut f = &__fini_array_end as *const _;
+    while f > &__fini_array_start {
+        f = f.offset(-1);
+        (*f)();
+    }
+
     _fini();
 
     Sys::exit(status);

+ 17 - 0
src/start.rs

@@ -30,6 +30,11 @@ impl Stack {
 #[no_mangle]
 pub unsafe extern "C" fn relibc_start(sp: &'static Stack) -> ! {
     extern "C" {
+        static __preinit_array_start: extern "C" fn();
+        static __preinit_array_end:   extern "C" fn();
+        static __init_array_start:    extern "C" fn();
+        static __init_array_end:      extern "C" fn();
+
         fn _init();
         fn main(argc: isize, argv: *const *const c_char, envp: *const *const c_char) -> c_int;
     }
@@ -66,6 +71,18 @@ pub unsafe extern "C" fn relibc_start(sp: &'static Stack) -> ! {
 
     _init();
 
+    // Look for the neighbor functions in memory until the end
+    let mut f = &__preinit_array_start as *const _;
+    while f < &__preinit_array_end {
+        (*f)();
+        f = f.offset(1);
+    }
+    f = &__init_array_start as *const _;
+    while f < &__init_array_end {
+        (*f)();
+        f = f.offset(1);
+    }
+
     stdlib::exit(main(
         argc,
         argv,