Hi, this is the first part of patch I comitted, changing the output machinery. It has fix for the ifunc "attribute".
Honza Index: ChangeLog =================================================================== --- ChangeLog (revision 212393) +++ ChangeLog (working copy) @@ -1,3 +1,14 @@ +2014-07-08 Jan Hubicka <hubi...@ucw.cz> + + * rs6000/rs6000-protos.h (rs6000_xcoff_declare_object_name): Declare. + * rs6000/rs6000.c: Inline output of .set instruction. + (declare_alias_data): New struct. + (rs6000_declare_alias): New function. + (rs6000_xcoff_declare_function_name): Use it. + (rs6000_xcoff_declare_object_name): New function. + * config/rs6000/xcoff.h: Define ASM_DECLARE_OBJECT_NAME. + (ASM_OUTPUT_DEF): Turn to empty definition. + 2014-07-08 Trevor Saunders <tsaund...@mozilla.com> PR bootstrap/61679 Index: config/rs6000/rs6000-protos.h =================================================================== --- config/rs6000/rs6000-protos.h (revision 212393) +++ config/rs6000/rs6000-protos.h (working copy) @@ -165,6 +165,7 @@ extern int function_ok_for_sibcall (tree); extern int rs6000_reg_parm_stack_space (tree, bool); extern void rs6000_xcoff_declare_function_name (FILE *, const char *, tree); +extern void rs6000_xcoff_declare_object_name (FILE *, const char *, tree); extern void rs6000_elf_declare_function_name (FILE *, const char *, tree); extern bool rs6000_elf_in_small_data_p (const_tree); #ifdef ARGS_SIZE_RTX Index: config/rs6000/rs6000.c =================================================================== --- config/rs6000/rs6000.c (revision 212393) +++ config/rs6000/rs6000.c (working copy) @@ -29158,7 +29158,11 @@ sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC, SYMBOL_REF_BLOCK_OFFSET (symbol)); - ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer); + fprintf (asm_out_file, "%s", SET_ASM_OP); + RS6000_OUTPUT_BASENAME (asm_out_file, XSTR (symbol, 0)); + fprintf (asm_out_file, ","); + RS6000_OUTPUT_BASENAME (asm_out_file, buffer); + fprintf (asm_out_file, "\n"); } static void @@ -29455,6 +29459,85 @@ asm_out_file); } +struct declare_alias_data +{ + FILE *file; + bool function_descriptor; +}; + +/* Declare alias N. A helper function for for_node_and_aliases. */ + +static bool +rs6000_declare_alias (struct symtab_node *n, void *d) +{ + struct declare_alias_data *data = (struct declare_alias_data *)d; + /* Main symbol is output specially, because varasm machinery does part of + the job for us - we do not need to declare .globl/lglobs and such. */ + if (!n->alias || n->weakref) + return false; + + if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (n->decl))) + return false; + + /* Prevent assemble_alias from trying to use .set pseudo operation + that does not behave as expected by the middle-end. */ + TREE_ASM_WRITTEN (n->decl) = true; + + const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (n->decl)); + char *buffer = (char *) alloca (strlen (name) + 2); + char *p; + int dollar_inside = 0; + + strcpy (buffer, name); + p = strchr (buffer, '$'); + while (p) { + *p = '_'; + dollar_inside++; + p = strchr (p + 1, '$'); + } + if (TREE_PUBLIC (n->decl)) + { + if (!RS6000_WEAK || !DECL_WEAK (n->decl)) + { + if (dollar_inside) { + if (data->function_descriptor) + fprintf(data->file, "\t.rename .%s,\".%s\"\n", buffer, name); + else + fprintf(data->file, "\t.rename %s,\"%s\"\n", buffer, name); + } + if (data->function_descriptor) + fputs ("\t.globl .", data->file); + else + fputs ("\t.globl ", data->file); + RS6000_OUTPUT_BASENAME (data->file, buffer); + putc ('\n', data->file); + } + else if (DECL_WEAK (n->decl) && !data->function_descriptor) + ASM_WEAKEN_DECL (data->file, n->decl, name, NULL); + } + else + { + if (dollar_inside) + { + if (data->function_descriptor) + fprintf(data->file, "\t.rename %s,\"%s\"\n", buffer, name); + else + fprintf(data->file, "\t.rename .%s,\".%s\"\n", buffer, name); + } + if (data->function_descriptor) + fputs ("\t.lglobl .", data->file); + else + fputs ("\t.lglobl ", data->file); + RS6000_OUTPUT_BASENAME (data->file, buffer); + putc ('\n', data->file); + } + if (data->function_descriptor) + fputs (".", data->file); + RS6000_OUTPUT_BASENAME (data->file, buffer); + fputs (":\n", data->file); + return false; +} + /* This macro produces the initial definition of a function name. On the RS/6000, we need to place an extra '.' in the function name and output the function descriptor. @@ -29464,14 +29547,19 @@ text_section was selected. We do have to go back to that csect, however. The third and fourth parameters to the .function pseudo-op (16 and 044) - are placeholders which no longer have any use. */ + are placeholders which no longer have any use. + Because AIX assembler's .set command has unexpected semantics, we output + all aliases as alternative labels in front of the definition. */ + void rs6000_xcoff_declare_function_name (FILE *file, const char *name, tree decl) { char *buffer = (char *) alloca (strlen (name) + 1); char *p; int dollar_inside = 0; + struct declare_alias_data data = {file, false}; + strcpy (buffer, name); p = strchr (buffer, '$'); while (p) { @@ -29507,6 +29595,7 @@ fputs (TARGET_32BIT ? "[DS]\n" : "[DS],3\n", file); RS6000_OUTPUT_BASENAME (file, buffer); fputs (":\n", file); + symtab_for_node_and_aliases (symtab_get_node (decl), rs6000_declare_alias, &data, true); fputs (TARGET_32BIT ? "\t.long ." : "\t.llong .", file); RS6000_OUTPUT_BASENAME (file, buffer); fputs (", TOC[tc0], 0\n", file); @@ -29515,11 +29604,26 @@ putc ('.', file); RS6000_OUTPUT_BASENAME (file, buffer); fputs (":\n", file); + data.function_descriptor = true; + symtab_for_node_and_aliases (symtab_get_node (decl), rs6000_declare_alias, &data, true); if (write_symbols != NO_DEBUG && !DECL_IGNORED_P (decl)) xcoffout_declare_function (file, decl, buffer); return; } +/* This macro produces the initial definition of a object (variable) name. + Because AIX assembler's .set command has unexpected semantics, we output + all aliases as alternative labels in front of the definition. */ + +void +rs6000_xcoff_declare_object_name (FILE *file, const char *name, tree decl) +{ + struct declare_alias_data data = {file, false}; + RS6000_OUTPUT_BASENAME (file, name); + fputs (":\n", file); + symtab_for_node_and_aliases (symtab_get_node (decl), rs6000_declare_alias, &data, true); +} + #ifdef HAVE_AS_TLS static void rs6000_xcoff_encode_section_info (tree decl, rtx rtl, int first) Index: config/rs6000/xcoff.h =================================================================== --- config/rs6000/xcoff.h (revision 212393) +++ config/rs6000/xcoff.h (working copy) @@ -139,6 +139,9 @@ #undef ASM_DECLARE_FUNCTION_NAME #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ rs6000_xcoff_declare_function_name ((FILE), (NAME), (DECL)) +#undef ASM_DECLARE_OBJECT_NAME +#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \ + rs6000_xcoff_declare_object_name ((FILE), (NAME), (DECL)) /* Output a reference to SYM on FILE. */ @@ -280,16 +283,18 @@ /* This is how we tell the assembler that two symbols have the same value. */ #define SET_ASM_OP "\t.set " -/* This is how we tell the assembler to equate two values. */ -#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) \ - do { fprintf ((FILE), "%s", SET_ASM_OP); \ - RS6000_OUTPUT_BASENAME (FILE, LABEL1); \ - fprintf (FILE, ","); \ - RS6000_OUTPUT_BASENAME (FILE, LABEL2); \ - fprintf (FILE, "\n"); \ - } while (0) +/* This is how we tell the assembler to equate two values. + The semantic of AIX assembler's .set do not correspond to middle-end expectations. + We output aliases as alternative symbols in the front of the definition + via DECLARE_FUNCTION_NAME and DECLARE_OBJECT_NAME. + We still need to define this macro to let middle-end know that aliases are + supported. + */ +#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) do { } while (0) /* Used by rs6000_assemble_integer, among others. */ + +/* Used by rs6000_assemble_integer, among others. */ #define DOUBLE_INT_ASM_OP "\t.llong\t" /* Output before instructions. */ Index: testsuite/ChangeLog =================================================================== --- testsuite/ChangeLog (revision 212279) +++ testsuite/ChangeLog (working copy) @@ -1,3 +1,8 @@ +2014-07-04 Jan Hubicka <hubi...@ucw.cz> + + * gcc.dg/globalalias.c: Remove XFAIL. + * gcc.dg/localalias.c: Remove XFAIL. + 2014-07-04 Thomas Schwinge <tho...@codesourcery.com> * lib/g++-dg.exp (g++-dg-runtest): Change interface to match Index: testsuite/gcc.dg/globalalias.c =================================================================== --- testsuite/gcc.dg/globalalias.c (revision 212279) +++ testsuite/gcc.dg/globalalias.c (working copy) @@ -8,7 +8,6 @@ /* { dg-do run } { dg-options "-O2" } { dg-require-alias "" } - { dg-xfail-if "" { powerpc-ibm-aix* } { "*" } { "" } } { dg-additional-sources "globalalias-2.c" } */ extern int test2count; extern void abort (void); Index: testsuite/gcc.dg/localalias.c =================================================================== --- testsuite/gcc.dg/localalias.c (revision 212279) +++ testsuite/gcc.dg/localalias.c (working copy) @@ -9,7 +9,6 @@ /* { dg-do run } { dg-options "-Wstrict-aliasing=2 -fstrict-aliasing" } { dg-require-alias "" } - { dg-xfail-if "" { powerpc-ibm-aix* } { "*" } { "" } } { dg-additional-sources "localalias-2.c" } */ extern void abort (void); extern int test2count;