]> git.lizzy.rs Git - rust.git/commitdiff
improve MIPS backend and implement segmented stacks
authorJyun-Yan You <jyyou@cs.nctu.edu.tw>
Tue, 7 May 2013 10:03:32 +0000 (18:03 +0800)
committerJyun-Yan You <jyyou@cs.nctu.edu.tw>
Thu, 9 May 2013 08:51:42 +0000 (16:51 +0800)
mk/platform.mk
src/libcore/libc.rs
src/libcore/path.rs
src/libstd/ebml.rs
src/rt/arch/mips/ccall.S
src/rt/arch/mips/morestack.S [new file with mode: 0644]
src/rt/arch/mips/record_sp.S
src/rt/rust_task.h

index e03b7c152478fd86a89ddc5da5f7b3859cd7907d..efba83e6ad4c71eee98b2dba5c7123cead153644 100644 (file)
@@ -247,12 +247,12 @@ AR_mips-unknown-linux-gnu=mips-linux-gnu-ar
 CFG_LIB_NAME_mips-unknown-linux-gnu=lib$(1).so
 CFG_LIB_GLOB_mips-unknown-linux-gnu=lib$(1)-*.so
 CFG_LIB_DSYM_GLOB_mips-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
-CFG_GCCISH_CFLAGS_mips-unknown-linux-gnu := -Wall -g -fPIC -mips32r2 -msoft-float -mabi=32
+CFG_GCCISH_CFLAGS_mips-unknown-linux-gnu := -Wall -g -fPIC -mips32r2 -msoft-float -mabi=32 -mno-compact-eh
 CFG_GCCISH_CXXFLAGS_mips-unknown-linux-gnu := -fno-rtti
 CFG_GCCISH_LINK_FLAGS_mips-unknown-linux-gnu := -shared -fPIC -g -mips32r2 -msoft-float -mabi=32
 CFG_GCCISH_DEF_FLAG_mips-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
 CFG_GCCISH_PRE_LIB_FLAGS_mips-unknown-linux-gnu := -Wl,-whole-archive
-CFG_GCCISH_POST_LIB_FLAGS_mips-unknown-linux-gnu := -Wl,-no-whole-archive -Wl,-znoexecstack
+CFG_GCCISH_POST_LIB_FLAGS_mips-unknown-linux-gnu := -Wl,-no-whole-archive
 CFG_DEF_SUFFIX_mips-unknown-linux-gnu := .linux.def
 CFG_INSTALL_NAME_mips-unknown-linux-gnu =
 CFG_LIBUV_LINK_FLAGS_mips-unknown-linux-gnu =
