summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--config.h.in3
-rwxr-xr-xconfigure10
-rw-r--r--configure.in7
-rw-r--r--nptl/ChangeLog3
-rw-r--r--nptl/DESIGN-barrier.txt2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h14
-rw-r--r--sysdeps/powerpc/powerpc64/configure68
-rw-r--r--sysdeps/powerpc/powerpc64/configure.in42
-rw-r--r--sysdeps/powerpc/powerpc64/dl-machine.h79
-rw-r--r--sysdeps/powerpc/powerpc64/sysdep.h201
11 files changed, 292 insertions, 151 deletions
diff --git a/ChangeLog b/ChangeLog
index 703e89b683..e108e01ef7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2004-09-07 Jakub Jelinek <jakub@redhat.com>
+
+ * sysdeps/powerpc/powerpc64/configure.in: New file.
+ * config.h.in (USE_PPC64_OVERLAPPING_OPD): Add.
+ * configure.in (HAVE_ASM_GLOBAL_DOT_NAME): Remove.
+ * sysdeps/powerpc/powerpc64/sysdep.h: Formatting.
+ (OPD_ENT, BODY_LABEL, ENTRY_1, ENTRY_2, END_2, DOT_PREFIX,
+ BODY_PREFIX): Define.
+ (ENTRY, DOT_LABEL, END, TRACEBACK, END_GEN_TB, EALIGN): Support
+ HAVE_ASM_GLOBAL_DOT_NAME or no dot symbols,
+ USE_PPC64_OVERLAPPING_OPD or never overlapping .opd entries.
+ * sysdeps/powerpc/powerpc64/dl-machine.h: Include sysdep.h.
+ (TRAMPOLINE_TEMPLATE, RTLD_START): Use the new sysdep.h macros.
+
2004-09-07 Ulrich Drepper <drepper@redhat.com>
* malloc/malloc.h: Don't define __THROW if it is already defined.
diff --git a/config.h.in b/config.h.in
index c02d691883..bd990c6627 100644
--- a/config.h.in
+++ b/config.h.in
@@ -61,6 +61,9 @@
/* Define a symbol_name as a global .symbol_name for ld. */
#undef HAVE_ASM_GLOBAL_DOT_NAME
+/* On powerpc64, use overlapping .opd entries. */
+#undef USE_PPC64_OVERLAPPING_OPD
+
/* Define if the assembler generates debugging information directly. */
#undef HAVE_CPP_ASM_DEBUGINFO
diff --git a/configure b/configure
index 985118daa5..625d507715 100755
--- a/configure
+++ b/configure
@@ -5031,16 +5031,6 @@ _ACEOF
fi
-# The Aix ld uses global .symbol_names instead of symbol_names.
-# Unfortunately also used in the PPC64 ELF ABI.
-case "${os}${machine}" in
-aix4.3* | linux*powerpc/powerpc64*)
- cat >>confdefs.h <<\_ACEOF
-#define HAVE_ASM_GLOBAL_DOT_NAME 1
-_ACEOF
-
-esac
-
echo "$as_me:$LINENO: checking for .symver assembler directive" >&5
echo $ECHO_N "checking for .symver assembler directive... $ECHO_C" >&6
if test "${libc_cv_asm_symver_directive+set}" = set; then
diff --git a/configure.in b/configure.in
index 3941aba967..24e6cb948f 100644
--- a/configure.in
+++ b/configure.in
@@ -1030,13 +1030,6 @@ if test "x$libc_cv_asm_type_prefix" != xno; then
AC_DEFINE_UNQUOTED(ASM_TYPE_DIRECTIVE_PREFIX, ${libc_cv_asm_type_prefix})
fi
-# The Aix ld uses global .symbol_names instead of symbol_names.
-# Unfortunately also used in the PPC64 ELF ABI.
-case "${os}${machine}" in
-aix4.3* | linux*powerpc/powerpc64*)
- AC_DEFINE(HAVE_ASM_GLOBAL_DOT_NAME)
-esac
-
AC_CACHE_CHECK(for .symver assembler directive, libc_cv_asm_symver_directive,
[cat > conftest.s <<EOF
${libc_cv_dot_text}
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 6857273d9c..f382a0080c 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,5 +1,8 @@
2004-09-07 Ulrich Drepper <drepper@redhat.com>
+ * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h: Allow
+ PSEUDO to be used with . prefix.
+
* sysdeps/unix/sysv/linux/alpha/pthread_once.c (__pthread_once):
Use atomic_increment instead of atomic_exchange_and_add.
* sysdeps/unix/sysv/linux/sparc/pthread_once.c (__pthread_once):
diff --git a/nptl/DESIGN-barrier.txt b/nptl/DESIGN-barrier.txt
index b0fbf14fb1..23463c6b7e 100644
--- a/nptl/DESIGN-barrier.txt
+++ b/nptl/DESIGN-barrier.txt
@@ -37,7 +37,7 @@ pthread_barrier_wait(barrier_t *barrier)
} while (event == barrier->curr_event);
}
- if (atomic_exchange_and_add (barrier->left, 1) == barrier->init_count - 1)
+ if (atomic_increment_val (barrier->left) == barrier->init_count)
lll_unlock(barrier->lock);
return result;
diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h b/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
index aa993b9a58..226aaafdce 100644
--- a/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
+++ b/nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
@@ -26,6 +26,12 @@
#if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
+# ifdef HAVE_ASM_GLOBAL_DOT_NAME
+# define DASHDASHPFX(str) .__##str
+# else
+# define DASHDASHPFX(str) __##str
+# endif
+
# undef PSEUDO
# define PSEUDO(name, syscall_name, args) \
.section ".text"; \
@@ -33,12 +39,12 @@
cfi_startproc; \
SINGLE_THREAD_P; \
bne- .Lpseudo_cancel; \
- .type .__##syscall_name##_nocancel,@function; \
- .globl .__##syscall_name##_nocancel; \
- .__##syscall_name##_nocancel: \
+ .type DASHDASHPFX(syscall_name##_nocancel),@function; \
+ .globl DASHDASHPFX(syscall_name##_nocancel); \
+ DASHDASHPFX(syscall_name##_nocancel): \
DO_CALL (SYS_ify (syscall_name)); \
PSEUDO_RET; \
- .size .__##syscall_name##_nocancel,.-.__##syscall_name##_nocancel; \
+ .size DASHDASHPFX(syscall_name##_nocancel),.-DASHDASHPFX(syscall_name##_nocancel); \
.Lpseudo_cancel: \
stdu 1,-128(1); \
cfi_adjust_cfa_offset (128); \
diff --git a/sysdeps/powerpc/powerpc64/configure b/sysdeps/powerpc/powerpc64/configure
new file mode 100644
index 0000000000..9075a5c8c4
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/configure
@@ -0,0 +1,68 @@
+# This file is generated from configure.in by Autoconf. DO NOT EDIT!
+ # Local configure fragment for sysdeps/powerpc/powerpc64.
+
+# The Aix ld uses global .symbol_names instead of symbol_names
+# and unfortunately early Linux PPC64 linkers use it as well.
+echo "$as_me:$LINENO: checking for support for omitting dot symbols" >&5
+echo $ECHO_N "checking for support for omitting dot symbols... $ECHO_C" >&6
+if test "${libc_cv_omit_dot_syms+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ libc_cv_omit_dot_syms=no
+echo 'void foo (void) {}' > conftest.c
+if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -S conftest.c -o conftest.s 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ if grep -w '\.foo' conftest.s > /dev/null; then
+ :
+ else
+ libc_cv_omit_dot_syms=yes
+ fi
+fi
+rm -f conftest.c conftest.s
+
+fi
+echo "$as_me:$LINENO: result: $libc_cv_omit_dot_syms" >&5
+echo "${ECHO_T}$libc_cv_omit_dot_syms" >&6
+if test x$libc_cv_omit_dot_syms != xyes; then
+ cat >>confdefs.h <<\_ACEOF
+#define HAVE_ASM_GLOBAL_DOT_NAME 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for linker support for overlapping .opd entries" >&5
+echo $ECHO_N "checking for linker support for overlapping .opd entries... $ECHO_C" >&6
+if test "${libc_cv_overlapping_opd+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ libc_cv_overlapping_opd=no
+echo 'void foo (void) {}' > conftest.c
+if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -S conftest.c -o conftest.s 1>&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ if grep '\.TOC\.@tocbase' conftest.s > /dev/null; then
+ if grep '\.TOC\.@tocbase[ ]*,[ ]*0' conftest.s > /dev/null; then
+ :
+ else
+ libc_cv_overlapping_opd=yes
+ fi
+ fi
+fi
+rm -f conftest.c conftest.s
+
+fi
+echo "$as_me:$LINENO: result: $libc_cv_overlapping_opd" >&5
+echo "${ECHO_T}$libc_cv_overlapping_opd" >&6
+if test x$libc_cv_overlapping_opd = xyes; then
+ cat >>confdefs.h <<\_ACEOF
+#define USE_PPC64_OVERLAPPING_OPD 1
+_ACEOF
+
+fi
diff --git a/sysdeps/powerpc/powerpc64/configure.in b/sysdeps/powerpc/powerpc64/configure.in
new file mode 100644
index 0000000000..67aac663d8
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/configure.in
@@ -0,0 +1,42 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/powerpc/powerpc64.
+
+# The Aix ld uses global .symbol_names instead of symbol_names
+# and unfortunately early Linux PPC64 linkers use it as well.
+AC_CACHE_CHECK(for support for omitting dot symbols,
+libc_cv_omit_dot_syms, [dnl
+libc_cv_omit_dot_syms=no
+echo 'void foo (void) {}' > conftest.c
+if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then
+ if grep -w '\.foo' conftest.s > /dev/null; then
+ :
+ else
+ libc_cv_omit_dot_syms=yes
+ fi
+fi
+rm -f conftest.c conftest.s
+])
+if test x$libc_cv_omit_dot_syms != xyes; then
+ AC_DEFINE(HAVE_ASM_GLOBAL_DOT_NAME)
+fi
+
+AC_CACHE_CHECK(for linker support for overlapping .opd entries,
+libc_cv_overlapping_opd, [dnl
+libc_cv_overlapping_opd=no
+echo 'void foo (void) {}' > conftest.c
+if AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS -S conftest.c -o conftest.s 1>&AS_MESSAGE_LOG_FD); then
+changequote(,)dnl
+ if grep '\.TOC\.@tocbase' conftest.s > /dev/null; then
+ if grep '\.TOC\.@tocbase[ ]*,[ ]*0' conftest.s > /dev/null; then
+ :
+ else
+ libc_cv_overlapping_opd=yes
+ fi
+ fi
+changequote([,])dnl
+fi
+rm -f conftest.c conftest.s
+])
+if test x$libc_cv_overlapping_opd = xyes; then
+ AC_DEFINE(USE_PPC64_OVERLAPPING_OPD)
+fi
diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h
index bcaa20049d..3fcf77df71 100644
--- a/sysdeps/powerpc/powerpc64/dl-machine.h
+++ b/sysdeps/powerpc/powerpc64/dl-machine.h
@@ -27,6 +27,7 @@
#include <assert.h>
#include <sys/param.h>
#include <dl-tls.h>
+#include <sysdep.h>
/* Translate a processor specific dynamic tag to the index
in l_info array. */
@@ -117,16 +118,15 @@ elf_machine_dynamic (void)
#define TRAMPOLINE_TEMPLATE(tramp_name, fixup_name) \
asm (".section \".text\"\n" \
" .align 2\n" \
-" .globl ." #tramp_name "\n" \
-" .type ." #tramp_name ",@function\n" \
+" .type " BODY_PREFIX #tramp_name ",@function\n" \
" .section \".opd\",\"aw\"\n" \
" .align 3\n" \
" .globl " #tramp_name "\n" \
-" .size " #tramp_name ",24\n" \
+" " ENTRY_2(tramp_name) "\n" \
#tramp_name ":\n" \
-" .quad ." #tramp_name ",.TOC.@tocbase,0\n" \
+" " OPD_ENT(tramp_name) "\n" \
" .previous\n" \
-"." #tramp_name ":\n" \
+BODY_PREFIX #tramp_name ":\n" \
/* We need to save the registers used to pass parameters, ie. r3 thru \
r10; the registers are saved in a stack frame. */ \
" stdu 1,-128(1)\n" \
@@ -141,14 +141,14 @@ elf_machine_dynamic (void)
" std 7,80(1)\n" \
" mflr 0\n" \
" std 8,88(1)\n" \
-/* Store the LR in the LR Save area of the previous frame. */ \
+/* Store the LR in the LR Save area of the previous frame. */ \
" std 0,128+16(1)\n" \
" mfcr 0\n" \
" std 9,96(1)\n" \
" std 10,104(1)\n" \
-/* I'm almost certain we don't have to save cr... be safe. */ \
+/* I'm almost certain we don't have to save cr... be safe. */ \
" std 0,8(1)\n" \
-" bl ." #fixup_name "\n" \
+" bl " DOT_PREFIX #fixup_name "\n" \
/* Put the registers back. */ \
" ld 0,128+16(1)\n" \
" ld 10,104(1)\n" \
@@ -174,13 +174,13 @@ elf_machine_dynamic (void)
".LT_" #tramp_name ":\n" \
" .long 0\n" \
" .byte 0x00,0x0c,0x24,0x40,0x00,0x00,0x00,0x00\n" \
-" .long .LT_" #tramp_name "-."#tramp_name "\n" \
+" .long .LT_" #tramp_name "-" BODY_PREFIX #tramp_name "\n" \
" .short .LT_" #tramp_name "_name_end-.LT_" #tramp_name "_name_start\n" \
".LT_" #tramp_name "_name_start:\n" \
" .ascii \"" #tramp_name "\"\n" \
".LT_" #tramp_name "_name_end:\n" \
" .align 2\n" \
-" .size ." #tramp_name ",. - ." #tramp_name "\n" \
+" " END_2(tramp_name) "\n" \
" .previous");
#ifndef PROF
@@ -210,16 +210,15 @@ elf_machine_dynamic (void)
#define RTLD_START \
asm (".section \".text\"\n" \
" .align 2\n" \
-" .globl ._start\n" \
-" .type ._start,@function\n" \
+" .type " BODY_PREFIX "_start,@function\n" \
" .section \".opd\",\"aw\"\n" \
" .align 3\n" \
" .globl _start\n" \
-" .size _start,24\n" \
+" " ENTRY_2(_start) "\n" \
"_start:\n" \
-" .quad ._start,.TOC.@tocbase,0\n" \
+" " OPD_ENT(_start) "\n" \
" .previous\n" \
-"._start:\n" \
+BODY_PREFIX "_start:\n" \
/* We start with the following on the stack, from top: \
argc (4 bytes); \
arguments for program (terminated by NULL); \
@@ -229,24 +228,24 @@ elf_machine_dynamic (void)
" li 4,0\n" \
" stdu 4,-128(1)\n" \
/* Call _dl_start with one parameter pointing at argc. */ \
-" bl ._dl_start\n" \
+" bl " DOT_PREFIX "_dl_start\n" \
" nop\n" \
/* Transfer control to _dl_start_user! */ \
-" b ._dl_start_user\n" \
-".LT__start:\n" \
-" .long 0\n" \
+" b " DOT_PREFIX "_dl_start_user\n" \
+".LT__start:\n" \
+" .long 0\n" \
" .byte 0x00,0x0c,0x24,0x40,0x00,0x00,0x00,0x00\n" \
-" .long .LT__start-._start\n" \
+" .long .LT__start-" BODY_PREFIX "_start\n" \
" .short .LT__start_name_end-.LT__start_name_start\n" \
".LT__start_name_start:\n" \
" .ascii \"_start\"\n" \
".LT__start_name_end:\n" \
" .align 2\n" \
-" .size ._start,.-._start\n" \
+" " END_2(_start) "\n" \
" .globl _dl_start_user\n" \
" .section \".opd\",\"aw\"\n" \
"_dl_start_user:\n" \
-" .quad ._dl_start_user, .TOC.@tocbase, 0\n" \
+" " OPD_ENT(_dl_start_user) "\n" \
" .previous\n" \
" .section \".toc\",\"aw\"\n" \
DL_STARTING_UP_DEF \
@@ -259,20 +258,20 @@ DL_STARTING_UP_DEF \
".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. \
- The ELF ABI doesn't say anything about parameters for these, \
- so we just pass argc, argv, and the environment. \
- Changing these is strongly discouraged (not least because argc is \
- passed by value!). */ \
-"._dl_start_user:\n" \
+" .type " BODY_PREFIX "_dl_start_user,@function\n" \
+" " ENTRY_2(_dl_start_user) "\n" \
+/* Now, we do our main work of calling initialisation procedures. \
+ The ELF ABI doesn't say anything about parameters for these, \
+ so we just pass argc, argv, and the environment. \
+ Changing these is strongly discouraged (not least because argc is \
+ passed by value!). */ \
+BODY_PREFIX "_dl_start_user:\n" \
/* 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,.LC__rtld_global@toc(2)\n" \
-" ld 29,.LC__dl_argc@toc(2)\n" \
-" ld 27,.LC__dl_argv@toc(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" \
@@ -280,7 +279,7 @@ DL_STARTING_UP_DEF \
" sldi 6,4,3\n" \
" add 6,5,6\n" \
" addi 6,6,8\n" \
-" bl ._dl_init\n" \
+" bl " DOT_PREFIX "_dl_init\n" \
" nop\n" \
/* Now, to conform to the ELF ABI, we have to: \
Pass argc (actually _dl_argc) in r3; */ \
@@ -305,7 +304,7 @@ DL_STARTING_UP_DEF \
linked statically, which linux will call with argc on top of the \
stack which will hopefully never be zero, and a dynamically linked \
program which will always have a NULL on the top of the stack. \
- Take the opportunity to clear LR, so anyone who accidentally \
+ Take the opportunity to clear LR, so anyone who accidentally \
returns from _start gets SEGV. Also clear the next few words of \
the stack. */ \
" li 31,0\n" \
@@ -315,23 +314,23 @@ DL_STARTING_UP_DEF \
" std 31,16(1)\n" \
" std 31,24(1)\n" \
/* Now, call the start function descriptor at r30... */ \
-" .globl ._dl_main_dispatch\n" \
-"._dl_main_dispatch:\n" \
+" .globl ._dl_main_dispatch\n" \
+"._dl_main_dispatch:\n" \
" ld 0,0(30)\n" \
" ld 2,8(30)\n" \
" mtctr 0\n" \
" ld 11,16(30)\n" \
" bctr\n" \
-".LT__dl_start_user:\n" \
+".LT__dl_start_user:\n" \
" .long 0\n" \
" .byte 0x00,0x0c,0x24,0x40,0x00,0x00,0x00,0x00\n" \
-" .long .LT__dl_start_user-._dl_start_user\n" \
+" .long .LT__dl_start_user-" BODY_PREFIX "_dl_start_user\n" \
" .short .LT__dl_start_user_name_end-.LT__dl_start_user_name_start\n" \
".LT__dl_start_user_name_start:\n" \
" .ascii \"_dl_start_user\"\n" \
".LT__dl_start_user_name_end:\n" \
" .align 2\n" \
-" .size ._dl_start_user,.-._dl_start_user\n" \
+" " END_2(_dl_start_user) "\n" \
" .previous");
/* Nonzero iff TYPE should not be allowed to resolve to one of
diff --git a/sysdeps/powerpc/powerpc64/sysdep.h b/sysdeps/powerpc/powerpc64/sysdep.h
index 29c1c2c36c..4420a6dfac 100644
--- a/sysdeps/powerpc/powerpc64/sysdep.h
+++ b/sysdeps/powerpc/powerpc64/sysdep.h
@@ -1,5 +1,5 @@
/* Assembly macros for 64-bit PowerPC.
- Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -19,9 +19,10 @@
#include <sysdeps/powerpc/sysdep.h>
+#ifdef __ELF__
+
#ifdef __ASSEMBLER__
-#ifdef __ELF__
/* If compiled for profiling, call `_mcount' at the start of each function.
see ppc-mcount.S for more details. */
#ifdef PROF
@@ -29,48 +30,70 @@
to locate our caller and so it can restore it; so store one just
for its benefit. */
#ifdef SYSV_ELF_PROFILING
-#define CALL_MCOUNT \
- .pushsection; \
- .section ".data"; \
- .align ALIGNARG(2); \
-__mcount: \
- .long 0; \
- .previous; \
- .section ".toc","aw"; \
-.LC__mcount:; \
- .tc __mcount[TC],__mcount; \
- .previous; \
- mflr r0; \
- std r0,16(r1); \
- ld r0,.LC__mcount@toc(r2); \
+#define CALL_MCOUNT \
+ .pushsection; \
+ .section ".data"; \
+ .align ALIGNARG(2); \
+__mcount: \
+ .long 0; \
+ .previous; \
+ .section ".toc","aw"; \
+.LC__mcount:; \
+ .tc __mcount[TC],__mcount; \
+ .previous; \
+ mflr r0; \
+ std r0,16(r1); \
+ ld r0,.LC__mcount@toc(r2); \
bl JUMPTARGET(_mcount);
#else /* SYSV_ELF_PROFILING */
-#define CALL_MCOUNT \
- mflr r0; \
- std r0,16(r1); \
+#define CALL_MCOUNT \
+ mflr r0; \
+ std r0,16(r1); \
bl JUMPTARGET(_mcount);
#endif /* SYSV_ELF_PROFILING */
#else /* PROF */
#define CALL_MCOUNT /* Do nothing. */
#endif /* PROF */
-#define DOT_LABEL(X) .##X
+#ifdef USE_PPC64_OVERLAPPING_OPD
+# define OPD_ENT(name) .quad BODY_LABEL (name), .TOC.@tocbase
+#else
+# define OPD_ENT(name) .quad BODY_LABEL (name), .TOC.@tocbase, 0
+#endif
-#define ENTRY(name) \
- .section ".text"; \
- .align ALIGNARG(2); \
- .globl DOT_LABEL(name); \
- .type DOT_LABEL(name),@function ; \
- .globl name; \
- .section ".opd","aw"; \
- .align 3; \
- .size name,24; \
-name##: ; \
- .quad DOT_LABEL(name) ; \
- .quad .TOC.@tocbase, 0; \
- .previous; \
-DOT_LABEL(name):
+#define ENTRY_1(name) \
+ .section ".text"; \
+ .type BODY_LABEL(name),@function; \
+ .globl name; \
+ .section ".opd","aw"; \
+ .align 3; \
+name##: OPD_ENT (name); \
+ .previous;
+
+#ifdef HAVE_ASM_GLOBAL_DOT_NAME
+# define DOT_LABEL(X) .##X
+# define BODY_LABEL(X) .##X
+# define ENTRY_2(name) \
+ .globl BODY_LABEL(name); \
+ ENTRY_1(name) \
+ .size name, 24;
+# define END_2(name) \
+ .size BODY_LABEL(name),.-BODY_LABEL(name);
+#else
+# define DOT_LABEL(X) X
+# define BODY_LABEL(X) .LY##X
+# define ENTRY_2(name) \
+ .type name,@function; \
+ ENTRY_1(name)
+# define END_2(name) \
+ .size name,.-BODY_LABEL(name); \
+ .size BODY_LABEL(name),.-BODY_LABEL(name);
+#endif
+#define ENTRY(name) \
+ ENTRY_2(name) \
+ .align ALIGNARG(2); \
+BODY_LABEL(name):
#define EALIGN_W_0 /* No words to insert. */
#define EALIGN_W_1 nop
@@ -82,44 +105,24 @@ DOT_LABEL(name):
#define EALIGN_W_7 EALIGN_W_6;nop
/* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes
- past a 2^align boundary. */
+ past a 2^alignt boundary. */
#ifdef PROF
#define EALIGN(name, alignt, words) \
- .section ".text"; \
- .globl DOT_LABEL(name); \
- .type DOT_LABEL(name),@function ; \
- .globl name; \
- .section ".opd","aw"; \
- .align 3; \
- .size name,24; \
-name##: ; \
- .quad DOT_LABEL(name) ; \
- .quad .TOC.@tocbase, 0; \
- .previous; \
- .align ALIGNARG(alignt); \
- EALIGN_W_##words; \
-DOT_LABEL(name): \
- CALL_MCOUNT \
- b 0f; \
- .align ALIGNARG(alignt); \
- EALIGN_W_##words; \
- 0:
+ ENTRY_2(name) \
+ .align ALIGNARG(alignt); \
+ EALIGN_W_##words; \
+BODY_LABEL(name): \
+ CALL_MCOUNT \
+ b 0f; \
+ .align ALIGNARG(alignt); \
+ EALIGN_W_##words; \
+0:
#else /* PROF */
#define EALIGN(name, alignt, words) \
- .section ".text"; \
- .globl DOT_LABEL(name); \
- .type DOT_LABEL(name),@function ; \
- .globl name; \
- .section ".opd","aw"; \
- .align 3; \
- .size name,24; \
-name##: ; \
- .quad DOT_LABEL(name) ; \
- .quad .TOC.@tocbase, 0; \
- .previous; \
- .align ALIGNARG(alignt); \
- EALIGN_W_##words; \
-DOT_LABEL(name):
+ ENTRY_2(name) \
+ .align ALIGNARG(alignt); \
+ EALIGN_W_##words; \
+BODY_LABEL(name):
#endif
/* Local labels stripped out by the linker. */
@@ -135,35 +138,35 @@ DOT_LABEL(name):
/* Support Traceback tables */
#define TB_ASM 0x000c000000000000
-#define TB_GLOBALLINK 0x0000800000000000
+#define TB_GLOBALLINK 0x0000800000000000
#define TB_IS_EPROL 0x0000400000000000
-#define TB_HAS_TBOFF 0x0000200000000000
+#define TB_HAS_TBOFF 0x0000200000000000
#define TB_INT_PROC 0x0000100000000000
#define TB_HAS_CTL 0x0000080000000000
#define TB_TOCLESS 0x0000040000000000
-#define TB_FP_PRESENT 0x0000020000000000
-#define TB_LOG_ABORT 0x0000010000000000
-#define TB_INT_HANDL 0x0000008000000000
-#define TB_NAME_PRESENT 0x0000004000000000
-#define TB_USES_ALLOCA 0x0000002000000000
+#define TB_FP_PRESENT 0x0000020000000000
+#define TB_LOG_ABORT 0x0000010000000000
+#define TB_INT_HANDL 0x0000008000000000
+#define TB_NAME_PRESENT 0x0000004000000000
+#define TB_USES_ALLOCA 0x0000002000000000
#define TB_SAVES_CR 0x0000000200000000
#define TB_SAVES_LR 0x0000000100000000
-#define TB_STORES_BC 0x0000000080000000
+#define TB_STORES_BC 0x0000000080000000
#define TB_FIXUP 0x0000000040000000
#define TB_FP_SAVED(fprs) (((fprs) & 0x3f) << 24)
#define TB_GPR_SAVED(gprs) (((fprs) & 0x3f) << 16)
#define TB_FIXEDPARMS(parms) (((parms) & 0xff) << 8)
#define TB_FLOATPARMS(parms) (((parms) & 0x7f) << 1)
-#define TB_PARMSONSTK 0x0000000000000001
+#define TB_PARMSONSTK 0x0000000000000001
-#define PPC_HIGHER(v) (((v) >> 32) & 0xffff)
-#define TB_DEFAULT TB_ASM | TB_HAS_TBOFF | TB_NAME_PRESENT
+#define PPC_HIGHER(v) (((v) >> 32) & 0xffff)
+#define TB_DEFAULT TB_ASM | TB_HAS_TBOFF | TB_NAME_PRESENT
#define TRACEBACK(name) \
LT_LABEL(name): ; \
.long 0 ; \
.quad TB_DEFAULT ; \
- .long LT_LABEL(name)-DOT_LABEL(name) ; \
+ .long LT_LABEL(name)-BODY_LABEL(name) ; \
.short LT_LABELSUFFIX(name,_name_end)-LT_LABELSUFFIX(name,_name_start) ; \
LT_LABELSUFFIX(name,_name_start): ;\
.ascii stringify(name) ; \
@@ -174,7 +177,7 @@ LT_LABELSUFFIX(name,_name_end): ; \
LT_LABEL(name): ; \
.long 0 ; \
.quad TB_DEFAULT | mask ; \
- .long LT_LABEL(name)-DOT_LABEL(name) ; \
+ .long LT_LABEL(name)-BODY_LABEL(name) ; \
.short LT_LABELSUFFIX(name,_name_end)-LT_LABELSUFFIX(name,_name_start) ; \
LT_LABELSUFFIX(name,_name_start): ;\
.ascii stringify(name) ; \
@@ -184,14 +187,13 @@ LT_LABELSUFFIX(name,_name_end): ; \
/* END generates Traceback tables */
#undef END
#define END(name) \
- TRACEBACK(name) \
- ASM_SIZE_DIRECTIVE(DOT_LABEL(name))
+ TRACEBACK(name) \
+ END_2(name)
/* This form supports more informative traceback tables */
#define END_GEN_TB(name,mask) \
TRACEBACK_MASK(name,mask) \
- ASM_SIZE_DIRECTIVE(DOT_LABEL(name))
-
+ END_2(name)
#define DO_CALL(syscall) \
li 0,syscall; \
@@ -244,10 +246,31 @@ LT_LABELSUFFIX(name,_name_end): ; \
#define PSEUDO_END_ERRVAL(name) \
END (name)
-/* Label in text section. */
-/* ppc64 function descriptors which requires . notation */
-#define C_TEXT(name) .##name
+#else /* !__ASSEMBLER__ */
-#endif /* __ELF__ */
+#ifdef USE_PPC64_OVERLAPPING_OPD
+# define OPD_ENT(name) ".quad " BODY_PREFIX #name ", .TOC.@tocbase;"
+#else
+# define OPD_ENT(name) ".quad " BODY_PREFIX #name ", .TOC.@tocbase, 0;"
+#endif
+
+#ifdef HAVE_ASM_GLOBAL_DOT_NAME
+# define DOT_PREFIX "."
+# define BODY_PREFIX "."
+# define ENTRY_2(name) \
+ ".globl " BODY_PREFIX #name ";\n" \
+ ".size " #name ", 24;"
+# define END_2(name) \
+ ".size " BODY_PREFIX #name ",.-" BODY_PREFIX #name ";"
+#else
+# define DOT_PREFIX ""
+# define BODY_PREFIX ".LY"
+# define ENTRY_2(name) ".type " #name ",@function;"
+# define END_2(name) \
+ ".size " #name ",.-" BODY_PREFIX #name ";\n" \
+ ".size " BODY_PREFIX #name ",.-" BODY_PREFIX #name ";"
+#endif
#endif /* __ASSEMBLER__ */
+
+#endif /* __ELF__ */