From: "CHIGOT, CLEMENT" <clement.chigot@atos.net>
To: David Edelsohn <dje.gcc@gmail.com>
Cc: "gcc-patches@gcc.gnu.org" <gcc-patches@gcc.gnu.org>
Subject: Re: [PATCH] gcc: implement AIX-style constructors
Date: Tue, 2 Nov 2021 13:28:16 +0000 [thread overview]
Message-ID: <PA4PR02MB6686B6289F877B745915FEB7EA8B9@PA4PR02MB6686.eurprd02.prod.outlook.com> (raw)
In-Reply-To: <CAGWvny=R0OS-yXSmnv5m+jQ8efS9wVfYOQuiifkkvUwpqozsng@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 471 bytes --]
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
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-gcc-implement-AIX-style-constructors.patch --]
[-- Type: text/x-patch; name="0001-gcc-implement-AIX-style-constructors.patch", Size: 23397 bytes --]
From 8a14b0eb312628ad9cce8ac9f439c420b12b33c5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20Chigot?= <clement.chigot@atos.net>
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 <clement.chigot@atos.net>
* 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 <clement.chigot@atos.net>
* 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
next prev parent reply other threads:[~2021-11-02 13:28 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-10-18 7:55 CHIGOT, CLEMENT
2021-10-19 20:14 ` David Edelsohn
2021-10-21 12:39 ` CHIGOT, CLEMENT
2021-10-21 13:59 ` David Edelsohn
2021-11-02 13:28 ` CHIGOT, CLEMENT [this message]
2021-11-16 8:42 ` CHIGOT, CLEMENT
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=PA4PR02MB6686B6289F877B745915FEB7EA8B9@PA4PR02MB6686.eurprd02.prod.outlook.com \
--to=clement.chigot@atos.net \
--cc=dje.gcc@gmail.com \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).