Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
R
relibc
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
redox-os
relibc
Commits
a2ab86d2
Verified
Commit
a2ab86d2
authored
9 months ago
by
Jacob Lorentzon
Browse files
Options
Downloads
Patches
Plain Diff
Implement signal selection in asm, for SA_ONSTACK.
parent
d45adade
No related branches found
No related tags found
1 merge request
!480
Refactor redox runtime and impl signals in userspace
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
redox-rt/src/arch/x86_64.rs
+45
-15
45 additions, 15 deletions
redox-rt/src/arch/x86_64.rs
redox-rt/src/signal.rs
+44
-16
44 additions, 16 deletions
redox-rt/src/signal.rs
src/platform/redox/signal.rs
+19
-15
19 additions, 15 deletions
src/platform/redox/signal.rs
with
108 additions
and
46 deletions
redox-rt/src/arch/x86_64.rs
+
45
−
15
View file @
a2ab86d2
...
...
@@ -16,6 +16,7 @@ pub struct SigArea {
altstack_top
:
usize
,
altstack_bottom
:
usize
,
tmp
:
usize
,
pub
onstack
:
u64
,
pub
disable_signals_depth
:
u64
,
}
...
...
@@ -128,18 +129,41 @@ asmfunction!(__relibc_internal_rlct_clone_ret -> usize: ["
"
]
<=
[]);
asmfunction!
(
__relibc_internal_sigentry
:
[
"
// Get offset to TCB
mov rax, gs:[0]
// First, select signal, always pick first available bit
// Read first signal word
mov rdx, fs:[{tcb_sc_off} + {sc_word}]
mov rcx, rdx
shr rcx, 32
and edx, ecx
bsf edx, edx
jnz 2f
// Read second signal word
mov rdx, fs:[{tcb_sc_off} + {sc_word} + 8]
mov rcx, rdx
shr rcx, 32
and edx, ecx
bsf edx, edx
jnz 4f
add edx, 32
2:
// By now we have selected a signal, stored in edx (6-bit). We now need to choose whether or
// not to switch to the alternate signal stack. If SA_ONSTACK is clear for this signal, then
// skip the sigaltstack logic.
bt fs:[{tcb_sa_off} + {sa_onstack}], edx
jc 3f
// If current RSP is above altstack region, switch to altstack
mov rdx,
[rax +
{tcb_sa_off} + {sa_altstack_top}]
mov rdx,
fs:[
{tcb_sa_off} + {sa_altstack_top}]
cmp rdx, rsp
cmova rsp, rdx
// If current RSP is below altstack region, also switch to altstack
mov rdx,
[rax +
{tcb_sa_off} + {sa_altstack_bottom}]
cmp rdx, r
ax
mov rdx,
fs:[
{tcb_sa_off} + {sa_altstack_bottom}]
cmp rdx, r
sp
cmovbe rsp, rdx
3:
// Otherwise, the altstack is already active. The sigaltstack being disabled, is equivalent
// to setting 'top' to usize::MAX and 'bottom' to 0.
...
...
@@ -147,16 +171,16 @@ asmfunction!(__relibc_internal_sigentry: ["
// Now that we have a stack, we can finally start initializing the signal stack!
push 0 // SS
push
[rax +
{tcb_sc_off} + {sc_saved_rsp}]
push
[rax +
{tcb_sc_off} + {sc_saved_rflags}]
push
fs:[
{tcb_sc_off} + {sc_saved_rsp}]
push
fs:[
{tcb_sc_off} + {sc_saved_rflags}]
push 0 // CS
push
[rax +
{tcb_sc_off} + {sc_saved_rip}]
push
fs:[
{tcb_sc_off} + {sc_saved_rip}]
push rdi
push rsi
push
[rax +
{tcb_sc_off} + {sc_saved_rdx}]
push
fs:[
{tcb_sc_off} + {sc_saved_rdx}]
push rcx
push
[rax +
{tcb_sc_off} + {sc_saved_rax}]
push
fs:[
{tcb_sc_off} + {sc_saved_rax}]
push r8
push r9
push r10
...
...
@@ -168,12 +192,14 @@ asmfunction!(__relibc_internal_sigentry: ["
push r14
push r15
sub rsp, 4096 + 32
push rdx // selected signal
sub rsp, 4096 + 24
cld
mov rdi, rsp
xor eax, eax
mov ecx, 4096 +
3
2
mov ecx, 4096 + 2
4
rep stosb
// TODO: self-modifying?
...
...
@@ -191,7 +217,7 @@ asmfunction!(__relibc_internal_sigentry: ["
mov edx, eax
xrstor [rsp]
add rsp, 4096 +
3
2
add rsp, 4096 + 2
4
2:
pop r15
pop r14
...
...
@@ -209,11 +235,11 @@ asmfunction!(__relibc_internal_sigentry: ["
pop rsi
pop rdi
pop qword ptr
g
s:[{tcb_sa_off} + {sa_tmp}]
pop qword ptr
f
s:[{tcb_sa_off} + {sa_tmp}]
add rsp, 8
popfq
pop rsp
jmp qword ptr
g
s:[{tcb_sa_off} + {sa_tmp}]
jmp qword ptr
f
s:[{tcb_sa_off} + {sa_tmp}]
3:
fxsave64 [rsp]
...
...
@@ -222,16 +248,20 @@ asmfunction!(__relibc_internal_sigentry: ["
fxrstor64 [rsp]
jmp 2b
4:
// Spurious signal
"
]
<=
[
inner
=
sym
inner_c
,
sa_tmp
=
const
offset_of!
(
SigArea
,
tmp
),
sa_altstack_top
=
const
offset_of!
(
SigArea
,
altstack_top
),
sa_altstack_bottom
=
const
offset_of!
(
SigArea
,
altstack_bottom
),
sa_onstack
=
const
offset_of!
(
SigArea
,
onstack
),
sc_saved_rax
=
const
offset_of!
(
Sigcontrol
,
saved_scratch_a
),
sc_saved_rdx
=
const
offset_of!
(
Sigcontrol
,
saved_scratch_b
),
sc_saved_rflags
=
const
offset_of!
(
Sigcontrol
,
saved_flags
),
sc_saved_rip
=
const
offset_of!
(
Sigcontrol
,
saved_ip
),
sc_saved_rsp
=
const
offset_of!
(
Sigcontrol
,
saved_sp
),
sc_word
=
const
offset_of!
(
Sigcontrol
,
word
),
tcb_sa_off
=
const
offset_of!
(
crate
::
Tcb
,
os_specific
)
+
offset_of!
(
RtSigarea
,
arch
),
tcb_sc_off
=
const
offset_of!
(
crate
::
Tcb
,
os_specific
)
+
offset_of!
(
RtSigarea
,
control
),
supports_xsave
=
sym
SUPPORTS_XSAVE
,
...
...
This diff is collapsed.
Click to expand it.
redox-rt/src/signal.rs
+
44
−
16
View file @
a2ab86d2
...
...
@@ -2,7 +2,7 @@ use core::cell::Cell;
use
core
::
ffi
::
c_int
;
use
core
::
sync
::
atomic
::{
AtomicU64
,
Ordering
};
use
syscall
::{
Error
,
IntRegisters
,
Result
,
SetSighandlerData
,
SigProcControl
,
Sigcontrol
,
EINVAL
,
SIGCHLD
,
SIGCONT
,
SIGKILL
,
SIGSTOP
,
SIGTSTP
,
SIGTTIN
,
SIGTTOU
,
SIGURG
,
SIGW0_TSTP_IS_STOP_BIT
,
SIGW0_TTIN_IS_STOP_BIT
,
SIGW0_TTOU_IS_STOP_BIT
,
SIGWINCH
};
use
syscall
::{
Error
,
IntRegisters
,
Result
,
SetSighandlerData
,
SigProcControl
,
Sigcontrol
,
EINVAL
,
SIGCHLD
,
SIGCONT
,
SIGKILL
,
SIGSTOP
,
SIGTSTP
,
SIGTTIN
,
SIGTTOU
,
SIGURG
,
SIGW0_NOCLDSTOP_BIT
,
SIGW0_TSTP_IS_STOP_BIT
,
SIGW0_TTIN_IS_STOP_BIT
,
SIGW0_TTOU_IS_STOP_BIT
,
SIGWINCH
};
use
crate
::{
arch
::
*
,
Tcb
};
use
crate
::
sync
::
Mutex
;
...
...
@@ -104,16 +104,24 @@ fn modify_sigmask(old: Option<&mut u64>, op: Option<impl FnMut(u32, bool) -> u32
Ok
(())
}
#[derive(Clone,
Copy)]
pub
enum
Sigaction
{
#[derive(Clone,
Copy,
Default)]
pub
enum
SigactionKind
{
#[default]
Default
,
Ignore
,
Handled
{
handler
:
SignalHandler
,
mask
:
u64
,
flags
:
SigactionFlags
,
},
}
#[derive(Clone,
Copy,
Default)]
pub
struct
Sigaction
{
pub
kind
:
SigactionKind
,
pub
mask
:
u64
,
pub
flags
:
SigactionFlags
,
}
pub
fn
sigaction
(
signal
:
u8
,
new
:
Option
<&
Sigaction
>
,
old
:
Option
<&
mut
Sigaction
>
)
->
Result
<
()
>
{
if
matches!
(
usize
::
from
(
signal
),
0
|
32
|
SIGKILL
|
SIGSTOP
|
65
..
)
{
return
Err
(
Error
::
new
(
EINVAL
));
...
...
@@ -125,39 +133,59 @@ pub fn sigaction(signal: u8, new: Option<&Sigaction>, old: Option<&mut Sigaction
let
old_ignmask
=
IGNMASK
.load
(
Ordering
::
Relaxed
);
if
let
Some
(
old
)
=
old
{
// TODO
}
let
Some
(
new
)
=
new
else
{
return
Ok
(());
};
match
(
usize
::
from
(
signal
),
new
)
{
(
_
,
Sigaction
::
Ignore
)
|
(
SIGCHLD
|
SIGURG
|
SIGWINCH
,
Sigaction
::
Default
)
=>
{
let
sig_group
=
usize
::
from
(
signal
)
/
32
;
let
sig_bit32
=
1
<<
((
signal
-
1
)
%
32
);
match
(
usize
::
from
(
signal
),
new
.kind
)
{
(
_
,
SigactionKind
::
Ignore
)
|
(
SIGURG
|
SIGWINCH
,
SigactionKind
::
Default
)
=>
{
IGNMASK
.store
(
old_ignmask
|
sig_bit
(
signal
.into
()),
Ordering
::
Relaxed
);
// mark the signal as masked
ctl
.word
[
u
si
ze
::
from
(
signal
)
/
32
]
.fetch_or
(
1
<<
((
signal
-
1
)
%
32
)
,
Ordering
::
Relaxed
);
ctl
.word
[
si
g_group
]
.fetch_or
(
sig_bit
32
,
Ordering
::
Relaxed
);
// POSIX specifies that pending signals shall be discarded if set to SIG_IGN by
// sigaction.
// TODO: handle tmp_disable_signals
}
// TODO: Handle pending signals before these flags are set.
(
SIGTSTP
,
Sigaction
::
Default
)
=>
{
(
SIGTSTP
,
Sigaction
Kind
::
Default
)
=>
{
PROC_CONTROL_STRUCT
.word
[
0
]
.fetch_or
(
SIGW0_TSTP_IS_STOP_BIT
,
Ordering
::
SeqCst
);
}
(
SIGTTIN
,
Sigaction
::
Default
)
=>
{
(
SIGTTIN
,
Sigaction
Kind
::
Default
)
=>
{
PROC_CONTROL_STRUCT
.word
[
0
]
.fetch_or
(
SIGW0_TTIN_IS_STOP_BIT
,
Ordering
::
SeqCst
);
}
(
SIGTTOU
,
Sigaction
::
Default
)
=>
{
(
SIGTTOU
,
Sigaction
Kind
::
Default
)
=>
{
PROC_CONTROL_STRUCT
.word
[
0
]
.fetch_or
(
SIGW0_TTOU_IS_STOP_BIT
,
Ordering
::
SeqCst
);
}
(
SIGCHLD
,
SigactionKind
::
Default
)
=>
{
if
new
.flags
.contains
(
SigactionFlags
::
NOCLDSTOP
)
{
PROC_CONTROL_STRUCT
.word
[
0
]
.fetch_or
(
SIGW0_NOCLDSTOP_BIT
,
Ordering
::
SeqCst
);
}
else
{
PROC_CONTROL_STRUCT
.word
[
0
]
.fetch_and
(
!
SIGW0_NOCLDSTOP_BIT
,
Ordering
::
SeqCst
);
}
IGNMASK
.store
(
old_ignmask
|
sig_bit
(
signal
.into
()),
Ordering
::
Relaxed
);
// mark the signal as masked
ctl
.word
[
sig_group
]
.fetch_or
(
sig_bit32
,
Ordering
::
Relaxed
);
}
(
_
,
SigactionKind
::
Default
)
=>
{
IGNMASK
.store
(
old_ignmask
&
!
sig_bit
(
signal
.into
()),
Ordering
::
Relaxed
);
(
_
,
Sigaction
::
Default
)
=>
(),
(
_
,
Sigaction
::
Handled
{
..
})
=>
(),
// TODO: update mask
//ctl.word[usize::from(signal)].fetch_or();
},
(
_
,
SigactionKind
::
Handled
{
..
})
=>
(),
}
todo!
()
Ok
(
()
)
}
fn
current_sigctl
()
->
&
'static
Sigcontrol
{
...
...
@@ -192,7 +220,7 @@ impl Drop for TmpDisableSignalsGuard {
bitflags
::
bitflags!
{
// Some flags are ignored by the rt, but they match relibc's 1:1 to simplify conversion.
#[derive(Clone,
Copy)]
#[derive(Clone,
Copy
,
Default
)]
pub
struct
SigactionFlags
:
u32
{
const
NOCLDSTOP
=
1
;
const
NOCLDWAIT
=
2
;
...
...
@@ -226,7 +254,7 @@ struct TheDefault {
ignmask
:
u64
,
}
static
SIGACTIONS
:
Mutex
<
[
Sigaction
;
64
]
>
=
Mutex
::
new
([
Sigaction
::
Default
;
64
]);
static
SIGACTIONS
:
Mutex
<
[
Sigaction
;
64
]
>
=
Mutex
::
new
([
Sigaction
{
flags
:
SigactionFlags
::
empty
(),
mask
:
0
,
kind
:
SigactionKind
::
Default
}
;
64
]);
static
IGNMASK
:
AtomicU64
=
AtomicU64
::
new
(
sig_bit
(
SIGCHLD
)
|
sig_bit
(
SIGURG
)
|
sig_bit
(
SIGWINCH
));
static
PROC_CONTROL_STRUCT
:
SigProcControl
=
SigProcControl
{
...
...
This diff is collapsed.
Click to expand it.
src/platform/redox/signal.rs
+
19
−
15
View file @
a2ab86d2
use
core
::
mem
;
use
redox_rt
::
signal
::{
Sigaction
,
SigactionFlags
,
SignalHandler
};
use
redox_rt
::
signal
::{
Sigaction
,
SigactionFlags
,
SigactionKind
,
SignalHandler
};
use
syscall
::{
self
,
Result
};
use
super
::{
...
...
@@ -111,49 +111,53 @@ impl PalSignal for Sys {
let
new_action
=
c_act
.map
(|
c_act
|
{
let
handler
=
c_act
.sa_handler
.map_or
(
0
,
|
f
|
f
as
usize
);
if
handler
==
SIG_DFL
{
Sigaction
::
Default
let
kind
=
if
handler
==
SIG_DFL
{
Sigaction
Kind
::
Default
}
else
if
handler
==
SIG_IGN
{
Sigaction
::
Ignore
Sigaction
Kind
::
Ignore
}
else
{
Sigaction
::
Handled
{
Sigaction
Kind
::
Handled
{
handler
:
if
c_act
.sa_flags
&
crate
::
header
::
signal
::
SA_SIGINFO
as
u64
!=
0
{
SignalHandler
{
sigaction
:
unsafe
{
core
::
mem
::
transmute
(
c_act
.sa_handler
)
}
}
}
else
{
SignalHandler
{
handler
:
c_act
.sa_handler
}
},
mask
:
c_act
.sa_mask
,
flags
:
SigactionFlags
::
from_bits_retain
(
c_act
.sa_flags
as
u32
),
}
};
Sigaction
{
kind
,
mask
:
c_act
.sa_mask
,
flags
:
SigactionFlags
::
from_bits_retain
(
c_act
.sa_flags
as
u32
),
}
});
let
mut
old_action
=
c_oact
.as_ref
()
.map
(|
_
|
Sigaction
::
D
efault
);
let
mut
old_action
=
c_oact
.as_ref
()
.map
(|
_
|
Sigaction
::
d
efault
()
);
redox_rt
::
signal
::
sigaction
(
sig
,
new_action
.as_ref
(),
old_action
.as_mut
())
?
;
if
let
(
Some
(
c_oact
),
Some
(
old_action
))
=
(
c_oact
,
old_action
)
{
*
c_oact
=
match
old_action
{
Sigaction
::
Ignore
=>
sigaction
{
*
c_oact
=
match
old_action
.kind
{
Sigaction
Kind
::
Ignore
=>
sigaction
{
sa_handler
:
unsafe
{
core
::
mem
::
transmute
(
SIG_IGN
)
},
sa_flags
:
0
,
sa_restorer
:
None
,
sa_mask
:
0
,
},
Sigaction
::
Default
=>
sigaction
{
Sigaction
Kind
::
Default
=>
sigaction
{
sa_handler
:
unsafe
{
core
::
mem
::
transmute
(
SIG_DFL
)
},
sa_flags
:
0
,
sa_restorer
:
None
,
sa_mask
:
0
,
},
Sigaction
::
Handled
{
handler
,
mask
,
flags
}
=>
sigaction
{
sa_handler
:
if
flags
.contains
(
SigactionFlags
::
SIGINFO
)
{
Sigaction
Kind
::
Handled
{
handler
}
=>
sigaction
{
sa_handler
:
if
old_action
.
flags
.contains
(
SigactionFlags
::
SIGINFO
)
{
unsafe
{
core
::
mem
::
transmute
(
handler
.sigaction
)
}
}
else
{
unsafe
{
handler
.handler
}
},
sa_restorer
:
None
,
sa_flags
:
flags
.bits
()
.into
(),
sa_mask
:
mask
,
sa_flags
:
old_action
.
flags
.bits
()
.into
(),
sa_mask
:
old_action
.
mask
,
},
};
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment