Update.
authorUlrich Drepper <drepper@redhat.com>
Wed, 8 Sep 2004 07:02:28 +0000 (07:02 +0000)
committerUlrich Drepper <drepper@redhat.com>
Wed, 8 Sep 2004 07:02:28 +0000 (07:02 +0000)
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.

ChangeLog
config.h.in
configure
configure.in
nptl/ChangeLog
nptl/DESIGN-barrier.txt
nptl/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h
sysdeps/powerpc/powerpc64/configure [new file with mode: 0644]
sysdeps/powerpc/powerpc64/configure.in [new file with mode: 0644]
sysdeps/powerpc/powerpc64/dl-machine.h
sysdeps/powerpc/powerpc64/sysdep.h

index 703e89b..e108e01 100644 (file)
--- 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.
index c02d691..bd990c6 100644 (file)
@@ -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
 
index 985118d..625d507 100755 (executable)
--- 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
index 3941aba..24e6cb9 100644 (file)
@@ -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}
index 6857273..f382a00 100644 (file)
@@ -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):
index b0fbf14..23463c6 100644 (file)
@@ -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;
index aa993b9..226aaaf 100644 (file)
 
 #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";                                                    \
     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 (file)
index 0000000..9075a5c
--- /dev/null
@@ -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 (file)
index 0000000..67aac66
--- /dev/null
@@ -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
index bcaa200..3fcf77d 100644 (file)
@@ -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
index 29c1c2c..4420a6d 100644 (file)
@@ -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
 
 #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
    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__ */