From 590b40f7ec801ea1b4be47112a016ed369041e64 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Wed, 8 Sep 2004 07:02:28 +0000 Subject: Update. 2004-09-07 Jakub Jelinek * 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 | 14 ++ config.h.in | 3 + configure | 10 - configure.in | 7 - nptl/ChangeLog | 3 + nptl/DESIGN-barrier.txt | 2 +- .../sysv/linux/powerpc/powerpc64/sysdep-cancel.h | 14 +- sysdeps/powerpc/powerpc64/configure | 68 +++++++ sysdeps/powerpc/powerpc64/configure.in | 42 +++++ sysdeps/powerpc/powerpc64/dl-machine.h | 79 ++++---- sysdeps/powerpc/powerpc64/sysdep.h | 201 ++++++++++++--------- 11 files changed, 292 insertions(+), 151 deletions(-) create mode 100644 sysdeps/powerpc/powerpc64/configure create mode 100644 sysdeps/powerpc/powerpc64/configure.in diff --git a/ChangeLog b/ChangeLog index 703e89b683..e108e01ef7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2004-09-07 Jakub Jelinek + + * 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 * 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 < + * 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 #include #include +#include /* 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 +#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__ */ -- cgit v1.2.3