cmd/go, cmd/ld, runtime, os/user: TLS emulation for android
Based on cl/69170045 by Elias Naur.
There are currently several schemes for acquiring a TLS
slot to save the g register. None of them appear to work
for android. The closest are linux and darwin.
Linux uses a linker TLS relocation. This is not supported
by the android linker.
Darwin uses a fixed offset, and calls pthread_key_create
until it gets the slot it wants. As the runtime loads
late in the android process lifecycle, after an
arbitrary number of other libraries, we cannot rely on
any particular slot being available.
So we call pthread_key_create, take the first slot we are
given, and put it in runtime.tlsg, which we turn into a
regular variable in cmd/ld.
Makes android/arm cgo binaries work.
LGTM=minux
R=elias.naur, minux, dave, josharian
CC=golang-codereviews
https://golang.org/cl/106380043
2014-07-03 14:14:34 -06:00
|
|
|
// Copyright 2014 The Go Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
#include "zasm_GOOS_GOARCH.h"
|
|
|
|
#include "funcdata.h"
|
2014-09-04 21:05:18 -06:00
|
|
|
#include "textflag.h"
|
cmd/go, cmd/ld, runtime, os/user: TLS emulation for android
Based on cl/69170045 by Elias Naur.
There are currently several schemes for acquiring a TLS
slot to save the g register. None of them appear to work
for android. The closest are linux and darwin.
Linux uses a linker TLS relocation. This is not supported
by the android linker.
Darwin uses a fixed offset, and calls pthread_key_create
until it gets the slot it wants. As the runtime loads
late in the android process lifecycle, after an
arbitrary number of other libraries, we cannot rely on
any particular slot being available.
So we call pthread_key_create, take the first slot we are
given, and put it in runtime.tlsg, which we turn into a
regular variable in cmd/ld.
Makes android/arm cgo binaries work.
LGTM=minux
R=elias.naur, minux, dave, josharian
CC=golang-codereviews
https://golang.org/cl/106380043
2014-07-03 14:14:34 -06:00
|
|
|
|
|
|
|
// We have to resort to TLS variable to save g(R10).
|
|
|
|
// One reason is that external code might trigger
|
|
|
|
// SIGSEGV, and our runtime.sigtramp don't even know we
|
|
|
|
// are in external code, and will continue to use R10,
|
|
|
|
// this might as well result in another SIGSEGV.
|
|
|
|
// Note: both functions will clobber R0 and R11 and
|
|
|
|
// can be called from 5c ABI code.
|
|
|
|
|
|
|
|
// On android, runtime.tlsg is a normal variable.
|
|
|
|
// TLS offset is computed in x_cgo_inittls.
|
|
|
|
|
|
|
|
// save_g saves the g register into pthread-provided
|
|
|
|
// thread-local memory, so that we can call externally compiled
|
|
|
|
// ARM code that will overwrite those registers.
|
|
|
|
// NOTE: runtime.gogo assumes that R1 is preserved by this function.
|
|
|
|
// runtime.mcall assumes this function only clobbers R0 and R11.
|
|
|
|
TEXT runtime·save_g(SB),NOSPLIT,$0
|
2014-07-10 13:14:49 -06:00
|
|
|
#ifdef GOOS_nacl
|
|
|
|
// nothing to do as nacl/arm does not use TLS at all.
|
|
|
|
RET
|
|
|
|
#endif
|
cmd/go, cmd/ld, runtime, os/user: TLS emulation for android
Based on cl/69170045 by Elias Naur.
There are currently several schemes for acquiring a TLS
slot to save the g register. None of them appear to work
for android. The closest are linux and darwin.
Linux uses a linker TLS relocation. This is not supported
by the android linker.
Darwin uses a fixed offset, and calls pthread_key_create
until it gets the slot it wants. As the runtime loads
late in the android process lifecycle, after an
arbitrary number of other libraries, we cannot rely on
any particular slot being available.
So we call pthread_key_create, take the first slot we are
given, and put it in runtime.tlsg, which we turn into a
regular variable in cmd/ld.
Makes android/arm cgo binaries work.
LGTM=minux
R=elias.naur, minux, dave, josharian
CC=golang-codereviews
https://golang.org/cl/106380043
2014-07-03 14:14:34 -06:00
|
|
|
MRC 15, 0, R0, C13, C0, 3 // fetch TLS base pointer
|
|
|
|
// $runtime.tlsg(SB) is a special linker symbol.
|
|
|
|
// It is the offset from the TLS base pointer to our
|
|
|
|
// thread-local storage for g.
|
|
|
|
#ifdef GOOS_android
|
|
|
|
MOVW runtime·tlsg(SB), R11
|
|
|
|
#else
|
|
|
|
MOVW $runtime·tlsg(SB), R11
|
|
|
|
#endif
|
|
|
|
ADD R11, R0
|
|
|
|
MOVW g, 0(R0)
|
|
|
|
RET
|
|
|
|
|
|
|
|
// load_g loads the g register from pthread-provided
|
|
|
|
// thread-local memory, for use after calling externally compiled
|
|
|
|
// ARM code that overwrote those registers.
|
|
|
|
TEXT runtime·load_g(SB),NOSPLIT,$0
|
2014-07-10 13:14:49 -06:00
|
|
|
#ifdef GOOS_nacl
|
|
|
|
// nothing to do as nacl/arm does not use TLS at all.
|
|
|
|
RET
|
|
|
|
#endif
|
cmd/go, cmd/ld, runtime, os/user: TLS emulation for android
Based on cl/69170045 by Elias Naur.
There are currently several schemes for acquiring a TLS
slot to save the g register. None of them appear to work
for android. The closest are linux and darwin.
Linux uses a linker TLS relocation. This is not supported
by the android linker.
Darwin uses a fixed offset, and calls pthread_key_create
until it gets the slot it wants. As the runtime loads
late in the android process lifecycle, after an
arbitrary number of other libraries, we cannot rely on
any particular slot being available.
So we call pthread_key_create, take the first slot we are
given, and put it in runtime.tlsg, which we turn into a
regular variable in cmd/ld.
Makes android/arm cgo binaries work.
LGTM=minux
R=elias.naur, minux, dave, josharian
CC=golang-codereviews
https://golang.org/cl/106380043
2014-07-03 14:14:34 -06:00
|
|
|
MRC 15, 0, R0, C13, C0, 3 // fetch TLS base pointer
|
|
|
|
// $runtime.tlsg(SB) is a special linker symbol.
|
|
|
|
// It is the offset from the TLS base pointer to our
|
|
|
|
// thread-local storage for g.
|
|
|
|
#ifdef GOOS_android
|
|
|
|
MOVW runtime·tlsg(SB), R11
|
|
|
|
#else
|
|
|
|
MOVW $runtime·tlsg(SB), R11
|
|
|
|
#endif
|
|
|
|
ADD R11, R0
|
|
|
|
MOVW 0(R0), g
|
|
|
|
RET
|