This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: R_ARM_TLS_DTPMOD32 Relocation


Dear Matthew,

Thanks for your answer,

We able to reproduce and identify our problem. It was related to build
environment. We build executable
with -fPIC option.

Dear Mr Lee,

Below relocations are generated when thread local storage is used in
application.

#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */
#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */
#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */

i.e when we want each thread to have its own copy of global data
instead of sharing process globals.



Shown below are two global declaration for variable i;

int i; >>>>> Global defination, hence all thread for &i will return
same address.



__thread int i; >>>>> Per Thread defination, hence each thread for &i
will return different address.




We already know the difference between the executable and shared libraries.

=> executable are always loaded at fixed address, since the global
lookup scope for any symbol starts with executable they do not require
GOT.

=> shared libraries are position independent, hence all global symbols
are accessed via GOT, also if symbols is defined in both executable
and shared library, then executable global defination is used as it
comes first in global lookup scope.



Similar is the case with symbol that are defined to be thread local.

=> ELF with GOT

#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */
#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */


=> ELF without GOT

#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */

I have made a simple test case (main.c & lib.c)



main.c

#include <pthread.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

#define MAX_THREAD 2

extern __thread int per_thread_var;
extern void *thread(void *arg);

int main(void)
{
        unsigned int i;
        pthread_t t_id;
        printf("%u\n", &per_thread_var);

        for (i=0 ; i < MAX_THREAD ; ++i) {
                pthread_create(&t_id, NULL, &thread, (void *)i);
        }
        sleep(1);
        return 0;
}


lib.c

#include <pthread.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

__thread int per_thread_var;

void *thread(void *arg)
{
        printf("%u\n", &per_thread_var);
}


$arm-linux-gnueabi-gcc -g -shared -fPIC -o lib1.so lib.c

$ arm-linux-gnueabi-gcc -g -o a-pic.out main.c -L. -l1 -lpthread
-fPIC

$ arm-linux-gnueabi-readelf -h a-pic.out | grep Type
Type: EXEC (Executable file)

$ arm-linux-gnueabi-readelf -r a-pic.out | grep per_thread_var
00010990 00000911 R_ARM_TLS_DTPMOD3 00000000 per_thread_var
00010994 00000912 R_ARM_TLS_DTPOFF3 00000000 per_thread_var


when compile executable without -fPIC option this disappear.

Thanks

On Wed, Jan 2, 2013 at 5:24 PM, Matthew Gretton-Dann
<matthew.gretton-dann@linaro.org> wrote:
>
> As I said above, I don't have enough information to answer this with
> confidence.  But my guess is that yes - you are going to have to
> handle this (and the related relocations) in the prelink utilities.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]