index 6fb4572913d2e7cc6c5f752a32deb0ae295c8490..7ae3f0fd2d462124d964d7e7a158c32b21c4efbc 100644 (file)
@@ -268,7 +268,7 @@ pub mod posix88 {
                 pub type ssize_t = i32;
             }
             pub mod posix01 {
-                use libc::types::os::arch::c95::{c_short, c_long, time_t};
+                use libc::types::os::arch::c95::{c_short, c_long, c_ulong, time_t};
                 use libc::types::os::arch::posix88::{dev_t, gid_t, ino_t};
                 use libc::types::os::arch::posix88::{mode_t, off_t};
                 use libc::types::os::arch::posix88::{uid_t};
@@ -276,6 +276,9 @@ pub mod posix01 {
                 pub type nlink_t = u32;
                 pub type blksize_t = i32;
                 pub type blkcnt_t = i32;
+
+                #[cfg(target_arch = "x86")]
+                #[cfg(target_arch = "arm")]
                 pub struct stat {
                     st_dev: dev_t,
                     __pad1: c_short,
@@ -298,6 +301,30 @@ pub struct stat {
                     __unused4: c_long,
                     __unused5: c_long,
                 }
+
+                #[cfg(target_arch = "mips")]
+                pub struct stat {
+                    st_dev: c_ulong,
+                    st_pad1: [c_long, ..3],
+                    st_ino: ino_t,
+                    st_mode: mode_t,
+                    st_nlink: nlink_t,
+                    st_uid: uid_t,
+                    st_gid: gid_t,
+                    st_rdev: c_ulong,
+                    st_pad2: [c_long, ..2],
+                    st_size: off_t,
+                    st_pad3: c_long,
+                    st_atime: time_t,
+                    st_atime_nsec: c_long,
+                    st_mtime: time_t,
+                    st_mtime_nsec: c_long,
+                    st_ctime: time_t,
+                    st_ctime_nsec: c_long,
+                    st_blksize: blksize_t,
+                    st_blocks: blkcnt_t,
+                    st_pad5: [c_long, ..14],
+                }
             }
             pub mod posix08 {}
             pub mod bsd44 {}
@@ -963,6 +990,9 @@ pub mod c95 {
         }
         pub mod c99 {
         }
+        #[cfg(target_arch = "x86")]
+        #[cfg(target_arch = "x86_64")]
+        #[cfg(target_arch = "arm")]
         pub mod posix88 {
             pub static O_RDONLY : int = 0;
             pub static O_WRONLY : int = 1;
@@ -1007,6 +1037,51 @@ pub mod posix88 {
             pub static SIGALRM : int = 14;
             pub static SIGTERM : int = 15;
         }
+        #[cfg(target_arch = "mips")]
+        pub mod posix88 {
+            pub static O_RDONLY : int = 0;
+            pub static O_WRONLY : int = 1;
+            pub static O_RDWR : int = 2;
+            pub static O_APPEND : int = 8;
+            pub static O_CREAT : int = 256;
+            pub static O_EXCL : int = 1024;
+            pub static O_TRUNC : int = 512;
+            pub static S_IFIFO : int = 4096;
+            pub static S_IFCHR : int = 8192;
+            pub static S_IFBLK : int = 24576;
+            pub static S_IFDIR : int = 16384;
+            pub static S_IFREG : int = 32768;
+            pub static S_IFMT : int = 61440;
+            pub static S_IEXEC : int = 64;
+            pub static S_IWRITE : int = 128;
+            pub static S_IREAD : int = 256;
+            pub static S_IRWXU : int = 448;
+            pub static S_IXUSR : int = 64;
+            pub static S_IWUSR : int = 128;
+            pub static S_IRUSR : int = 256;
+            pub static F_OK : int = 0;
+            pub static R_OK : int = 4;
+            pub static W_OK : int = 2;
+            pub static X_OK : int = 1;
+            pub static STDIN_FILENO : int = 0;
+            pub static STDOUT_FILENO : int = 1;
+            pub static STDERR_FILENO : int = 2;
+            pub static F_LOCK : int = 1;
+            pub static F_TEST : int = 3;
+            pub static F_TLOCK : int = 2;
+            pub static F_ULOCK : int = 0;
+            pub static SIGHUP : int = 1;
+            pub static SIGINT : int = 2;
+            pub static SIGQUIT : int = 3;
+            pub static SIGILL : int = 4;
+            pub static SIGABRT : int = 6;
+            pub static SIGFPE : int = 8;
+            pub static SIGKILL : int = 9;
+            pub static SIGSEGV : int = 11;
+            pub static SIGPIPE : int = 13;
+            pub static SIGALRM : int = 14;
+            pub static SIGTERM : int = 15;
+        }
         pub mod posix01 {
             pub static SIGTRAP : int = 5;
 
@@ -1026,11 +1101,20 @@ pub mod posix08 {
         }
         pub mod bsd44 {
         }
+        #[cfg(target_arch = "x86")]
+        #[cfg(target_arch = "x86_64")]
+        #[cfg(target_arch = "arm")]
         pub mod extra {
             pub static O_RSYNC : int = 1052672;
             pub static O_DSYNC : int = 4096;
             pub static O_SYNC : int = 1052672;
         }
+        #[cfg(target_arch = "mips")]
+        pub mod extra {
+            pub static O_RSYNC : int = 16400;
+            pub static O_DSYNC : int = 16;
+            pub static O_SYNC : int = 16400;
+        }
     }
 
     #[cfg(target_os = "freebsd")]
index a87fd90f4e27ab4957229c9d3a4af210d86055be..d3010aff3e8cde8af65a72fdc03ab79350666254 100644 (file)
@@ -122,7 +122,6 @@ pub trait GenericPath {
 mod stat {
     #[cfg(target_arch = "x86")]
     #[cfg(target_arch = "arm")]
-    #[cfg(target_arch = "mips")]
     pub mod arch {
         use libc;
 
@@ -152,6 +151,36 @@ pub fn default_stat() -> libc::stat {
         }
     }
 
+    #[cfg(target_arch = "mips")]
+    pub mod arch {
+        use libc;
+
+        pub fn default_stat() -> libc::stat {
+            libc::stat {
+                st_dev: 0,
+                st_pad1: [0, ..3],
+                st_ino: 0,
+                st_mode: 0,
+                st_nlink: 0,
+                st_uid: 0,
+                st_gid: 0,
+                st_rdev: 0,
+                st_pad2: [0, ..2],
+                st_size: 0,
+                st_pad3: 0,
+                st_atime: 0,
+                st_atime_nsec: 0,
+                st_mtime: 0,
+                st_mtime_nsec: 0,
+                st_ctime: 0,
+                st_ctime_nsec: 0,
+                st_blksize: 0,
+                st_blocks: 0,
+                st_pad5: [0, ..14],
+            }
+        }
+    }
+
     #[cfg(target_arch = "x86_64")]
     pub mod arch {
         use libc;
index 5e4f708f52fd4c3e3659f68d33db8a55928da4d4..55f48fb86716c59dfb4ee4b7cf0d5030b8d67132 100644 (file)
@@ -157,6 +157,7 @@ pub fn vuint_at(data: &[u8], start: uint) -> Res {
     }
 
     #[cfg(target_arch = "arm")]
+    #[cfg(target_arch = "mips")]
     pub fn vuint_at(data: &[u8], start: uint) -> Res {
         vuint_at_slow(data, start)
     }
index abbbad164fd372ec24f2caac971ed04a0322d690..cdcdc07db555d6f132dedb2cce35358fd76a0937 100644 (file)
@@ -8,7 +8,6 @@
 .align 2
 .globl __morestack
 .hidden __morestack
-.cfi_sections .eh_frame_entry
 .cfi_startproc
 .set nomips16
 .ent __morestack
diff --git a/src/rt/arch/mips/morestack.S b/src/rt/arch/mips/morestack.S
new file mode 100644 (file)
index 0000000..e534ac0
--- /dev/null
@@ -0,0 +1,97 @@
+// Mark stack as non-executable
+#if defined(__linux__) && defined(__ELF__)
+.section        .note.GNU-stack, "", @progbits
+#endif
+
+.text
+
+.globl upcall_new_stack
+.globl upcall_del_stack
+.globl __morestack
+
+.hidden __morestack
+
+.cfi_startproc
+.set nomips16
+.ent __morestack
+__morestack:
+        .set noreorder
+        .set nomacro
+
+        addiu $29, $29, -12
+        sw $31, 8($29)
+        sw $30, 4($29)
+        sw $23, 0($29)
+
+        // 24 = 12 (current) + 12 (previous)
+        .cfi_def_cfa_offset 24
+        .cfi_offset 31, -4
+        .cfi_offset 30, -20
+        .cfi_offset 23, -24
+
+        move $23, $28
+        move $30, $29
+        .cfi_def_cfa_register 30
+
+        // Save argument registers of the original function
+        addiu $29, $29, -32
+        sw $4, 16($29)
+        sw $5, 20($29)
+        sw $6, 24($29)
+        sw $7, 28($29)
+
+        move $4, $14     // Size of stack arguments
+        addu $5, $30, 24 // Address of stack arguments
+        move $6, $15     // The amount of stack needed
+
+        move $28, $23
+        lw $25, %call16(upcall_new_stack)($23)
+        jalr $25
+        nop
+
+        // Pop the saved arguments
+        lw $4, 16($29)
+        lw $5, 20($29)
+        lw $6, 24($29)
+        lw $7, 28($29)
+        addiu $29, $29, 32
+
+        lw $24, 8($30)     // Grab the return pointer.
+        addiu $24, $24, 12 // Skip past the `lw`, `jr`, `addiu` in our parent frame
+        move $29, $2       // Switch to the new stack.
+
+        // for PIC
+        lw $2, 12($30)
+        lw $25, 16($30)
+
+        move $28, $23
+        jalr $24           // Reenter the caller function
+        nop
+
+        // Switch back to the rust stack
+        move $29, $30
+
+        // Save the return value
+        addiu $29, $29, -24
+        sw $2, 16($29)
+        sw $3, 20($29)
+
+        move $28, $23
+        lw $25, %call16(upcall_del_stack)($23)
+        jalr $25
+        nop
+
+        // Restore the return value
+        lw $2, 16($29)
+        lw $3, 20($29)
+        addiu $29, $29, 24
+
+        lw $31, 8($29)
+        lw $30, 4($29)
+        lw $23, 0($29)
+        addiu $29, $29, 12
+
+        jr $31
+        nop
+.end __morestack
+.cfi_endproc
index dd4d2f393754d1c8ac4aba049cb2289e2a7094f5..a88fefead049fd3cc764b2a0e30e141adc291f9a 100644 (file)
@@ -16,8 +16,8 @@ record_sp_limit:
         .set mips32r2
         rdhwr $3, $29
         .set pop
-        addiu $3, $3, -0x7008
-        sw $4, 4($3)
+        addiu $3, $3, -0x7004
+        sw $4, 0($3)
         jr $31
         nop
 .end record_sp_limit
@@ -33,8 +33,8 @@ get_sp_limit:
         .set mips32r2
         rdhwr $3, $29
         .set pop
-        addiu $3, $3, -0x7008
-        lw $2, 4($3)
+        addiu $3, $3, -0x7004
+        lw $2, 0($3)
         jr $31
         nop
 .end get_sp_limit
index b76a177e1c87aefb0e4fbc992c1dd6c474bf30db..672af608db86358053ad1880a5897f3371547999 100644 (file)
 #define RED_ZONE_SIZE RZ_LINUX_64
 #endif
 #ifdef __mips__
-#define RED_ZONE_SIZE RZ_LINUX_32
+#define RED_ZONE_SIZE RZ_MAC_32
 #endif
 #endif
 #ifdef __APPLE__