This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
[PATCH] PPC64 support multi TOCs
- From: Steven Munroe <sjmunroe at us dot ibm dot com>
- To: libc-alpha at sources dot redhat dot com, Alan Modra <amodra at bigpond dot net dot au>
- Date: Thu, 12 Jun 2003 16:18:37 -0500
- Subject: [PATCH] PPC64 support multi TOCs
- Reply-to: sjmunroe at vnet dot ibm dot com
This time attach the patches ...
Currently very large applications/libraries may fail to link because
they overflow the 64KB (8K entry) "Table Of Contents" or TOC (i.e
"relocation truncated to fit: R_PPC64_TOC16_DS ..."). Alan Modra is
working on gcc/binutils changes to automatically create multiple TOCs
for these cases.
The PowerPC64 ABI combines the GOT and TOC and allows for both @toc and
@got notation and relocations. At run time the GOT may exists as subset
of the TOC and use the same base register (R2). Alan's proposed change
[binutils cvs head and
ftp://ftp.linuxppc64.org/pub/people/amodra/gcc-3.2/gcc-20030611-ppc64.diff.gz]
supports multiple TOC per application/library but not multiple GOTs. So
it would be best if powerpc64 libc code did not contain any @got
references. The attached patch replaces the few remaining @got usages
with @toc notation.
2003-06-12 Steven Munroe <sjmunroe@us.ibm.com>
* sysdeps/powerpc/powerpc64/dl-machine.h (RTLD_START): Replace
@got notation with @toc.
* sysdeps/powerpc/powerpc64/sysdep.h (CALL_MCOUNT): Replace @got
notation with @toc.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S (__brk)
Replace @ got notation with @toc.
Separately for linuxthreads
2003-06-12 Steven Munroe <sjmunroe@us.ibm.com>
* sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
(SINGLE_THREAD_P): Replace @ got notation with @toc.
diff -rup libc23-cvstip-20030610/sysdeps/powerpc/powerpc64/dl-machine.h libc23/sysdeps/powerpc/powerpc64/dl-machine.h
--- libc23-cvstip-20030610/sysdeps/powerpc/powerpc64/dl-machine.h 2003-05-31 20:31:07.000000000 -0500
+++ libc23/sysdeps/powerpc/powerpc64/dl-machine.h 2003-06-11 17:14:12.000000000 -0500
@@ -239,6 +239,18 @@ elf_machine_dynamic (void)
"_dl_start_user:\n" \
" .quad ._dl_start_user, .TOC.@tocbase, 0\n" \
" .previous\n" \
+" .section \".toc\",\"aw\"\n" \
+".LC__dl_starting_up:\n" \
+" .tc _dl_starting_up_internal[TC],_dl_starting_up_internal\n" \
+".LC__rtld_global:\n" \
+" .tc _rtld_global[TC],_rtld_global\n" \
+".LC__dl_argc:\n" \
+" .tc _dl_argc[TC],_dl_argc\n" \
+".LC__dl_argv:\n" \
+" .tc _dl_argv_internal[TC],_dl_argv_internal\n" \
+".LC__dl_fini:\n" \
+" .tc _dl_fini[TC],_dl_fini\n" \
+" .previous\n" \
" .globl ._dl_start_user\n" \
" .type ._dl_start_user,@function\n" \
/* Now, we do our main work of calling initialisation procedures. \
@@ -250,9 +262,9 @@ elf_machine_dynamic (void)
/* the address of _start in r30. */ \
" mr 30,3\n" \
/* &_dl_argc in 29, &_dl_argv in 27, and _dl_loaded in 28. */ \
-" ld 28,_rtld_global@got(2)\n" \
-" ld 29,_dl_argc@got(2)\n" \
-" ld 27,_dl_argv@got(2)\n" \
+" ld 28,.LC__rtld_global@toc(2)\n" \
+" ld 29,.LC__dl_argc@toc(2)\n" \
+" ld 27,.LC__dl_argv@toc(2)\n" \
/* _dl_init (_dl_loaded, _dl_argc, _dl_argv, _dl_argv+_dl_argc+1). */ \
" ld 3,0(28)\n" \
" lwa 4,0(29)\n" \
@@ -279,8 +291,8 @@ elf_machine_dynamic (void)
" addi 6,6,8\n" \
/* Pass a termination function pointer (in this case _dl_fini) in \
r7. */ \
-" ld 7,_dl_fini@got(2)\n" \
-" ld 26,_dl_starting_up@got(2)\n" \
+" ld 7,.LC__dl_fini@toc(2)\n" \
+" ld 26,.LC__dl_starting_up@toc(2)\n" \
/* Pass the stack pointer in r1 (so far so good), pointing to a NULL \
value. This lets our startup code distinguish between a program \
linked statically, which linux will call with argc on top of the \
diff -rup libc23-cvstip-20030610/sysdeps/powerpc/powerpc64/sysdep.h libc23/sysdeps/powerpc/powerpc64/sysdep.h
--- libc23-cvstip-20030610/sysdeps/powerpc/powerpc64/sysdep.h 2003-03-24 12:45:27.000000000 -0600
+++ libc23/sysdeps/powerpc/powerpc64/sysdep.h 2003-06-12 09:50:57.000000000 -0500
@@ -34,11 +34,16 @@
.pushsection; \
.section ".data"; \
.align ALIGNARG(2); \
-0: .long 0; \
+__mcount: \
+ .long 0; \
+ .previous; \
+ .section ".toc","aw"; \
+.LC__mcount:; \
+ .tc __mcount[TC],__mcount; \
.previous; \
mflr r0; \
std r0,16(r1); \
- ld r0,0b@got(r2); \
+ ld r0,.LC__mcount@toc(r2); \
bl JUMPTARGET(_mcount);
#else /* SYSV_ELF_PROFILING */
#define CALL_MCOUNT \
@@ -52,11 +57,16 @@
.pushsection; \
.section ".data"; \
.align ALIGNARG(2); \
-0: .long 0; \
+__mcount: \
+ .long 0; \
+ .previous; \
+ .section ".toc","aw"; \
+.LC__mcount:; \
+ .tc __mcount[TC],__mcount; \
.previous; \
mflr r0; \
std r0,16(r1); \
- ld r0,0b@got(r2); \
+ ld r0,.LC__mcount@toc(r2); \
bl JUMPTARGET(_mcount);
#else /* SYSV_ELF_PROFILING */
#define CALL_MCOUNT \
diff -rup libc23-cvstip-20030610/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S libc23/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S
--- libc23-cvstip-20030610/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S 2002-09-17 18:50:03.000000000 -0500
+++ libc23/sysdeps/unix/sysv/linux/powerpc/powerpc64/brk.S 2003-06-12 09:58:11.000000000 -0500
@@ -24,6 +24,9 @@
#include <bp-asm.h>
.comm __curbrk,8,8
+ .section ".toc","aw"
+.LC__curbrk:
+ .tc __curbrk[TC],__curbrk
.section ".text"
ENTRY (BP_SYM (__brk))
DISCARD_BOUNDS (r3) /* the bounds are meaningless, so toss 'em. */
@@ -32,7 +35,7 @@ ENTRY (BP_SYM (__brk))
std r3,48(r1)
DO_CALL(SYS_ify(brk))
ld r6,48(r1)
- ld r5,__curbrk@got(r2)
+ ld r5,.LC__curbrk@toc(r2)
std r3,0(r5)
cmpld r6,r3
addi r1,r1,64
diff -rup libc23-cvstip-20030610/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h libc23/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
--- libc23-cvstip-20030610/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h 2003-01-12 02:14:11.000000000 -0600
+++ libc23/linuxthreads/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h 2003-06-12 09:59:20.000000000 -0500
@@ -89,7 +89,11 @@ extern int __local_multiple_threads attr
# define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
# else
# define SINGLE_THREAD_P \
- ld 10,__local_multiple_threads@got(2); \
+ .section ".toc","aw"; \
+.LC__local_multiple_threads:; \
+ .tc __local_multiple_threads[TC],__local_multiple_threads; \
+ .previous; \
+ ld 10,.LC__local_multiple_threads@toc(2); \
ld 10,0(10); \
cmpdi 10,0
# endif