This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: powerpc64 linux dot symbols
Here is the current patch. This incorporates Jakub's fixes, and makes
dot-symbol output selectable via -mcall-aixdesc and -mcall-linux.
* config/rs6000/linux64.h (DOT_SYMBOLS): Define.
(CRT_CALL_STATIC_FUNCTION): Define !DOT_SYMBOLS version.
(ASM_DECLARE_FUNCTION_SIZE): Modify for !DOT_SYMBOLS.
(ASM_OUTPUT_SOURCE_LINE, DBX_OUTPUT_BRAC, DBX_OUTPUT_NFUN): Likewise.
(RS6000_ABI_NAME): Define as "linux".
(SUBSUBTARGET_OVERRIDE_OPTIONS): Set dot_symbols.
* config/rs6000/sysv4.h (SUBTARGET_OVERRIDE_OPTIONS): Select
ABI_AIX when rs6000_abi_name is "linux" and TARGET_64BIT.
* config/rs6000/rs6000-protos.h (rs6000_output_function_entry): Decl.
* config/rs6000/rs6000.c (dot_symbols): New global var.
(rs6000_output_function_entry): New function, modified for
!DOT_SYMBOLS..
(print_operand <case 'z'>): ..extracted from here.
(rs6000_assemble_visibility): Modify for !DOT_SYMBOLS.
(rs6000_output_function_epilogue): Likewise.
(rs6000_elf_declare_function_name): Likewise.
* config/rs6000/rs6000.h (DOT_SYMBOLS): Define.
(ASM_WEAKEN_DECL, ASM_OUTPUT_DEF_FROM_DECLS): Modify for !DOT_SYMBOLS.
* configure.ac (HAVE_LD_NO_DOT_SYMS): Add new AC_DEFINE.
* configure: Regenerate.
* config.in: Regenerate.
diff -urp -xCVS -x'*~' gcc-virgin/gcc/config/rs6000/linux64.h gcc-dot/gcc/config/rs6000/linux64.h
--- gcc-virgin/gcc/config/rs6000/linux64.h 2004-07-26 16:31:41.000000000 +0930
+++ gcc-dot/gcc/config/rs6000/linux64.h 2004-08-20 13:40:39.926927090 +0930
@@ -50,6 +50,13 @@
#undef TARGET_AIX
#define TARGET_AIX TARGET_64BIT
+#ifdef HAVE_LD_NO_DOT_SYMS
+/* New ABI uses a local sym for the function entry point. */
+extern int dot_symbols;
+#undef DOT_SYMBOLS
+#define DOT_SYMBOLS dot_symbols
+#endif
+
#undef PROCESSOR_DEFAULT64
#define PROCESSOR_DEFAULT64 PROCESSOR_PPC630
@@ -57,7 +64,7 @@
#define TARGET_RELOCATABLE (!TARGET_64BIT && (target_flags & MASK_RELOCATABLE))
#undef RS6000_ABI_NAME
-#define RS6000_ABI_NAME (TARGET_64BIT ? "aixdesc" : "sysv")
+#define RS6000_ABI_NAME "linux"
#define INVALID_64BIT "-m%s not supported in this configuration"
#define INVALID_32BIT INVALID_64BIT
@@ -75,6 +82,7 @@
rs6000_current_abi = ABI_AIX; \
error (INVALID_64BIT, "call"); \
} \
+ dot_symbols = !strcmp (rs6000_abi_name, "aixdesc"); \
if (target_flags & MASK_RELOCATABLE) \
{ \
target_flags &= ~MASK_RELOCATABLE; \
@@ -392,11 +400,19 @@
object files, each potentially with a different TOC pointer. For
that reason, place a nop after the call so that the linker can
restore the TOC pointer if a TOC adjusting call stub is needed. */
+#if DOT_SYMBOLS
#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \
asm (SECTION_OP "\n" \
" bl ." #FUNC "\n" \
" nop\n" \
" .previous");
+#else
+#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \
+ asm (SECTION_OP "\n" \
+" bl " #FUNC "\n" \
+" nop\n" \
+" .previous");
+#endif
#endif
/* FP save and restore routines. */
@@ -421,13 +437,11 @@
if (!flag_inhibit_size_directive) \
{ \
fputs ("\t.size\t", (FILE)); \
- if (TARGET_64BIT) \
+ if (TARGET_64BIT && DOT_SYMBOLS) \
putc ('.', (FILE)); \
assemble_name ((FILE), (FNAME)); \
fputs (",.-", (FILE)); \
- if (TARGET_64BIT) \
- putc ('.', (FILE)); \
- assemble_name ((FILE), (FNAME)); \
+ rs6000_output_function_entry (FILE, FNAME); \
putc ('\n', (FILE)); \
} \
} \
@@ -471,14 +485,13 @@
do \
{ \
char temp[256]; \
+ const char *s; \
ASM_GENERATE_INTERNAL_LABEL (temp, "LM", COUNTER); \
fprintf (FILE, "\t.stabn 68,0,%d,", LINE); \
assemble_name (FILE, temp); \
putc ('-', FILE); \
- if (TARGET_64BIT) \
- putc ('.', FILE); \
- assemble_name (FILE, \
- XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));\
+ s = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); \
+ rs6000_output_function_entry (FILE, s); \
putc ('\n', FILE); \
(*targetm.asm_out.internal_label) (FILE, "LM", COUNTER); \
} \
@@ -488,19 +501,20 @@ while (0)
#define DBX_OUTPUT_BRAC(FILE, NAME, BRAC) \
do \
{ \
- const char *flab; \
+ const char *s; \
fprintf (FILE, "%s%d,0,0,", ASM_STABN_OP, BRAC); \
assemble_name (FILE, NAME); \
putc ('-', FILE); \
if (current_function_func_begin_label != NULL_TREE) \
- flab = IDENTIFIER_POINTER (current_function_func_begin_label); \
+ { \
+ s = IDENTIFIER_POINTER (current_function_func_begin_label); \
+ assemble_name (FILE, s); \
+ } \
else \
{ \
- if (TARGET_64BIT) \
- putc ('.', FILE); \
- flab = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); \
+ s = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); \
+ rs6000_output_function_entry (FILE, s); \
} \
- assemble_name (FILE, flab); \
putc ('\n', FILE); \
} \
while (0)
@@ -512,12 +526,12 @@ while (0)
#define DBX_OUTPUT_NFUN(FILE, LSCOPE, DECL) \
do \
{ \
+ const char *s; \
fprintf (FILE, "%s\"\",%d,0,0,", ASM_STABS_OP, N_FUN); \
assemble_name (FILE, LSCOPE); \
putc ('-', FILE); \
- if (TARGET_64BIT) \
- putc ('.', FILE); \
- assemble_name (FILE, XSTR (XEXP (DECL_RTL (DECL), 0), 0)); \
+ s = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); \
+ rs6000_output_function_entry (FILE, s); \
putc ('\n', FILE); \
} \
while (0)
diff -urp -xCVS -x'*~' gcc-virgin/gcc/config/rs6000/rs6000-protos.h gcc-dot/gcc/config/rs6000/rs6000-protos.h
--- gcc-virgin/gcc/config/rs6000/rs6000-protos.h 2004-08-19 10:06:36.000000000 +0930
+++ gcc-dot/gcc/config/rs6000/rs6000-protos.h 2004-08-20 12:04:51.358068189 +0930
@@ -113,6 +113,7 @@ extern enum reg_class secondary_reload_c
extern int ccr_bit (rtx, int);
extern int extract_MB (rtx);
extern int extract_ME (rtx);
+extern void rs6000_output_function_entry (FILE *, const char *);
extern void print_operand (FILE *, rtx, int);
extern void print_operand_address (FILE *, rtx);
extern enum rtx_code rs6000_reverse_condition (enum machine_mode,
diff -urp -xCVS -x'*~' gcc-virgin/gcc/config/rs6000/rs6000.c gcc-dot/gcc/config/rs6000/rs6000.c
--- gcc-virgin/gcc/config/rs6000/rs6000.c 2004-08-20 11:19:55.187713346 +0930
+++ gcc-dot/gcc/config/rs6000/rs6000.c 2004-08-20 13:40:14.825913549 +0930
@@ -213,6 +213,9 @@ enum rs6000_abi rs6000_current_abi;
/* ABI string from -mabi= option. */
const char *rs6000_abi_string;
+/* Whether to use variant of AIX ABI for PowerPC64 Linux. */
+int dot_symbols;
+
/* Debug flags */
const char *rs6000_debug_name;
int rs6000_debug_stack; /* debug stack applications */
@@ -9791,6 +9794,36 @@ rs6000_get_some_local_dynamic_name_1 (rt
return 0;
}
+/* Write out a function code label. */
+
+void
+rs6000_output_function_entry (FILE *file, const char *fname)
+{
+ if (fname[0] != '.')
+ {
+ switch (DEFAULT_ABI)
+ {
+ default:
+ abort ();
+
+ case ABI_AIX:
+ if (DOT_SYMBOLS)
+ putc ('.', file);
+ else
+ ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
+ break;
+
+ case ABI_V4:
+ case ABI_DARWIN:
+ break;
+ }
+ }
+ if (TARGET_AIX)
+ RS6000_OUTPUT_BASENAME (file, fname);
+ else
+ assemble_name (file, fname);
+}
+
/* Print an operand. Recognize special options, documented below. */
#if TARGET_ELF
@@ -10323,23 +10356,7 @@ print_operand (FILE *file, rtx x, int co
if (SYMBOL_REF_DECL (x))
mark_decl_referenced (SYMBOL_REF_DECL (x));
- if (XSTR (x, 0)[0] != '.')
- {
- switch (DEFAULT_ABI)
- {
- default:
- abort ();
-
- case ABI_AIX:
- putc ('.', file);
- break;
-
- case ABI_V4:
- case ABI_DARWIN:
- break;
- }
- }
- /* For macho, we need to check it see if we need a stub. */
+ /* For macho, check to see if we need a stub. */
if (TARGET_MACHO)
{
const char *name = XSTR (x, 0);
@@ -10350,10 +10367,10 @@ print_operand (FILE *file, rtx x, int co
#endif
assemble_name (file, name);
}
- else if (TARGET_AIX)
- RS6000_OUTPUT_BASENAME (file, XSTR (x, 0));
- else
+ else if (!DOT_SYMBOLS)
assemble_name (file, XSTR (x, 0));
+ else
+ rs6000_output_function_entry (file, XSTR (x, 0));
return;
case 'Z':
@@ -10609,7 +10626,9 @@ rs6000_assemble_visibility (tree decl, i
{
/* Functions need to have their entry point symbol visibility set as
well as their descriptor symbol visibility. */
- if (DEFAULT_ABI == ABI_AIX && TREE_CODE (decl) == FUNCTION_DECL)
+ if (DEFAULT_ABI == ABI_AIX
+ && DOT_SYMBOLS
+ && TREE_CODE (decl) == FUNCTION_DECL)
{
static const char * const visibility_types[] = {
NULL, "internal", "hidden", "protected"
@@ -14219,17 +14238,12 @@ rs6000_output_function_epilogue (FILE *f
/* Offset from start of code to tb table. */
fputs ("\t.long ", file);
ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
-#if TARGET_AIX
- RS6000_OUTPUT_BASENAME (file, fname);
-#else
- assemble_name (file, fname);
-#endif
- fputs ("-.", file);
-#if TARGET_AIX
- RS6000_OUTPUT_BASENAME (file, fname);
-#else
- assemble_name (file, fname);
-#endif
+ if (TARGET_AIX)
+ RS6000_OUTPUT_BASENAME (file, fname);
+ else
+ assemble_name (file, fname);
+ putc ('-', file);
+ rs6000_output_function_entry (file, fname);
putc ('\n', file);
/* Interrupt handler mask. */
@@ -16802,22 +16816,27 @@ rs6000_elf_declare_function_name (FILE *
fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
ASM_OUTPUT_LABEL (file, name);
fputs (DOUBLE_INT_ASM_OP, file);
- putc ('.', file);
- assemble_name (file, name);
- fputs (",.TOC.@tocbase,0\n\t.previous\n\t.size\t", file);
- assemble_name (file, name);
- fputs (",24\n\t.type\t.", file);
- assemble_name (file, name);
- fputs (",@function\n", file);
- if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
+ rs6000_output_function_entry (file, name);
+ fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
+ if (DOT_SYMBOLS)
{
- fputs ("\t.globl\t.", file);
+ fputs ("\t.size\t", file);
assemble_name (file, name);
- putc ('\n', file);
+ fputs (",24\n\t.type\t.", file);
+ assemble_name (file, name);
+ fputs (",@function\n", file);
+ if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
+ {
+ fputs ("\t.globl\t.", file);
+ assemble_name (file, name);
+ putc ('\n', file);
+ }
}
+ else
+ ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
- putc ('.', file);
- ASM_OUTPUT_LABEL (file, name);
+ rs6000_output_function_entry (file, name);
+ fputs (":\n", file);
return;
}
diff -urp -xCVS -x'*~' gcc-virgin/gcc/config/rs6000/rs6000.h gcc-dot/gcc/config/rs6000/rs6000.h
--- gcc-virgin/gcc/config/rs6000/rs6000.h 2004-08-19 10:06:39.000000000 +0930
+++ gcc-dot/gcc/config/rs6000/rs6000.h 2004-08-20 12:04:52.645863795 +0930
@@ -40,6 +40,10 @@
#define TARGET_AIX 0
#endif
+/* Control whether function entry points use a "dot" symbol when
+ ABI_AIX. */
+#define DOT_SYMBOLS 1
+
/* Default string to use for cpu if not specified. */
#ifndef TARGET_CPU_DEFAULT
#define TARGET_CPU_DEFAULT ((char *)0)
@@ -2246,9 +2250,9 @@ extern int toc_initialized;
do \
{ \
fputs ("\t.weak\t", (FILE)); \
- RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \
+ RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \
if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL \
- && DEFAULT_ABI == ABI_AIX) \
+ && DEFAULT_ABI == ABI_AIX && DOT_SYMBOLS) \
{ \
if (TARGET_XCOFF) \
fputs ("[DS]", (FILE)); \
@@ -2260,7 +2264,7 @@ extern int toc_initialized;
{ \
ASM_OUTPUT_DEF ((FILE), (NAME), (VAL)); \
if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL \
- && DEFAULT_ABI == ABI_AIX) \
+ && DEFAULT_ABI == ABI_AIX && DOT_SYMBOLS) \
{ \
fputs ("\t.set\t.", (FILE)); \
RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \
@@ -2281,7 +2285,7 @@ extern int toc_initialized;
const char *alias = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \
const char *name = IDENTIFIER_POINTER (TARGET); \
if (TREE_CODE (DECL) == FUNCTION_DECL \
- && DEFAULT_ABI == ABI_AIX) \
+ && DEFAULT_ABI == ABI_AIX && DOT_SYMBOLS) \
{ \
if (TREE_PUBLIC (DECL)) \
{ \
diff -urp -xCVS -x'*~' gcc-virgin/gcc/config/rs6000/sysv4.h gcc-dot/gcc/config/rs6000/sysv4.h
--- gcc-virgin/gcc/config/rs6000/sysv4.h 2004-05-07 11:27:14.000000000 +0930
+++ gcc-dot/gcc/config/rs6000/sysv4.h 2004-08-20 13:40:42.091583305 +0930
@@ -194,7 +194,12 @@ do { \
else if (!strcmp (rs6000_abi_name, "freebsd")) \
rs6000_current_abi = ABI_V4; \
else if (!strcmp (rs6000_abi_name, "linux")) \
- rs6000_current_abi = ABI_V4; \
+ { \
+ if (TARGET_64BIT) \
+ rs6000_current_abi = ABI_AIX; \
+ else \
+ rs6000_current_abi = ABI_V4; \
+ } \
else if (!strcmp (rs6000_abi_name, "gnu")) \
rs6000_current_abi = ABI_V4; \
else if (!strcmp (rs6000_abi_name, "netbsd")) \
diff -urp -xCVS -x'*~' gcc-virgin/gcc/configure.ac gcc-dot/gcc/configure.ac
--- gcc-virgin/gcc/configure.ac 2004-08-18 12:52:46.000000000 +0930
+++ gcc-dot/gcc/configure.ac 2004-08-20 12:04:28.534690610 +0930
@@ -2845,6 +2845,47 @@ if test x"$gcc_cv_ld_as_needed" = xyes;
[Define if your linker supports --as-needed and --no-as-needed options.])
fi
+case "$target" in
+ powerpc64*-*-linux*)
+ AC_CACHE_CHECK(linker support for omitting dot symbols,
+ gcc_cv_ld_no_dot_syms,
+ [gcc_cv_ld_no_dot_syms=no
+ if test $in_tree_ld = yes ; then
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 16 -o "$gcc_cv_gld_major_version" -gt 2; then
+ gcc_cv_ld_no_dot_syms=yes
+ fi
+ elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x ; then
+ cat > conftest1.s <<EOF
+ .text
+ bl .foo
+EOF
+ cat > conftest2.s <<EOF
+ .section ".opd","aw"
+ .align 3
+ .globl foo
+ .type foo,@function
+foo:
+ .quad .LEfoo,.TOC.@tocbase,0
+ .text
+.LEfoo:
+ blr
+ .size foo,.-.LEfoo
+EOF
+ if $gcc_cv_as -a64 -o conftest1.o conftest1.s > /dev/null 2>&1 \
+ && $gcc_cv_as -a64 -o conftest2.o conftest2.s > /dev/null 2>&1 \
+ && $gcc_cv_ld -melf64ppc -o conftest conftest1.o conftest2.o > /dev/null 2>&1; then
+ gcc_cv_ld_no_dot_syms=yes
+ fi
+ rm -f conftest conftest1.o conftest2.o conftest1.s conftest2.s
+ fi
+ ])
+ if test x"$gcc_cv_ld_no_dot_syms" = xyes; then
+ AC_DEFINE(HAVE_LD_NO_DOT_SYMS, 1,
+ [Define if your PowerPC64 linker only needs function descriptor syms.])
+ fi
+ ;;
+esac
+
if test x$with_sysroot = x && test x$host = x$target \
&& test "$prefix" != "/usr" && test "x$prefix" != "x$local_prefix" ; then
AC_DEFINE_UNQUOTED(PREFIX_INCLUDE_DIR, "$prefix/include",
--
Alan Modra
IBM OzLabs - Linux Technology Centre