-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Expose Linux syscall interface #63745
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
Changes from all commits
5e522cc
d4cb657
5aa44a6
1b6b1c4
a94c60c
1432b78
d246bd7
878dc6d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,4 @@ | |
|
||
pub mod raw; | ||
pub mod fs; | ||
pub mod syscall; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
#[inline(always)] | ||
pub unsafe fn syscall0(n: usize) -> usize { | ||
let ret : usize; | ||
asm!("svc 0" : "={x0}"(ret) | ||
: "{x8}"(n) | ||
: "memory" "cc" | ||
: "volatile"); | ||
ret | ||
} | ||
|
||
#[inline(always)] | ||
pub unsafe fn syscall1(n: usize, a1: usize) -> usize { | ||
let ret : usize; | ||
asm!("svc 0" : "={x0}"(ret) | ||
: "{x8}"(n), "{x0}"(a1) | ||
: "memory" "cc" | ||
: "volatile"); | ||
ret | ||
} | ||
|
||
#[inline(always)] | ||
pub unsafe fn syscall2(n: usize, a1: usize, a2: usize) -> usize { | ||
let ret : usize; | ||
asm!("svc 0" : "={x0}"(ret) | ||
: "{x8}"(n), "{x0}"(a1), "{x1}"(a2) | ||
: "memory" "cc" | ||
: "volatile"); | ||
ret | ||
} | ||
|
||
#[inline(always)] | ||
pub unsafe fn syscall3(n: usize, a1: usize, a2: usize, a3: usize) -> usize { | ||
let ret : usize; | ||
asm!("svc 0" : "={x0}"(ret) | ||
: "{x8}"(n), "{x0}"(a1), "{x1}"(a2), "{x2}"(a3) | ||
: "memory" "cc" | ||
: "volatile"); | ||
ret | ||
} | ||
|
||
#[inline(always)] | ||
pub unsafe fn syscall4(n: usize, a1: usize, a2: usize, a3: usize, | ||
a4: usize) -> usize { | ||
let ret : usize; | ||
asm!("svc 0" : "={x0}"(ret) | ||
: "{x8}"(n), "{x0}"(a1), "{x1}"(a2), "{x2}"(a3), "{x3}"(a4) | ||
: "memory" "cc" | ||
: "volatile"); | ||
ret | ||
} | ||
|
||
#[inline(always)] | ||
pub unsafe fn syscall5(n: usize, a1: usize, a2: usize, a3: usize, | ||
a4: usize, a5: usize) -> usize { | ||
let ret : usize; | ||
asm!("svc 0" : "={x0}"(ret) | ||
: "{x8}"(n), "{x0}"(a1), "{x1}"(a2), "{x2}"(a3), "{x3}"(a4), | ||
"{x4}"(a5) | ||
: "memory" "cc" | ||
: "volatile"); | ||
ret | ||
} | ||
|
||
#[inline(always)] | ||
pub unsafe fn syscall6(n: usize, a1: usize, a2: usize, a3: usize, | ||
a4: usize, a5: usize, a6: usize) -> usize { | ||
let ret : usize; | ||
asm!("svc 0" : "={x0}"(ret) | ||
: "{x8}"(n), "{x0}"(a1), "{x1}"(a2), "{x2}"(a3), "{x3}"(a4), | ||
"{x4}"(a5), "{x6}"(a6) | ||
: "memory" "cc" | ||
: "volatile"); | ||
ret | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
#[inline(always)] | ||
pub unsafe fn syscall0(n: usize) -> usize { | ||
let ret : usize; | ||
asm!("swi $$0" : "={r0}"(ret) | ||
: "{r7}"(n) | ||
: "memory" "cc" | ||
: "volatile"); | ||
ret | ||
} | ||
|
||
#[inline(always)] | ||
pub unsafe fn syscall1(n: usize, a1: usize) -> usize { | ||
let ret : usize; | ||
asm!("swi $$0" : "={r0}"(ret) | ||
: "{r7}"(n), "{r0}"(a1) | ||
: "memory" "cc" | ||
: "volatile"); | ||
ret | ||
} | ||
|
||
#[inline(always)] | ||
pub unsafe fn syscall2(n: usize, a1: usize, a2: usize) -> usize { | ||
let ret : usize; | ||
asm!("swi $$0" : "={r0}"(ret) | ||
: "{r7}"(n), "{r0}"(a1), "{r1}"(a2) | ||
: "memory" "cc" | ||
: "volatile"); | ||
ret | ||
} | ||
|
||
#[inline(always)] | ||
pub unsafe fn syscall3(n: usize, a1: usize, a2: usize, a3: usize) -> usize { | ||
let ret : usize; | ||
asm!("swi $$0" : "={r0}"(ret) | ||
: "{r7}"(n), "{r0}"(a1), "{r1}"(a2), "{r2}"(a3) | ||
: "memory" "cc" | ||
: "volatile"); | ||
ret | ||
} | ||
|
||
#[inline(always)] | ||
pub unsafe fn syscall4(n: usize, a1: usize, a2: usize, a3: usize, | ||
a4: usize) -> usize { | ||
let ret : usize; | ||
asm!("swi $$0" : "={r0}"(ret) | ||
: "{r7}"(n), "{r0}"(a1), "{r1}"(a2), "{r2}"(a3), | ||
"{r3}"(a4) | ||
: "memory" "cc" | ||
: "volatile"); | ||
ret | ||
} | ||
|
||
#[inline(always)] | ||
pub unsafe fn syscall5(n: usize, a1: usize, a2: usize, a3: usize, | ||
a4: usize, a5: usize) -> usize { | ||
let ret : usize; | ||
asm!("swi $$0" : "={r0}"(ret) | ||
: "{r7}"(n), "{r0}"(a1), "{r1}"(a2), "{r2}"(a3), | ||
"{r3}"(a4), "{r4}"(a5) | ||
: "memory" "cc" | ||
: "volatile"); | ||
ret | ||
} | ||
|
||
#[inline(always)] | ||
pub unsafe fn syscall6(n: usize, a1: usize, a2: usize, a3: usize, | ||
a4: usize, a5: usize, a6: usize) -> usize { | ||
let ret : usize; | ||
asm!("swi $$0" : "={r0}"(ret) | ||
: "{r7}"(n), "{r0}"(a1), "{r1}"(a2), "{r2}"(a3), | ||
"{r3}"(a4), "{r4}"(a5), "{r5}"(a6) | ||
: "memory" "cc" | ||
: "volatile"); | ||
ret | ||
} | ||
|
||
#[inline(always)] | ||
pub unsafe fn syscall7(n: usize, a1: usize, a2: usize, a3: usize, | ||
a4: usize, a5: usize, a6: usize, | ||
a7: usize) -> usize { | ||
let ret : usize; | ||
asm!("swi $$0" : "={r0}"(ret) | ||
: "{r7}"(n), "{r0}"(a1), "{r1}"(a2), "{r2}"(a3), | ||
"{r3}"(a4), "{r4}"(a5), "{r5}"(a6), "{r6}"(a7) | ||
: "memory" "cc" | ||
: "volatile"); | ||
ret | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
//! Raw syscall functions. | ||
#![unstable(feature = "linux_syscall", issue = "63748")] | ||
#![cfg(any(target_arch = "x86", target_arch = "x86_64", target_arch = "aarch64"))] | ||
|
||
#[cfg(target_arch = "x86")] | ||
#[path="x86.rs"] mod platform; | ||
|
||
#[cfg(target_arch = "x86_64")] | ||
#[path="x86_64.rs"] mod platform; | ||
|
||
#[cfg(target_arch = "aarch64")] | ||
#[path="aarch64"] mod platform; | ||
|
||
#[cfg(target_arch = "arm")] | ||
#[path="arm"] mod platform; | ||
|
||
/// Execute syscall with 0 arguments. | ||
#[unstable(feature = "linux_syscall", issue = "63748")] | ||
#[inline(always)] | ||
pub unsafe fn syscall0(n: usize) -> usize { | ||
platform::syscall0(n) | ||
} | ||
|
||
/// Execute syscall with 1 argument. | ||
#[unstable(feature = "linux_syscall", issue = "63748")] | ||
#[inline(always)] | ||
pub unsafe fn syscall1(n: usize, a1: usize) -> usize { | ||
platform::syscall1(n, a1) | ||
} | ||
|
||
/// Execute syscall with 2 arguments. | ||
#[unstable(feature = "linux_syscall", issue = "63748")] | ||
#[inline(always)] | ||
pub unsafe fn syscall2(n: usize, a1: usize, a2: usize) -> usize { | ||
platform::syscall2(n, a1, a2) | ||
} | ||
|
||
/// Execute syscall with 3 arguments. | ||
#[unstable(feature = "linux_syscall", issue = "63748")] | ||
#[inline(always)] | ||
pub unsafe fn syscall3(n: usize, a1: usize, a2: usize, a3: usize) -> usize { | ||
platform::syscall3(n, a1, a2, a3) | ||
} | ||
|
||
/// Execute syscall with 4 arguments. | ||
#[unstable(feature = "linux_syscall", issue = "63748")] | ||
#[inline(always)] | ||
pub unsafe fn syscall4( | ||
n: usize, a1: usize, a2: usize, a3: usize, a4: usize, | ||
) -> usize { | ||
platform::syscall4(n, a1, a2, a3, a4) | ||
} | ||
|
||
/// Execute syscall with 5 arguments. | ||
#[unstable(feature = "linux_syscall", issue = "63748")] | ||
#[inline(always)] | ||
pub unsafe fn syscall5( | ||
n: usize, a1: usize, a2: usize, a3: usize, a4: usize, a5: usize, | ||
) -> usize { | ||
platform::syscall5(n, a1, a2, a3, a4, a5) | ||
} | ||
|
||
/// Execute syscall with 6 arguments. | ||
#[unstable(feature = "linux_syscall", issue = "63748")] | ||
#[inline(always)] | ||
pub unsafe fn syscall6( | ||
n: usize, a1: usize, a2: usize, a3: usize, a4: usize, a5: usize, a6: usize, | ||
) -> usize { | ||
platform::syscall6(n, a1, a2, a3, a4, a5, a6) | ||
} | ||
|
||
/// Execute syscall with 7 arguments. | ||
/// | ||
/// Available only on ARM targets. | ||
#[cfg(target_arch = "arm")] | ||
#[unstable(feature = "linux_syscall", issue = "63748")] | ||
#[inline(always)] | ||
pub unsafe fn syscall7( | ||
n: usize, a1: usize, a2: usize, a3: usize, a4: usize, | ||
a5: usize, a6: usize, a7: usize, | ||
) -> usize { | ||
platform::syscall7(n, a1, a2, a3, a4, a5, a6, a7) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
#[inline(always)] | ||
pub unsafe fn syscall0(n: usize) -> usize { | ||
let ret : usize; | ||
asm!("int $$0x80" : "={eax}"(ret) | ||
: "{eax}"(n) | ||
: "memory" "cc" | ||
: "volatile"); | ||
ret | ||
} | ||
|
||
#[inline(always)] | ||
pub unsafe fn syscall1(n: usize, a1: usize) -> usize { | ||
let ret : usize; | ||
asm!("int $$0x80" : "={eax}"(ret) | ||
: "{eax}"(n), "{ebx}"(a1) | ||
: "memory" "cc" | ||
: "volatile"); | ||
ret | ||
} | ||
|
||
#[inline(always)] | ||
pub unsafe fn syscall2(n: usize, a1: usize, a2: usize) -> usize { | ||
let ret : usize; | ||
asm!("int $$0x80" : "={eax}"(ret) | ||
: "{eax}"(n), "{ebx}"(a1), "{ecx}"(a2) | ||
: "memory" "cc" | ||
: "volatile"); | ||
ret | ||
} | ||
|
||
#[inline(always)] | ||
pub unsafe fn syscall3(n: usize, a1: usize, a2: usize, a3: usize) -> usize { | ||
let ret : usize; | ||
asm!("int $$0x80" : "={eax}"(ret) | ||
: "{eax}"(n), "{ebx}"(a1), "{ecx}"(a2), "{edx}"(a3) | ||
: "memory" "cc" | ||
: "volatile"); | ||
ret | ||
} | ||
|
||
#[inline(always)] | ||
pub unsafe fn syscall4(n: usize, a1: usize, a2: usize, a3: usize, | ||
a4: usize) -> usize { | ||
let ret : usize; | ||
asm!("int $$0x80" : "={eax}"(ret) | ||
: "{eax}"(n), "{ebx}"(a1), "{ecx}"(a2), "{edx}"(a3), | ||
"{esi}"(a4) | ||
: "memory" "cc" | ||
: "volatile"); | ||
ret | ||
} | ||
|
||
#[inline(always)] | ||
pub unsafe fn syscall5(n: usize, a1: usize, a2: usize, a3: usize, | ||
a4: usize, a5: usize) -> usize { | ||
let ret : usize; | ||
asm!("int $$0x80" : "={eax}"(ret) | ||
: "{eax}"(n), "{ebx}"(a1), "{ecx}"(a2), "{edx}"(a3), | ||
"{esi}"(a4), "{edi}"(a5) | ||
: "memory" "cc" | ||
: "volatile"); | ||
ret | ||
} | ||
|
||
#[inline(always)] | ||
pub unsafe fn syscall6(n: usize, a1: usize, a2: usize, a3: usize, | ||
a4: usize, a5: usize, a6: usize) -> usize { | ||
let ret : usize; | ||
|
||
// | ||
// this fails when building without optimizations: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would something like the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It could, but since There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @newpavlov I'm really surprised that I'd love to avoid this extra overhead if possible, but this doesn't need to be a blocker. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would be concerned if |
||
// | ||
// asm!("int $$0x80" : "={eax}"(ret) | ||
// : "{eax}"(n), "{ebx}"(a1), "{ecx}"(a2), "{edx}"(a3), | ||
// "{esi}"(a4), "{edi}"(a5), "{ebp}"(a6) | ||
// : "memory" "cc" | ||
// : "volatile"); | ||
// | ||
// error: ran out of registers during register allocation | ||
// | ||
// this fails when building with optimizations as the "m"(a6) gets translated to | ||
// [esp+offset] but the push ebp moved esp. | ||
// | ||
// asm!("push %ebp | ||
// mov $7, %ebp | ||
// int $$0x80 | ||
// pop %ebp" | ||
// : "={eax}"(ret) | ||
// : "{eax}"(n), "{ebx}"(a1), "{ecx}"(a2), "{edx}"(a3), | ||
// "{esi}"(a4), "{edi}"(a5), "m"(a6) | ||
// : "memory" "cc" | ||
// : "volatile"); | ||
// | ||
// in general putting "ebp" in clobber list seems to not have any effect. | ||
// | ||
// As workaround only use a single input operand with known memory layout and manually save | ||
// restore ebp. | ||
let args = [n, a1, a2, a3, a4, a5, a6]; | ||
|
||
asm!("push %ebp | ||
movl 24(%eax), %ebp | ||
movl 20(%eax), %edi | ||
movl 16(%eax), %esi | ||
movl 12(%eax), %edx | ||
movl 8(%eax), %ecx | ||
movl 4(%eax), %ebx | ||
movl 0(%eax), %eax | ||
int $$0x80 | ||
pop %ebp" | ||
: "={eax}"(ret) | ||
: "{eax}"(args) | ||
: "ebx" "ecx" "edx" "esi" "edi" "ebp" "memory" "cc" | ||
: "volatile"); | ||
ret | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should these be calling via the VDSO instead?