Skip to content

improve MIPS backend and implement segmented stacks #6358

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions mk/platform.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
86 changes: 85 additions & 1 deletion src/libcore/libc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,14 +268,17 @@ pub mod types {
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};

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,
Expand All @@ -298,6 +301,30 @@ pub mod types {
__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 {}
Expand Down Expand Up @@ -963,6 +990,9 @@ pub mod consts {
}
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;
Expand Down Expand Up @@ -1007,6 +1037,51 @@ pub mod consts {
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;

Expand All @@ -1026,11 +1101,20 @@ pub mod consts {
}
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")]
Expand Down
31 changes: 30 additions & 1 deletion src/libcore/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -152,6 +151,36 @@ mod 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;
Expand Down
1 change: 1 addition & 0 deletions src/libstd/ebml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ pub mod reader {
}

#[cfg(target_arch = "arm")]
#[cfg(target_arch = "mips")]
pub fn vuint_at(data: &[u8], start: uint) -> Res {
vuint_at_slow(data, start)
}
Expand Down
1 change: 0 additions & 1 deletion src/rt/arch/mips/ccall.S
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
.align 2
.globl __morestack
.hidden __morestack
.cfi_sections .eh_frame_entry
.cfi_startproc
.set nomips16
.ent __morestack
Expand Down
97 changes: 97 additions & 0 deletions src/rt/arch/mips/morestack.S
Original file line number Diff line number Diff line change
@@ -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
8 changes: 4 additions & 4 deletions src/rt/arch/mips/record_sp.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/rt/rust_task.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
#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__
Expand Down