Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
go
Commits
2d6ae385
Commit
2d6ae385
authored
Jul 17, 2010
by
Russ Cox
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
linux/386: use Xen-friendly ELF TLS instruction sequence
Fixes #465. R=iant CC=golang-dev
https://golang.org/cl/1665051
parent
bc2ee6b8
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
76 additions
and
12 deletions
+76
-12
src/cmd/8l/list.c
src/cmd/8l/list.c
+1
-1
src/cmd/8l/pass.c
src/cmd/8l/pass.c
+37
-4
src/libcgo/linux_386.c
src/libcgo/linux_386.c
+6
-3
src/pkg/runtime/linux/386/sys.s
src/pkg/runtime/linux/386/sys.s
+7
-4
src/pkg/runtime/mkasmh.sh
src/pkg/runtime/mkasmh.sh
+25
-0
No files found.
src/cmd/8l/list.c
View file @
2d6ae385
...
...
@@ -102,7 +102,7 @@ Dconv(Fmt *fp)
i
=
a
->
type
;
if
(
i
>=
D_INDIR
&&
i
<
2
*
D_INDIR
)
{
if
(
a
->
offset
)
sprint
(
str
,
"%ld(%R)"
,
a
->
offset
,
i
-
D_INDIR
);
sprint
(
str
,
"%ld(%R)"
,
(
long
)
a
->
offset
,
i
-
D_INDIR
);
else
sprint
(
str
,
"(%R)"
,
i
-
D_INDIR
);
goto
brk
;
...
...
src/cmd/8l/pass.c
View file @
2d6ae385
...
...
@@ -378,7 +378,7 @@ patch(void)
s
=
lookup
(
"exit"
,
0
);
vexit
=
s
->
value
;
for
(
p
=
firstp
;
p
!=
P
;
p
=
p
->
link
)
{
if
(
HEADTYPE
==
10
)
{
if
(
HEADTYPE
==
10
)
{
// Windows
// Convert
// op n(GS), reg
// to
...
...
@@ -391,7 +391,7 @@ patch(void)
&&
p
->
to
.
type
>=
D_AX
&&
p
->
to
.
type
<=
D_DI
)
{
q
=
appendp
(
p
);
q
->
from
=
p
->
from
;
q
->
from
.
type
+=
p
->
to
.
type
-
D_GS
;
q
->
from
.
type
=
D_INDIR
+
p
->
to
.
type
;
q
->
to
=
p
->
to
;
q
->
as
=
p
->
as
;
p
->
as
=
AMOVL
;
...
...
@@ -399,6 +399,23 @@ patch(void)
p
->
from
.
offset
=
0x2C
;
}
}
if
(
HEADTYPE
==
7
)
{
// Linux
// Running binaries under Xen requires using
// MOVL 0(GS), reg
// and then off(reg) instead of saying off(GS) directly
// when the offset is negative.
if
(
p
->
from
.
type
==
D_INDIR
+
D_GS
&&
p
->
from
.
offset
<
0
&&
p
->
to
.
type
>=
D_AX
&&
p
->
to
.
type
<=
D_DI
)
{
q
=
appendp
(
p
);
q
->
from
=
p
->
from
;
q
->
from
.
type
=
D_INDIR
+
p
->
to
.
type
;
q
->
to
=
p
->
to
;
q
->
as
=
p
->
as
;
p
->
as
=
AMOVL
;
p
->
from
.
type
=
D_INDIR
+
D_GS
;
p
->
from
.
offset
=
0
;
}
}
if
(
p
->
as
==
ATEXT
)
curtext
=
p
;
if
(
p
->
as
==
ACALL
||
(
p
->
as
==
AJMP
&&
p
->
to
.
type
!=
D_BRANCH
))
{
...
...
@@ -616,7 +633,8 @@ dostkoff(void)
if
(
pmorestack
!=
P
)
if
(
!
(
p
->
from
.
scale
&
NOSPLIT
))
{
p
=
appendp
(
p
);
// load g into CX
if
(
HEADTYPE
==
10
)
{
switch
(
HEADTYPE
)
{
case
10
:
// Windows
p
->
as
=
AMOVL
;
p
->
from
.
type
=
D_INDIR
+
D_FS
;
p
->
from
.
offset
=
0x2c
;
...
...
@@ -627,7 +645,22 @@ dostkoff(void)
p
->
from
.
type
=
D_INDIR
+
D_CX
;
p
->
from
.
offset
=
0
;
p
->
to
.
type
=
D_CX
;
}
else
{
break
;
case
7
:
// Linux
p
->
as
=
AMOVL
;
p
->
from
.
type
=
D_INDIR
+
D_GS
;
p
->
from
.
offset
=
0
;
p
->
to
.
type
=
D_CX
;
p
=
appendp
(
p
);
p
->
as
=
AMOVL
;
p
->
from
.
type
=
D_INDIR
+
D_CX
;
p
->
from
.
offset
=
tlsoffset
+
0
;
p
->
to
.
type
=
D_CX
;
break
;
default:
p
->
as
=
AMOVL
;
p
->
from
.
type
=
D_INDIR
+
D_GS
;
p
->
from
.
offset
=
tlsoffset
+
0
;
...
...
src/libcgo/linux_386.c
View file @
2d6ae385
...
...
@@ -45,11 +45,14 @@ threadentry(void *v)
* Set specific keys. On Linux/ELF, the thread local storage
* is just before %gs:0. Our dynamic 8.out's reserve 8 bytes
* for the two words g and m at %gs:-8 and %gs:-4.
* Xen requires us to access those words indirect from %gs:0
* which points at itself.
*/
asm
volatile
(
"movl %0, %%gs:-8
\n
"
// MOVL g, -8(GS)
"movl %1, %%gs:-4
\n
"
// MOVL m, -4(GS)
::
"r"
(
ts
.
g
),
"r"
(
ts
.
m
)
"movl %%gs:0, %%eax
\n
"
// MOVL 0(GS), tmp
"movl %0, -8(%%eax)
\n
"
// MOVL g, -8(GS)
"movl %1, -4(%%eax)
\n
"
// MOVL m, -4(GS)
::
"r"
(
ts
.
g
),
"r"
(
ts
.
m
)
:
"%eax"
);
crosscall_386
(
ts
.
fn
);
...
...
src/pkg/runtime/linux/386/sys.s
View file @
2d6ae385
...
...
@@ -161,12 +161,12 @@ TEXT clone(SB),7,$0
//
In
child
on
new
stack
.
Reload
registers
(
paranoia
)
.
MOVL
0
(
SP
),
BX
//
m
MOVL
4
(
SP
),
DX
//
g
MOVL
8
(
SP
),
CX
//
fn
MOVL
8
(
SP
),
SI
//
fn
MOVL
AX
,
m_procid
(
BX
)
//
save
tid
as
m
->
procid
//
set
up
ldt
7
+
id
to
point
at
m
->
tls
.
//
m
->
tls
is
at
m
+
40
.
newosproc
left
the
id
in
tls
[
0
]
.
//
newosproc
left
the
id
in
tls
[
0
]
.
LEAL
m_tls
(
BX
),
BP
MOVL
0
(
BP
),
DI
ADDL
$
7
,
DI
//
m0
is
LDT
#
7
.
count
up
.
...
...
@@ -186,7 +186,7 @@ TEXT clone(SB),7,$0
MOVL
DX
,
g
(
AX
)
MOVL
BX
,
m
(
AX
)
CALL
stackcheck
(
SB
)
//
smashes
AX
CALL
stackcheck
(
SB
)
//
smashes
AX
,
CX
MOVL
0
(
DX
),
DX
//
paranoia
; check they are not nil
MOVL
0
(
BX
),
BX
...
...
@@ -195,7 +195,7 @@ TEXT clone(SB),7,$0
CALL
emptyfunc
(
SB
)
POPAL
CALL
CX
//
fn
()
CALL
SI
//
fn
()
CALL
exit1
(
SB
)
MOVL
$
0x1234
,
0x1005
RET
...
...
@@ -247,8 +247,11 @@ TEXT setldt(SB),7,$32
*
To
accommodate
that
rewrite
,
we
translate
*
the
address
here
and
bump
the
limit
to
0xffffffff
(
no
limit
)
*
so
that
-
8
(
GS
)
maps
to
0
(
address
)
.
*
Also
,
the
final
0
(
GS
)
(
current
8
(
CX
))
has
to
point
*
to
itself
,
to
mimic
ELF
.
*/
ADDL
$
0x8
,
CX
//
address
MOVL
CX
,
0
(
CX
)
//
set
up
user_desc
LEAL
16
(
SP
),
AX
//
struct
user_desc
...
...
src/pkg/runtime/mkasmh.sh
View file @
2d6ae385
...
...
@@ -24,6 +24,31 @@ case "$GOARCH" in
echo
'#define g(r) 0(r)'
echo
'#define m(r) 4(r)'
;;
linux
)
# On Linux systems, what we call 0(GS) and 4(GS) for g and m
# turn into %gs:-8 and %gs:-4 (using gcc syntax to denote
# what the machine sees as opposed to 8l input).
# 8l rewrites 0(GS) and 4(GS) into these.
#
# On Linux Xen, it is not allowed to use %gs:-8 and %gs:-4
# directly. Instead, we have to store %gs:0 into a temporary
# register and then use -8(%reg) and -4(%reg). This kind
# of addressing is correct even when not running Xen.
#
# 8l can rewrite MOVL 0(GS), CX into the appropriate pair
# of mov instructions, using CX as the intermediate register
# (safe because CX is about to be written to anyway).
# But 8l cannot handle other instructions, like storing into 0(GS),
# which is where these macros come into play.
# get_tls sets up the temporary and then g and r use it.
#
# The final wrinkle is that get_tls needs to read from %gs:0,
# but in 8l input it's called 8(GS), because 8l is going to
# subtract 8 from all the offsets, as described above.
echo
'#define get_tls(r) MOVL 8(GS), r'
echo
'#define g(r) -8(r)'
echo
'#define m(r) -4(r)'
;;
*
)
echo
'#define get_tls(r)'
echo
'#define g(r) 0(GS)'
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment