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
c59b94d1
Commit
c59b94d1
authored
2 years ago
by
Jeremy Soller
Browse files
Options
Downloads
Patches
Plain Diff
Hacks to support aarch64 static TLS
parent
b0d3e5b1
No related branches found
No related tags found
No related merge requests found
Pipeline
#10545
failed
2 years ago
Stage: build
Stage: test
Changes
1
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/ld_so/tcb.rs
+33
-31
33 additions, 31 deletions
src/ld_so/tcb.rs
with
33 additions
and
31 deletions
src/ld_so/tcb.rs
+
33
−
31
View file @
c59b94d1
...
@@ -55,7 +55,7 @@ impl Tcb {
...
@@ -55,7 +55,7 @@ impl Tcb {
/// Create a new TCB
/// Create a new TCB
pub
unsafe
fn
new
(
size
:
usize
)
->
Result
<&
'static
mut
Self
>
{
pub
unsafe
fn
new
(
size
:
usize
)
->
Result
<&
'static
mut
Self
>
{
let
page_size
=
Sys
::
getpagesize
();
let
page_size
=
Sys
::
getpagesize
();
let
(
tls
,
tcb_page
)
=
Self
::
os_new
(
round_up
(
size
,
page_size
))
?
;
let
(
abi_page
,
tls
,
tcb_page
)
=
Self
::
os_new
(
round_up
(
size
,
page_size
))
?
;
let
tcb_ptr
=
tcb_page
.as_mut_ptr
()
as
*
mut
Self
;
let
tcb_ptr
=
tcb_page
.as_mut_ptr
()
as
*
mut
Self
;
trace!
(
"New TCB: {:p}"
,
tcb_ptr
);
trace!
(
"New TCB: {:p}"
,
tcb_ptr
);
...
@@ -123,8 +123,14 @@ impl Tcb {
...
@@ -123,8 +123,14 @@ impl Tcb {
.filter
(|
m
|
m
.len
>
0
)
.filter
(|
m
|
m
.len
>
0
)
.enumerate
()
.enumerate
()
{
{
let
range
=
let
range
=
if
cfg!
(
any
(
target_arch
=
"x86"
,
target_arch
=
"x86_64"
))
{
self
.tls_len
-
master
.offset
..
self
.tls_len
-
master
.offset
+
master
.len
;
// x86 TLS layout is backwards
self
.tls_len
-
master
.offset
..
self
.tls_len
-
master
.offset
+
master
.len
}
else
{
//TODO: fix aarch64 TLS layout when there is more than one master
assert_eq!
(
i
,
0
,
"aarch64 TLS layout only supports one master"
);
0
..
master
.len
};
if
let
Some
(
tls_data
)
=
tls
.get_mut
(
range
)
{
if
let
Some
(
tls_data
)
=
tls
.get_mut
(
range
)
{
let
data
=
master
.data
();
let
data
=
master
.data
();
trace!
(
trace!
(
...
@@ -165,7 +171,7 @@ impl Tcb {
...
@@ -165,7 +171,7 @@ impl Tcb {
/// Activate TLS
/// Activate TLS
pub
unsafe
fn
activate
(
&
mut
self
)
{
pub
unsafe
fn
activate
(
&
mut
self
)
{
Self
::
os_arch_activate
(
self
.t
cb_ptr
as
usize
);
Self
::
os_arch_activate
(
self
.t
ls_end
as
usize
,
self
.tls_len
);
}
}
/// Mapping with correct flags for TCB and TLS
/// Mapping with correct flags for TCB and TLS
...
@@ -189,23 +195,26 @@ impl Tcb {
...
@@ -189,23 +195,26 @@ impl Tcb {
/// OS specific code to create a new TLS and TCB - Linux and Redox
/// OS specific code to create a new TLS and TCB - Linux and Redox
#[cfg(any(target_os
=
"linux"
,
target_os
=
"redox"
))]
#[cfg(any(target_os
=
"linux"
,
target_os
=
"redox"
))]
unsafe
fn
os_new
(
size
:
usize
)
->
Result
<
(
&
'static
mut
[
u8
],
&
'static
mut
[
u8
])
>
{
unsafe
fn
os_new
(
size
:
usize
)
->
Result
<
(
&
'static
mut
[
u8
],
&
'static
mut
[
u8
],
&
'static
mut
[
u8
])
>
{
let
page_size
=
Sys
::
getpagesize
();
let
page_size
=
Sys
::
getpagesize
();
let
tls_tcb
=
Self
::
map
(
size
+
page_size
)
?
;
let
abi_tls_tcb
=
Self
::
map
(
page_size
+
size
+
page_size
)
?
;
Ok
(
tls_tcb
.split_at_mut
(
size
))
let
(
abi
,
tls_tcb
)
=
abi_tls_tcb
.split_at_mut
(
page_size
);
let
(
tls
,
tcb
)
=
tls_tcb
.split_at_mut
(
size
);
Ok
((
abi
,
tls
,
tcb
))
}
}
/// Architecture specific code to read a usize from the TCB - aarch64
/// Architecture specific code to read a usize from the TCB - aarch64
#[inline(always)]
#[inline(always)]
#[cfg(target_arch
=
"aarch64"
)]
#[cfg(target_arch
=
"aarch64"
)]
unsafe
fn
arch_read
(
offset
:
usize
)
->
usize
{
unsafe
fn
arch_read
(
offset
:
usize
)
->
usize
{
let
tp
:
usize
;
let
abi_ptr
:
usize
;
asm!
(
asm!
(
"mrs {}, tpidr_el0"
,
"mrs {}, tpidr_el0"
,
out
(
reg
)
tp
,
out
(
reg
)
abi_ptr
,
);
);
*
((
tp
+
offset
)
as
*
const
usize
)
let
tcb_ptr
=
*
(
abi_ptr
as
*
const
usize
);
*
((
tcb_ptr
+
offset
)
as
*
const
usize
)
}
}
/// Architecture specific code to read a usize from the TCB - x86
/// Architecture specific code to read a usize from the TCB - x86
...
@@ -240,33 +249,26 @@ impl Tcb {
...
@@ -240,33 +249,26 @@ impl Tcb {
/// OS and architecture specific code to activate TLS - Linux x86_64
/// OS and architecture specific code to activate TLS - Linux x86_64
#[cfg(all(target_os
=
"linux"
,
target_arch
=
"x86_64"
))]
#[cfg(all(target_os
=
"linux"
,
target_arch
=
"x86_64"
))]
unsafe
fn
os_arch_activate
(
t
p
:
usize
)
{
unsafe
fn
os_arch_activate
(
t
ls_end
:
usize
,
_tls_len
:
usize
)
{
const
ARCH_SET_FS
:
usize
=
0x1002
;
const
ARCH_SET_FS
:
usize
=
0x1002
;
syscall!
(
ARCH_PRCTL
,
ARCH_SET_FS
,
t
p
);
syscall!
(
ARCH_PRCTL
,
ARCH_SET_FS
,
t
ls_end
);
}
}
/// OS and architecture specific code to activate TLS - Redox aarch64
/// OS and architecture specific code to activate TLS - Redox aarch64
#[cfg(all(target_os
=
"redox"
,
target_arch
=
"aarch64"
))]
#[cfg(all(target_os
=
"redox"
,
target_arch
=
"aarch64"
))]
unsafe
fn
os_arch_activate
(
tp
:
usize
)
{
unsafe
fn
os_arch_activate
(
tls_end
:
usize
,
tls_len
:
usize
)
{
let
mut
env
=
syscall
::
EnvRegisters
::
default
();
// Uses ABI page
let
abi_ptr
=
tls_end
-
tls_len
-
16
;
let
file
=
syscall
::
open
(
"thisproc:current/regs/env"
,
syscall
::
O_CLOEXEC
|
syscall
::
O_RDWR
)
ptr
::
write
(
abi_ptr
as
*
mut
usize
,
tls_end
);
.expect_notls
(
"failed to open handle for process registers"
);
asm!
(
"msr tpidr_el0, {}"
,
let
_
=
syscall
::
read
(
file
,
&
mut
env
)
in
(
reg
)
abi_ptr
,
.expect_notls
(
"failed to read thread pointer"
);
);
env
.tpidr_el0
=
tp
;
let
_
=
syscall
::
write
(
file
,
&
env
)
.expect_notls
(
"failed to write thread pointer"
);
let
_
=
syscall
::
close
(
file
);
}
}
/// OS and architecture specific code to activate TLS - Redox x86
/// OS and architecture specific code to activate TLS - Redox x86
#[cfg(all(target_os
=
"redox"
,
target_arch
=
"x86"
))]
#[cfg(all(target_os
=
"redox"
,
target_arch
=
"x86"
))]
unsafe
fn
os_arch_activate
(
t
p
:
usize
)
{
unsafe
fn
os_arch_activate
(
t
ls_end
:
usize
,
_tls_len
:
usize
)
{
let
mut
env
=
syscall
::
EnvRegisters
::
default
();
let
mut
env
=
syscall
::
EnvRegisters
::
default
();
let
file
=
syscall
::
open
(
"thisproc:current/regs/env"
,
syscall
::
O_CLOEXEC
|
syscall
::
O_RDWR
)
let
file
=
syscall
::
open
(
"thisproc:current/regs/env"
,
syscall
::
O_CLOEXEC
|
syscall
::
O_RDWR
)
...
@@ -275,7 +277,7 @@ impl Tcb {
...
@@ -275,7 +277,7 @@ impl Tcb {
let
_
=
syscall
::
read
(
file
,
&
mut
env
)
let
_
=
syscall
::
read
(
file
,
&
mut
env
)
.expect_notls
(
"failed to read gsbase"
);
.expect_notls
(
"failed to read gsbase"
);
env
.gsbase
=
t
p
as
u32
;
env
.gsbase
=
t
ls_end
as
u32
;
let
_
=
syscall
::
write
(
file
,
&
env
)
let
_
=
syscall
::
write
(
file
,
&
env
)
.expect_notls
(
"failed to write gsbase"
);
.expect_notls
(
"failed to write gsbase"
);
...
@@ -285,7 +287,7 @@ impl Tcb {
...
@@ -285,7 +287,7 @@ impl Tcb {
/// OS and architecture specific code to activate TLS - Redox x86_64
/// OS and architecture specific code to activate TLS - Redox x86_64
#[cfg(all(target_os
=
"redox"
,
target_arch
=
"x86_64"
))]
#[cfg(all(target_os
=
"redox"
,
target_arch
=
"x86_64"
))]
unsafe
fn
os_arch_activate
(
t
p
:
usize
)
{
unsafe
fn
os_arch_activate
(
t
ls_end
:
usize
,
_tls_len
:
usize
)
{
let
mut
env
=
syscall
::
EnvRegisters
::
default
();
let
mut
env
=
syscall
::
EnvRegisters
::
default
();
let
file
=
syscall
::
open
(
"thisproc:current/regs/env"
,
syscall
::
O_CLOEXEC
|
syscall
::
O_RDWR
)
let
file
=
syscall
::
open
(
"thisproc:current/regs/env"
,
syscall
::
O_CLOEXEC
|
syscall
::
O_RDWR
)
...
@@ -294,7 +296,7 @@ impl Tcb {
...
@@ -294,7 +296,7 @@ impl Tcb {
let
_
=
syscall
::
read
(
file
,
&
mut
env
)
let
_
=
syscall
::
read
(
file
,
&
mut
env
)
.expect_notls
(
"failed to read fsbase"
);
.expect_notls
(
"failed to read fsbase"
);
env
.fsbase
=
t
p
as
u64
;
env
.fsbase
=
t
ls_end
as
u64
;
let
_
=
syscall
::
write
(
file
,
&
env
)
let
_
=
syscall
::
write
(
file
,
&
env
)
.expect_notls
(
"failed to write fsbase"
);
.expect_notls
(
"failed to write fsbase"
);
...
...
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