Hi David, Here is the new version of the patch. I've moved the startup function in crtcdtors files.
I'm just wondering if the part dealing with the __init_aix_libgcc_cxa_atexit is needed. I'm adding it because the destructor created in crtcxa.o is following GCC format and thus won't be launched if the flag "-mcdtors=aix" is passed. However, as you said, this option might not operate correctly if the GCC runtime isn't rebuild with it. Thanks, Clément
From 8a14b0eb312628ad9cce8ac9f439c420b12b33c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Chigot?= <[email protected]> Date: Mon, 4 Oct 2021 09:24:43 +0200 Subject: [PATCH] gcc: implement AIX-style constructors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AIX linker now supports constructors and destructors detection. For such functions to be detected, their name must starts with __sinit or __sterm. and -bcdtors must be passed to linker calls. It will create "_cdtors" symbol which can be used to launch the initialization. This patch creates a new RS6000 flag "-mcdtors=". With "-mcdtors=aix", gcc will generate these new constructors/destructors. With "-mcdtors=gcc", which is currently the default, gcc will continue to generate "gcc" format for constructors (ie _GLOBAL__I and _GLOBAL__D symbols). Ideally, it would have been better to enable the AIX format by default instead of using collect2. However, the compatibility between the previously-built binaries and the new ones is too complex to be done. gcc/ChangeLog: 2021-10-04 Clément Chigot <[email protected]> * collect2.c (aixbcdtors_flags): New variable. (main): Use it to detect -bcdtors and remove -binitfini flag. (write_c_file_stat): Adapt to new AIX format. * config/rs6000/aix.h (FILE_SINIT_FORMAT): New define. (FILE_STERM_FORMAT): New define. (TARGET_FILE_FUNCTION_FORMAT): New define. * config/rs6000/aix64.opt: Add -mcdtors flag. * config/rs6000/aix71.h (LINK_SPEC_COMMON): Pass -bcdtors when -mcdtors=aix is passed. (STARTFILE_SPEC): Add crtcdtors.o with -mcdtors=aix. * config/rs6000/aix72.h (LINK_SPEC_COMMON): Likewise. (STARTFILE_SPEC): Likewise. * config/rs6000/aix73.h (LINK_SPEC_COMMON): Likewise. (STARTFILE_SPEC): Likewise. * config/rs6000/rs6000-opts.h (enum rs6000_cdtors): New enum. * doc/invoke.texi: Add -mcdtors flag. * tree.c (get_file_function_name): Add TARGET_FILE_FUNCTION_FORMAT support. libgcc/ChangeLog: * config.host: Add crtcdtors.o files. * config/rs6000/t-aix-cxa: Likewise. * config/rs6000/crtcdtors.c: New file. gcc/testsuite/ChangeLog: 2021-10-04 Clément Chigot <[email protected]> * gcc.target/powerpc/constructor-aix.c: New test. --- gcc/collect2.c | 63 ++++++++++++++++--- gcc/config/rs6000/aix.h | 56 +++++++++++++++++ gcc/config/rs6000/aix64.opt | 17 +++++ gcc/config/rs6000/aix71.h | 10 ++- gcc/config/rs6000/aix72.h | 10 ++- gcc/config/rs6000/aix73.h | 10 ++- gcc/config/rs6000/rs6000-opts.h | 8 +++ gcc/doc/invoke.texi | 21 ++++++- .../gcc.target/powerpc/constructor-aix.c | 12 ++++ gcc/tree.c | 5 ++ libgcc/config.host | 2 +- libgcc/config/rs6000/crtcdtors.c | 53 ++++++++++++++++ libgcc/config/rs6000/t-aix-cxa | 12 ++++ 13 files changed, 260 insertions(+), 19 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/constructor-aix.c create mode 100644 libgcc/config/rs6000/crtcdtors.c diff --git a/gcc/collect2.c b/gcc/collect2.c index 33114322f01..3d04bc8465f 100644 --- a/gcc/collect2.c +++ b/gcc/collect2.c @@ -186,6 +186,7 @@ static int aix64_flag; /* true if -b64 */ static int aixrtl_flag; /* true if -brtl */ static int aixlazy_flag; /* true if -blazy */ static int visibility_flag; /* true if -fvisibility */ +static int aixbcdtors_flag; /* True if -bcdtors */ #endif enum lto_mode_d { @@ -984,6 +985,8 @@ main (int argc, char **argv) aixrtl_flag = 0; else if (strcmp (argv[i], "-blazy") == 0) aixlazy_flag = 1; + else if (strcmp (argv[i], "-bcdtors") == 0) + aixbcdtors_flag = 1; #endif } @@ -1731,7 +1734,9 @@ main (int argc, char **argv) /* Tell the linker that we have initializer and finalizer functions. */ #ifdef LD_INIT_SWITCH #ifdef COLLECT_EXPORT_LIST - *ld2++ = concat (LD_INIT_SWITCH, ":", initname, ":", fininame, NULL); + /* Do not emit -binitfini when -bcdtors is enabled. */ + if (!aixbcdtors_flag) + *ld2++ = concat (LD_INIT_SWITCH, ":", initname, ":", fininame, NULL); #else *ld2++ = LD_INIT_SWITCH; *ld2++ = initname; @@ -2020,6 +2025,7 @@ write_c_file_stat (FILE *stream, const char *name ATTRIBUTE_UNUSED) { const char *p, *q; char *prefix, *r; + char *regframe_name, *deregframe_name; int frames = (frame_tables.number > 0); /* Figure out name of output_file, stripping off .so version. */ @@ -2062,6 +2068,22 @@ write_c_file_stat (FILE *stream, const char *name ATTRIBUTE_UNUSED) aix_shared_fininame = concat ("_GLOBAL__AIXD_", prefix, NULL); #endif + regframe_name = concat ("reg_frame", NULL, NULL); + deregframe_name = concat ("dereg_frame", NULL, NULL); +#ifdef COLLECT_EXPORT_LIST + /* In order to be detected by the linker, sinit/sterm symbols + must be external. Thus, reg_frame and dereg_frame can't + be static anymore and their name needs to be unique. + In order to ensure that frames are initialized before any + constructors, their constructor must have the highest priority + 0. */ + if (aixbcdtors_flag) + { + regframe_name = concat ("__sinit0_reg_frame_", prefix, NULL); + deregframe_name = concat ("__sterm0_dereg_frame_", prefix, NULL); + } +#endif + free (prefix); /* Write the tables as C code. */ @@ -2073,9 +2095,16 @@ write_c_file_stat (FILE *stream, const char *name ATTRIBUTE_UNUSED) mechanisms GCC uses to order constructors across different dependent shared libraries (see config/rs6000/aix.h). */ - fprintf (stream, "static int count;\n"); - fprintf (stream, "typedef void entry_pt();\n"); - write_list_with_asm (stream, "extern entry_pt ", constructors.first); +#ifdef COLLECT_EXPORT_LIST + if (!aixbcdtors_flag) + { +#endif + fprintf (stream, "static int count;\n"); + fprintf (stream, "typedef void entry_pt();\n"); + write_list_with_asm (stream, "extern entry_pt ", constructors.first); +#ifdef COLLECT_EXPORT_LIST + } +#endif if (frames) { @@ -2102,7 +2131,12 @@ write_c_file_stat (FILE *stream, const char *name ATTRIBUTE_UNUSED) fprintf (stream, "extern void *__gcc_unwind_dbase;\n"); #endif - fprintf (stream, "static void reg_frame () {\n"); +#ifdef COLLECT_EXPORT_LIST + if (aixbcdtors_flag) + fprintf (stream, "void %s () {\n", regframe_name); + else +#endif + fprintf (stream, "static void %s () {\n", regframe_name); fprintf (stream, "\tstatic struct object ob;\n"); #ifdef TARGET_AIX_VERSION /* Use __gcc_unwind_dbase as the base address for data on AIX. @@ -2114,11 +2148,24 @@ write_c_file_stat (FILE *stream, const char *name ATTRIBUTE_UNUSED) #endif fprintf (stream, "\t}\n"); - fprintf (stream, "static void dereg_frame () {\n"); +#ifdef COLLECT_EXPORT_LIST + if (aixbcdtors_flag) + fprintf (stream, "void %s () {\n", deregframe_name); + else +#endif + fprintf (stream, "static void %s () {\n", deregframe_name); fprintf (stream, "\t__deregister_frame_info (frame_table);\n"); fprintf (stream, "\t}\n"); } +#ifdef COLLECT_EXPORT_LIST + /* Files built with the new AIX cdtors format don't need to + explicitly call them. + NOTE: This breaks compatibility with previously-built files. */ + if (aixbcdtors_flag) + return; +#endif + #ifdef COLLECT_EXPORT_LIST /* Set visibility of initializers to default. */ if (visibility_flag) @@ -2130,7 +2177,7 @@ write_c_file_stat (FILE *stream, const char *name ATTRIBUTE_UNUSED) fprintf (stream, "\tstatic entry_pt *ctors[] = {\n"); write_list (stream, "\t\t", constructors.first); if (frames) - fprintf (stream, "\treg_frame,\n"); + fprintf (stream, "\t%s,\n", regframe_name); fprintf (stream, "\t};\n"); fprintf (stream, "\tentry_pt **p;\n"); fprintf (stream, "\tif (count++ != 0) return;\n"); @@ -2147,7 +2194,7 @@ write_c_file_stat (FILE *stream, const char *name ATTRIBUTE_UNUSED) fprintf (stream, "\tstatic entry_pt *dtors[] = {\n"); write_list (stream, "\t\t", destructors.first); if (frames) - fprintf (stream, "\tdereg_frame,\n"); + fprintf (stream, "\t%s,\n", deregframe_name); fprintf (stream, "\t};\n"); fprintf (stream, "\tentry_pt **p;\n"); fprintf (stream, "\tif (--count != 0) return;\n"); diff --git a/gcc/config/rs6000/aix.h b/gcc/config/rs6000/aix.h index 0f4d8cb2dc8..d9ed88cb459 100644 --- a/gcc/config/rs6000/aix.h +++ b/gcc/config/rs6000/aix.h @@ -284,3 +284,59 @@ #define SUBTARGET_DRIVER_SELF_SPECS \ "%{m64:-maix64} %<m64", \ "%{m32:-maix32} %<m32" + +/* Support for cdtors detected by AIX linker. + With -bcdtors flag, AIX linker is able to handle initialisers + by itself. For that, these initalisers must be named with the + following schema: __sinit{priority}_{name}. For destructors, + __sinit is replaced by __sterm. + + For now, this part is enabled only when -mcdtors=aix flag is + passed to gcc. + + The TARGET_FILE_FUNCTION_FORMAT allows to change the default name of + gcc constructors and destructors to one which will be understand by + AIX linker. + + NOTE: + sinit/sterm functions will be triggered only if -bcdtors is passed + to the linker when building the binary. Even libraries built with + -bcdtors won't triggered those functions by themselves. + Ideally, if one day AIX way become the default, we would like + to ensure full compatibility between previously-made libraries + and new ones. However, this is hardly possible. + The main reason why this isn't working is that old libraries need + to be able to call constructors of new libraries using the previous + way, ie using GLOBAL_AIXI symbols. But if an old library loading a + new library is called by a new binary (thus with -bcdtors enabled), + it will trigger the new library's cdtors twice. + TODO: The only solution is to modify the wrapper created by gcc + around constructors and destructors so that it ensures that they + are called only once. +*/ +#define FILE_SINIT_FORMAT "__sinit%s_%s" +#define FILE_STERM_FORMAT "__sterm%s_%s" +#define TARGET_FILE_FUNCTION_FORMAT(TYPE, BUF, SUBNAME) \ + do \ + { \ + if (rs6000_current_cdtors == CDTORS_AIX && (TYPE[0] == 'I')) \ + { \ + BUF = (char *) alloca (sizeof (FILE_SINIT_FORMAT) \ + + strlen (SUBNAME) + strlen (TYPE) - 2); \ + sprintf (BUF, FILE_SINIT_FORMAT, TYPE + 2, SUBNAME); \ + } \ + else if (rs6000_current_cdtors == CDTORS_AIX && (TYPE[0] == 'D')) \ + { \ + BUF = (char *) alloca (sizeof (FILE_STERM_FORMAT) \ + + strlen (SUBNAME) + strlen (TYPE) - 2); \ + sprintf (BUF, FILE_STERM_FORMAT, TYPE + 2, SUBNAME); \ + } \ + else \ + { \ + BUF = (char *) alloca (sizeof (FILE_FUNCTION_FORMAT) \ + + strlen (SUBNAME) + strlen (TYPE)); \ + sprintf (BUF, FILE_FUNCTION_FORMAT, TYPE, SUBNAME); \ + } \ + } \ + while(0) + diff --git a/gcc/config/rs6000/aix64.opt b/gcc/config/rs6000/aix64.opt index 15d863fa0a2..508e79f17f9 100644 --- a/gcc/config/rs6000/aix64.opt +++ b/gcc/config/rs6000/aix64.opt @@ -59,3 +59,20 @@ Driver m32 Driver + +mcdtors= +Target RejectNegative Joined Enum(rs6000_cdtors) Var(rs6000_current_cdtors) +Select constructors format. + +Enum +Name(rs6000_cdtors) Type(enum rs6000_cdtors) +Known constructors format (for use with the -mcdtors= option): + +EnumValue +Enum(rs6000_cdtors) String(aix) Value(CDTORS_AIX) + +EnumValue +Enum(rs6000_cdtors) String(gcc) Value(CDTORS_GCC) + +TargetVariable +enum rs6000_cdtors rs6000_current_cdtors = CDTORS_GCC \ No newline at end of file diff --git a/gcc/config/rs6000/aix71.h b/gcc/config/rs6000/aix71.h index 75afa22a2eb..cd991674af8 100644 --- a/gcc/config/rs6000/aix71.h +++ b/gcc/config/rs6000/aix71.h @@ -176,7 +176,7 @@ do { \ #define LINK_SPEC64 "-b64" #define LINK_SPEC_COMMON "-bpT:0x10000000 -bpD:0x20000000 %{!r:-btextro}\ %{static:-bnso %(link_syscalls) } %{shared:-bM:SRE %{!e:-bnoentry}}\ - %{mpe:-binitfini:poe_remote_main} " + %{mpe:-binitfini:poe_remote_main} %{mcdtors=aix:-bcdtors}" #undef STARTFILE_SPEC #if DEFAULT_ARCH64_P @@ -185,14 +185,18 @@ do { \ %{pthread:%{pg:gcrt0_r%O%s;:%{p:mcrt0_r%O%s;:crt0_r%O%s}};:\ %{pg:gcrt0%O%s;:%{p:mcrt0%O%s;:crt0%O%s}}}}}\ %{!maix32:%{shared:crtcxa_64_s%O%s;:crtcxa_64%O%s} crtdbase_64%O%s;:\ - %{shared:crtcxa_s%O%s;:crtcxa%O%s} crtdbase%O%s}" + %{shared:crtcxa_s%O%s;:crtcxa%O%s} crtdbase%O%s}\ + %{mcdtors=aix: %{!maix32:%{shared:crtcdtors_64_s%O%s;:crtcdtors_64%O%s};:\ + %{shared:crtcdtors_s%O%s;:crtcdtors%O%s}}}" #else #define STARTFILE_SPEC "%{!shared:\ %{maix64:%{pg:gcrt0_64%O%s;:%{p:mcrt0_64%O%s;:crt0_64%O%s}};:\ %{pthread:%{pg:gcrt0_r%O%s;:%{p:mcrt0_r%O%s;:crt0_r%O%s}};:\ %{pg:gcrt0%O%s;:%{p:mcrt0%O%s;:crt0%O%s}}}}}\ %{maix64:%{shared:crtcxa_64_s%O%s;:crtcxa_64%O%s} crtdbase_64%O%s;:\ - %{shared:crtcxa_s%O%s;:crtcxa%O%s} crtdbase%O%s}" + %{shared:crtcxa_s%O%s;:crtcxa%O%s} crtdbase%O%s}\ + %{mcdtors=aix: %{maix64:%{shared:crtcdtors_64_s%O%s;:crtcdtors_64%O%s};:\ + %{shared:crtcdtors_s%O%s;:crtcdtors%O%s}}}" #endif diff --git a/gcc/config/rs6000/aix72.h b/gcc/config/rs6000/aix72.h index 7ae25bd2a29..b4fc3040341 100644 --- a/gcc/config/rs6000/aix72.h +++ b/gcc/config/rs6000/aix72.h @@ -177,7 +177,7 @@ do { \ #define LINK_SPEC64 "-b64" #define LINK_SPEC_COMMON "-bpT:0x10000000 -bpD:0x20000000 %{!r:-btextro}\ %{static:-bnso %(link_syscalls) } %{shared:-bM:SRE %{!e:-bnoentry}}\ - %{mpe:-binitfini:poe_remote_main} " + %{mpe:-binitfini:poe_remote_main} %{mcdtors=aix:-bcdtors}" #undef STARTFILE_SPEC #if DEFAULT_ARCH64_P @@ -186,14 +186,18 @@ do { \ %{pthread:%{pg:gcrt0_r%O%s;:%{p:mcrt0_r%O%s;:crt0_r%O%s}};:\ %{pg:gcrt0%O%s;:%{p:mcrt0%O%s;:crt0%O%s}}}}}\ %{!maix32:%{shared:crtcxa_64_s%O%s;:crtcxa_64%O%s} crtdbase_64%O%s;:\ - %{shared:crtcxa_s%O%s;:crtcxa%O%s} crtdbase%O%s}" + %{shared:crtcxa_s%O%s;:crtcxa%O%s} crtdbase%O%s}\ + %{mcdtors=aix: %{!maix32:%{shared:crtcdtors_64_s%O%s;:crtcdtors_64%O%s};:\ + %{shared:crtcdtors_s%O%s;:crtcdtors%O%s}}}" #else #define STARTFILE_SPEC "%{!shared:\ %{maix64:%{pg:gcrt0_64%O%s;:%{p:mcrt0_64%O%s;:crt0_64%O%s}};:\ %{pthread:%{pg:gcrt0_r%O%s;:%{p:mcrt0_r%O%s;:crt0_r%O%s}};:\ %{pg:gcrt0%O%s;:%{p:mcrt0%O%s;:crt0%O%s}}}}}\ %{maix64:%{shared:crtcxa_64_s%O%s;:crtcxa_64%O%s} crtdbase_64%O%s;:\ - %{shared:crtcxa_s%O%s;:crtcxa%O%s} crtdbase%O%s}" + %{shared:crtcxa_s%O%s;:crtcxa%O%s} crtdbase%O%s}\ + %{mcdtors=aix: %{maix64:%{shared:crtcdtors_64_s%O%s;:crtcdtors_64%O%s};:\ + %{shared:crtcdtors_s%O%s;:crtcdtors%O%s}}}" #endif diff --git a/gcc/config/rs6000/aix73.h b/gcc/config/rs6000/aix73.h index ee5858cc443..95af5611252 100644 --- a/gcc/config/rs6000/aix73.h +++ b/gcc/config/rs6000/aix73.h @@ -178,7 +178,7 @@ do { \ #define LINK_SPEC64 "-b64" #define LINK_SPEC_COMMON "-bpT:0x10000000 -bpD:0x20000000 %{!r:-btextro}\ %{static:-bnso %(link_syscalls) } %{shared:-bM:SRE %{!e:-bnoentry}}\ - %{mpe:-binitfini:poe_remote_main} " + %{mpe:-binitfini:poe_remote_main} %{mcdtors=aix:-bcdtors}" #undef STARTFILE_SPEC #if DEFAULT_ARCH64_P @@ -187,14 +187,18 @@ do { \ %{pthread:%{pg:gcrt0_r%O%s;:%{p:mcrt0_r%O%s;:crt0_r%O%s}};:\ %{pg:gcrt0%O%s;:%{p:mcrt0%O%s;:crt0%O%s}}}}}\ %{!maix32:%{shared:crtcxa_64_s%O%s;:crtcxa_64%O%s} crtdbase_64%O%s;:\ - %{shared:crtcxa_s%O%s;:crtcxa%O%s} crtdbase%O%s}" + %{shared:crtcxa_s%O%s;:crtcxa%O%s} crtdbase%O%s}\ + %{mcdtors=aix: %{!maix32:%{shared:crtcdtors_64_s%O%s;:crtcdtors_64%O%s};:\ + %{shared:crtcdtors_s%O%s;:crtcdtors%O%s}}}" #else #define STARTFILE_SPEC "%{!shared:\ %{maix64:%{pg:gcrt0_64%O%s;:%{p:mcrt0_64%O%s;:crt0_64%O%s}};:\ %{pthread:%{pg:gcrt0_r%O%s;:%{p:mcrt0_r%O%s;:crt0_r%O%s}};:\ %{pg:gcrt0%O%s;:%{p:mcrt0%O%s;:crt0%O%s}}}}}\ %{maix64:%{shared:crtcxa_64_s%O%s;:crtcxa_64%O%s} crtdbase_64%O%s;:\ - %{shared:crtcxa_s%O%s;:crtcxa%O%s} crtdbase%O%s}" + %{shared:crtcxa_s%O%s;:crtcxa%O%s} crtdbase%O%s}\ + %{mcdtors=aix: %{maix64:%{shared:crtcdtors_64_s%O%s;:crtcdtors_64%O%s};:\ + %{shared:crtcdtors_s%O%s;:crtcdtors%O%s}}}" #endif diff --git a/gcc/config/rs6000/rs6000-opts.h b/gcc/config/rs6000/rs6000-opts.h index 51d6c654842..ab78f31dc9d 100644 --- a/gcc/config/rs6000/rs6000-opts.h +++ b/gcc/config/rs6000/rs6000-opts.h @@ -147,6 +147,14 @@ enum stack_protector_guard { SSP_GLOBAL /* global canary */ }; +/* Constructors format for AIX32 + aix: AIX format (__sinit/__sterm) + gcc: GCC format (_GLOBAL__I/_GLOBAL__F) */ +enum rs6000_cdtors { + CDTORS_AIX, + CDTORS_GCC +}; + /* No enumeration is defined to index the -mcpu= values (entries in processor_target_table), with the type int being used instead, but we need to distinguish the special "native" value. */ diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 6d1e328571a..5b64cbb4569 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1249,7 +1249,8 @@ See RS/6000 and PowerPC Options. -mstack-protector-guard=@var{guard} -mstack-protector-guard-reg=@var{reg} @gol -mstack-protector-guard-offset=@var{offset} -mprefixed -mno-prefixed @gol -mpcrel -mno-pcrel -mmma -mno-mmma -mrop-protect -mno-rop-protect @gol --mprivileged -mno-privileged} +-mprivileged -mno-privileged @gol +-mcdtors=@var{cdtors_format}} @emph{RX Options} @gccoptlist{-m64bit-doubles -m32bit-doubles -fpu -nofpu@gol @@ -28572,6 +28573,24 @@ Generate (do not generate) code that will run in privileged state. @opindex no-block-ops-unaligned-vsx Generate (do not generate) unaligned vsx loads and stores for inline expansion of @code{memcpy} and @code{memmove}. + +@item -mcdtors=@var{cdtors_format} +@opindex mcdtors +Specifies which format should be used to generate constructors +and destructors on AIX. +Valid values are: @samp{gcc} and @samp{aix}. + +@item -mcdtors=gcc +@opindex mcdtors=gcc +Generate constructors and destructors following GCC format. + +@item -mcdtors=aix +@opindex mcdtors=aix +Generate constructors and destructors following AIX format. +This is made for interoperability with IBM XL Compiler. +This option will not operate correctly unless the application +and the GCC runtime are built with the option. + @end table @node RX Options diff --git a/gcc/testsuite/gcc.target/powerpc/constructor-aix.c b/gcc/testsuite/gcc.target/powerpc/constructor-aix.c new file mode 100644 index 00000000000..65222a5e239 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/constructor-aix.c @@ -0,0 +1,12 @@ +/* { dg-do run { target powerpc*-*-aix* } } */ +/* { dg-options "-mcdtors=aix" } */ + +int i; + +void hello (void) __attribute__ ((constructor)); +void hello (void) { i = 1; } + +int main (void) { + if (i != 1) + return 1; +} diff --git a/gcc/tree.c b/gcc/tree.c index 7bfd64160f4..cc0a10a3c22 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -8633,6 +8633,10 @@ get_file_function_name (const char *type) } clean_symbol_name (q); + +#ifdef TARGET_FILE_FUNCTION_FORMAT + TARGET_FILE_FUNCTION_FORMAT(type, buf, p); +#else buf = (char *) alloca (sizeof (FILE_FUNCTION_FORMAT) + strlen (p) + strlen (type)); @@ -8641,6 +8645,7 @@ get_file_function_name (const char *type) the program) rather than the file name (which imposes extra constraints). */ sprintf (buf, FILE_FUNCTION_FORMAT, type, p); +#endif return get_identifier (buf); } diff --git a/libgcc/config.host b/libgcc/config.host index 6c34b13d611..f88a7cc6b40 100644 --- a/libgcc/config.host +++ b/libgcc/config.host @@ -1288,7 +1288,7 @@ rs6000-ibm-aix5.1.* | powerpc-ibm-aix5.1.*) rs6000-ibm-aix[56789].* | powerpc-ibm-aix[56789].*) md_unwind_header=rs6000/aix-unwind.h tmake_file="t-fdpbit rs6000/t-ppc64-fp rs6000/t-slibgcc-aix rs6000/t-ibm-ldouble rs6000/t-aix-cxa" - extra_parts="crtcxa.o crtcxa_s.o crtdbase.o crtcxa_64.o crtcxa_64_s.o crtdbase_64.o" + extra_parts="crtcxa.o crtcxa_s.o crtdbase.o crtcxa_64.o crtcxa_64_s.o crtdbase_64.o crtcdtors.o crtcdtors_s.o crtcdtors_64.o crtcdtors_64_s.o" ;; rl78-*-elf) tmake_file="$tm_file t-fdpbit rl78/t-rl78" diff --git a/libgcc/config/rs6000/crtcdtors.c b/libgcc/config/rs6000/crtcdtors.c new file mode 100644 index 00000000000..a60c8e30c56 --- /dev/null +++ b/libgcc/config/rs6000/crtcdtors.c @@ -0,0 +1,53 @@ +/* Initialization of constructors and destructors following + AIX format. + Copyright (C) 2021-2021 Free Software Foundation, Inc. + Written by Clément Chigot. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3, or (at your option) any later + version. + + GCC is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef SHARED +extern void (* _cdtors[]) (void); +extern void __run_initial_ctors (void (**) (void)); +extern void __run_final_dtors (void); + +void _AIX_init(void); +void _AIX_init(void) +{ + /* Run CTORs now */ + __run_initial_ctors(&_cdtors[0]); + + /* Warn exit() that we want to run dtors at the end */ + __run_final_dtors(); +} + +void (*__C_runtime_pstartup) (void) = _AIX_init; + +#endif + +/* crtcxa is compiled without -mcdtors=aix flag. Thus, a new + destructor must be created following AIX format and this file + must be compiled with -mcdtors=aix to enable it. */ +void __init_aix_libgcc_cxa_atexit_dup (void) __attribute__ ((destructor (65535))); +void __init_aix_libgcc_cxa_atexit_dup (void) +{ + __init_aix_libgcc_cxa_atexit (); +} diff --git a/libgcc/config/rs6000/t-aix-cxa b/libgcc/config/rs6000/t-aix-cxa index 0e1bccb1525..e9e862909bc 100644 --- a/libgcc/config/rs6000/t-aix-cxa +++ b/libgcc/config/rs6000/t-aix-cxa @@ -24,3 +24,15 @@ crtcxa_64.o: $(srcdir)/config/rs6000/crtcxa.c crtcxa_64_s.o: $(srcdir)/config/rs6000/crtcxa.c $(crt_compile) -maix64 -DSHARED -c $< + +crtcdtors.o: $(srcdir)/config/rs6000/crtcdtors.c + $(crt_compile) -maix32 -c $< -mcdtors=aix + +crtcdtors_s.o: $(srcdir)/config/rs6000/crtcdtors.c + $(crt_compile) -maix32 -DSHARED -c $< -mcdtors=aix + +crtcdtors_64.o: $(srcdir)/config/rs6000/crtcdtors.c + $(crt_compile) -maix64 -c $< -mcdtors=aix + +crtcdtors_64_s.o: $(srcdir)/config/rs6000/crtcdtors.c + $(crt_compile) -maix64 -DSHARED -c $< -mcdtors=aix \ No newline at end of file -- 2.33.0
