LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 23566 - need llvm support for emulated tls for Android
Summary: need llvm support for emulated tls for Android
Status: RESOLVED FIXED
Alias: None
Product: libraries
Classification: Unclassified
Component: Backend: ARM (show other bugs)
Version: trunk
Hardware: PC Linux
: P normal
Assignee: Chih-Hung Hsieh
URL:
Keywords:
Depends on:
Blocks: 21420
  Show dependency tree
 
Reported: 2015-05-18 15:58 PDT by Chih-Hung Hsieh
Modified: 2015-08-03 13:12 PDT (History)
2 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Chih-Hung Hsieh 2015-05-18 15:58:09 PDT
Current clang generates references to __aeabi_read_tp
for arm target under -fpie.
It generates references to __tls_get_addr under -fPIC,
and no special library reference under -fpie for x86 target.

The reference to __aeabi_read_tp caused link time error
because Android run-time library does not have this function yet.

Gcc for arm target generates references to __emutls_get_address under -fpie or -fPIC.

Is there any clang arm target configuration flag to generate
for -fpie references to __tls_get_addr or __emutls_get_address,
or no external reference at all?
This will allow existing AOSP upstream projects to continue using -fpie,
instead of -fPIC or waiting for an upgrade of AOSP library.


The folloing is a test case reduced from Android Open Source external/fio/gettime.c
It shows that reference to __aeabi_read_tp is used only for arm -fpie,
not for -fPIC or x86.

$ cat g.i.c
struct mytimeval {
  int tv_sec;
  int tv_usec;
};
struct tv_valid {
 struct mytimeval last_tv;
 int last_tv_valid;
};
extern __thread struct tv_valid static_tv_valid;
void fio_gettime(struct mytimeval *tp)
{
 struct tv_valid *tv = &static_tv_valid;
 if (tv) {
  if (tv->last_tv_valid)
    tp->tv_sec = tv->last_tv.tv_sec;
  tv->last_tv_valid = 1;
 }
}

$ clang -fpie g.i.c -c -o /tmp/c.x86.pie.o
$ clang -fPIC g.i.c -c -o /tmp/c.x86.PIC.o
$ clang -target arm-linux-androideabi -fpie g.i.c -c -o /tmp/c.pie.o
$ clang -target arm-linux-androideabi -fPIC g.i.c -c -o /tmp/c.PIC.o

$ nm /tmp/c.x86.pie.o | grep -E 'aeabi_read|tls_'
$ nm /tmp/c.x86.PIC.o | grep -E 'aeabi_read|tls_'
        U __tls_get_addr
$ nm /tmp/c.pie.o | grep -E 'aeabi_read|tls_'
        U __aeabi_read_tp
$ nm /tmp/c.PIC.o | grep -E 'aeabi_read|tls_'
        U __tls_get_addr
Comment 1 dimitry 2015-05-18 18:00:19 PDT
The problem with __aeabi_read_tp function is that it uses fixed offset for everything. This leads to number of problems starting with

1) It currently starts at errno slot __aeabi_read_tp() + 8
2) It does not support having thread_local variable in more than one dso (they end up sharing offsets and will overwrite each-other values)
3) It may run out of boundaries of the tls buffer, if number of thread_locals is big enough. And there is no way for libc to catch this (because of compiled in offsets which do not get passed to __aeabi_read_tp).

I think the best way to solve this is to always use __tls_get_addr(), or in case of emulated tls (which llvm does not yet support afaik) - translate thread_locals to pthread_keycreate() and co calls.
Comment 2 Chih-Hung Hsieh 2015-05-20 14:22:07 PDT
To make thread local storage work with current Android run-time, llvm should do as gcc does now. Emulated tls mode is when __thread/thread_local are translated to appropriate calls to pthread_key_create/getspecific/setspecific().
Comment 3 Chih-Hung Hsieh 2015-06-17 19:13:23 PDT
First draft implementation to review at
http://reviews.llvm.org/D10522 and
http://reviews.llvm.org/D10524
Comment 4 Chih-Hung Hsieh 2015-06-29 14:14:28 PDT
Current llvm supports ELF TLS as described in http://www.akkadia.org/drepper/tls.pdf
However, Android dynamic linker does not handle the ELF TLS models yet.

Android has GCC emutls library to support the emulated TLS code generated by gcc.
Before Android linker can handle the ELF TLS models and devices upgraded to a new linker, clang/llvm users would need to use compatible emutls model.
The patch in http://reviews.llvm.org/D10524 adds a new flag -ftls-model=emulated in clang to generate the "emultated" TLS model attribute, and patch http://reviews.llvm.org/D10524 added to llvm to generate the compatible function calls and control variables to link with libgcc's emutls. See https://github.com/gcc-mirror/gcc/blob/master/libgcc/emutls.c
Comment 5 Chih-Hung Hsieh 2015-08-03 13:12:09 PDT
Should have been fixed with changes up to r243475.