Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Update.
* elf/tst-tls1.c: Move TLS helper macros to... * elf/tls-macros.h: ...here. New file. * elf/tst-tls2.c: New file. * elf/Makefile (tests): Add tst-tls2. (distribute): Add tls-macros.h.
- Loading branch information
Ulrich Drepper
committed
Feb 10, 2002
1 parent
a5176ea
commit 2cef425
Showing
5 changed files
with
163 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
/* Macros to support TLS testing in times of missing compiler support. */ | ||
|
||
#define COMMON_INT_DEF(x) \ | ||
asm (".tls_common " #x ",4,4") | ||
|
||
/* XXX This definition will probably be machine specific, too. */ | ||
#define VAR_INT_DEF(x) \ | ||
asm (".section .tdata\n\t" \ | ||
".globl " #x "\n" \ | ||
#x ":\t.long 0\n\t" \ | ||
".previous") | ||
|
||
|
||
/* XXX Each architecture must have its own asm for now. */ | ||
#ifdef __i386__ | ||
# define TLS_LE(x) \ | ||
({ int *__l; \ | ||
asm ("movl %%gs:0,%0\n\t" \ | ||
"subl $" #x "@tpoff,%0" \ | ||
: "=r" (__l)); \ | ||
__l; }) | ||
|
||
#define TLS_IE(x) \ | ||
({ int *__l, __b; \ | ||
asm ("call 1f\n\t" \ | ||
".subsection 1\n" \ | ||
"1:\tmovl (%%esp), %%ebx\n\t" \ | ||
"ret\n\t" \ | ||
".previous\n\t" \ | ||
"addl $_GLOBAL_OFFSET_TABLE_, %%ebx\n\t" \ | ||
"movl %%gs:0,%0\n\t" \ | ||
"subl " #x "@gottpoff(%%ebx),%0" \ | ||
: "=r" (__l), "=&b" (__b)); \ | ||
__l; }) | ||
|
||
#define TLS_LD(x) \ | ||
({ int *__l, __b; \ | ||
asm ("call 1f\n\t" \ | ||
".subsection 1\n" \ | ||
"1:\tmovl (%%esp), %%ebx\n\t" \ | ||
"ret\n\t" \ | ||
".previous\n\t" \ | ||
"addl $_GLOBAL_OFFSET_TABLE_, %%ebx\n\t" \ | ||
"leal " #x "@tlsldm(%%ebx),%%eax\n\t" \ | ||
"call ___tls_get_addr@plt\n\t" \ | ||
"leal " #x "@dtpoff(%%eax), %%eax" \ | ||
: "=a" (__l), "=&b" (__b)); \ | ||
__l; }) | ||
|
||
#define TLS_GD(x) \ | ||
({ int *__l, __b; \ | ||
asm ("call 1f\n\t" \ | ||
".subsection 1\n" \ | ||
"1:\tmovl (%%esp), %%ebx\n\t" \ | ||
"ret\n\t" \ | ||
".previous\n\t" \ | ||
"addl $_GLOBAL_OFFSET_TABLE_, %%ebx\n\t" \ | ||
"leal " #x "@tlsgd(%%ebx),%%eax\n\t" \ | ||
"call ___tls_get_addr@plt\n\t" \ | ||
"nop" \ | ||
: "=a" (__l), "=&b" (__b)); \ | ||
__l; }) | ||
|
||
#else | ||
# error "No support for this architecture so far." | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/* glibc test for TLS in ld.so. */ | ||
#include <stdio.h> | ||
|
||
#include <tls.h> | ||
#include "tls-macros.h" | ||
|
||
|
||
/* Two 'int' variables in TLS. */ | ||
VAR_INT_DEF(foo); | ||
VAR_INT_DEF(bar); | ||
|
||
|
||
int | ||
main (void) | ||
{ | ||
#ifdef USE_TLS | ||
int result = 0; | ||
int *ap, *bp; | ||
|
||
|
||
/* Set the variable using the local exec model. */ | ||
puts ("set bar to 1 (LE)"); | ||
ap = TLS_LE (bar); | ||
*ap = 1; | ||
|
||
|
||
/* Get variables using initial exec model. */ | ||
fputs ("get sum of foo and bar (IE)", stdout); | ||
ap = TLS_IE (foo); | ||
bp = TLS_IE (bar); | ||
printf (" = %d\n", *ap + *bp); | ||
result |= *ap + *bp != 1; | ||
if (*ap != 0) | ||
{ | ||
printf ("foo = %d\n", *ap); | ||
result = 1; | ||
} | ||
if (*bp != 1) | ||
{ | ||
printf ("bar = %d\n", *bp); | ||
result = 1; | ||
} | ||
|
||
|
||
/* Get variables using local dynamic model. */ | ||
fputs ("get sum of foo and bar (LD)", stdout); | ||
ap = TLS_LD (foo); | ||
bp = TLS_LD (bar); | ||
printf (" = %d\n", *ap + *bp); | ||
result |= *ap + *bp != 1; | ||
if (*ap != 0) | ||
{ | ||
printf ("foo = %d\n", *ap); | ||
result = 1; | ||
} | ||
if (*bp != 1) | ||
{ | ||
printf ("bar = %d\n", *bp); | ||
result = 1; | ||
} | ||
|
||
|
||
/* Get variables using generic dynamic model. */ | ||
fputs ("get sum of foo and bar (GD)", stdout); | ||
ap = TLS_GD (foo); | ||
bp = TLS_GD (bar); | ||
printf (" = %d\n", *ap + *bp); | ||
result |= *ap + *bp != 1; | ||
if (*ap != 0) | ||
{ | ||
printf ("foo = %d\n", *ap); | ||
result = 1; | ||
} | ||
if (*bp != 1) | ||
{ | ||
printf ("bar = %d\n", *bp); | ||
result = 1; | ||
} | ||
|
||
return result; | ||
#else | ||
return 0; | ||
#endif | ||
} |