From 657527453de8d1a4a228ee602680531781d283f2 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Thu, 19 Feb 2026 15:38:17 -0500
Subject: [PATCH v7 5/8] Force 64-bit builds on AIX.

There's too many problems with 32-bit builds, due to AIX's
inefficient management of address space.  Rather than documenting
those, let's just desupport the case.

In the make-based build system, it's not too hard to force the
right things to happen regardless of the OBJECT_MODE setting.
But meson seems too obstreperously set on the idea that they
know better.  Pending somebody working out an end run around
that silliness, document that users must set OBJECT_MODE=64
while building.

TODO: it doesn't seem that -Wl,-bbigtoc actually works; we still get
warnings from ld.  Curiously, the meson build doesn't produce
those warnings.  I see it's inserting -Wl,-bbigtoc under the hood,
but seemingly there's some additional secret sauce.

TODO: who to credit for this work?
---
 doc/src/sgml/installation.sgml     | 109 ++++-------------------------
 meson.build                        |   9 +++
 src/backend/Makefile               |   2 +-
 src/backend/port/aix/mkldexport.sh |   3 +
 src/makefiles/Makefile.aix         |   3 +
 src/template/aix                   |  10 +++
 6 files changed, 40 insertions(+), 96 deletions(-)

diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml
index 554d1bde7e0..2a0f4d7a781 100644
--- a/doc/src/sgml/installation.sgml
+++ b/doc/src/sgml/installation.sgml
@@ -3499,106 +3499,25 @@ export MANPATH
     The native IBM compiler <command>xlc</command> is not supported.
    </para>
 
+   <para>
+    Also, only 64-bit builds are supported.  While the make-based build
+    system will automatically create 64-bit executables and libraries,
+    the meson build system requires you to
+    set <varname>OBJECT_MODE</varname> before building:
+<programlisting>
+export OBJECT_MODE=64
+meson setup ...
+</programlisting>
+    Failure to do that will usually manifest as complaints
+    from <application>ar</application> about files having the wrong
+    object file mode.
+   </para>
+
    <para>
     <productname>AIX</productname> versions before 7.2 are no longer
     tested nor supported by the <productname>PostgreSQL</productname>
     community.
    </para>
-
-   <sect3 id="installation-notes-aix-mem-management">
-    <title>Memory Management</title>
-    <!-- https://archives.postgresql.org/message-id/603bgqmpl9.fsf@dba2.int.libertyrms.com -->
-
-    <para>
-     AIX can be somewhat peculiar with regards to the way it does
-     memory management.  You can have a server with many multiples of
-     gigabytes of RAM free, but still get out of memory or address
-     space errors when running applications.  One example
-     is loading of extensions failing with unusual errors.
-     For example, running as the owner of the PostgreSQL installation:
-<screen>
-=# CREATE EXTENSION plperl;
-ERROR:  could not load library "/opt/dbs/pgsql/lib/plperl.so": A memory address is not in the address space for the process.
-</screen>
-    Running as a non-owner in the group possessing the PostgreSQL
-    installation:
-<screen>
-=# CREATE EXTENSION plperl;
-ERROR:  could not load library "/opt/dbs/pgsql/lib/plperl.so": Bad address
-</screen>
-     Another example is out of memory errors in the PostgreSQL server
-     logs, with every memory allocation near or greater than 256 MB
-     failing.
-    </para>
-
-    <para>
-     The overall cause of all these problems is the default bittedness
-     and memory model used by the server process.  By default, all
-     binaries built on AIX are 32-bit.  This does not depend upon
-     hardware type or kernel in use.  These 32-bit processes are
-     limited to 4 GB of memory laid out in 256 MB segments using one
-     of a few models.  The default allows for less than 256 MB in the
-     heap as it shares a single segment with the stack.
-    </para>
-
-    <para>
-     In the case of the <literal>plperl</literal> example, above,
-     check your umask and the permissions of the binaries in your
-     PostgreSQL installation.  The binaries involved in that example
-     were 32-bit and installed as mode 750 instead of 755.  Due to the
-     permissions being set in this fashion, only the owner or a member
-     of the possessing group can load the library.  Since it isn't
-     world-readable, the loader places the object into the process'
-     heap instead of the shared library segments where it would
-     otherwise be placed.
-    </para>
-
-    <para>
-     The <quote>ideal</quote> solution for this is to use a 64-bit
-     build of PostgreSQL, but that is not always practical, because
-     systems with 32-bit processors can build, but not run, 64-bit
-     binaries.
-    </para>
-
-    <para>
-     If a 32-bit binary is desired, set <symbol>LDR_CNTRL</symbol> to
-     <literal>MAXDATA=0x<replaceable>n</replaceable>0000000</literal>,
-     where 1 &lt;= n &lt;= 8, before starting the PostgreSQL server,
-     and try different values and <filename>postgresql.conf</filename>
-     settings to find a configuration that works satisfactorily.  This
-     use of <symbol>LDR_CNTRL</symbol> tells AIX that you want the
-     server to have <symbol>MAXDATA</symbol> bytes set aside for the
-     heap, allocated in 256 MB segments.  When you find a workable
-     configuration,
-     <command>ldedit</command> can be used to modify the binaries so
-     that they default to using the desired heap size.  PostgreSQL can
-     also be rebuilt, passing <literal>configure
-     LDFLAGS="-Wl,-bmaxdata:0x<replaceable>n</replaceable>0000000"</literal>
-     to achieve the same effect.
-    </para>
-
-    <para>
-     For a 64-bit build, set <envar>OBJECT_MODE</envar> to 64 and
-     pass <literal>CC="gcc -maix64"</literal>
-     and <literal>LDFLAGS="-Wl,-bbigtoc"</literal>
-     to <command>configure</command>.  If you omit the export of
-    <envar>OBJECT_MODE</envar>, your build may fail with linker errors.  When
-    <envar>OBJECT_MODE</envar> is set, it tells AIX's build utilities
-    such as <command>ar</command>, <command>as</command>, and <command>ld</command> what
-    type of objects to default to handling.
-    </para>
-
-    <para>
-     By default, overcommit of paging space can happen.  While we have
-     not seen this occur, AIX will kill processes when it runs out of
-     memory and the overcommit is accessed.  The closest to this that
-     we have seen is fork failing because the system decided that
-     there was not enough memory for another process.  Like many other
-     parts of AIX, the paging space allocation method and
-     out-of-memory kill is configurable on a system- or process-wide
-     basis if this becomes a problem.
-    </para>
-   </sect3>
   </sect2>
 
   <sect2 id="installation-notes-cygwin">
diff --git a/meson.build b/meson.build
index 2ebf4a189eb..d0736ab05ac 100644
--- a/meson.build
+++ b/meson.build
@@ -237,6 +237,15 @@ if host_system == 'aix'
   mod_link_with_dir = 'libdir'
   mod_link_with_name = '@0@.imp'
 
+  # We force 64-bit builds, because AIX doesn't play very nice with dynamic
+  # library loading in 32-bit mode: there's not enough address space.
+  cppflags += '-maix64'
+  ldflags += '-maix64'
+  # Note: it's also necessary to tell programs like 'ar' to work in 64-bit
+  # mode.  Since meson, in its infinite wisdom, doesn't allow us either
+  # to pass '-X64' to ar or to set the OBJECT_MODE environment variable
+  # from here, we have to tell the user to set OBJECT_MODE.
+
   # M:SRE sets a flag indicating that an object is a shared library.
   ldflags_sl += '-Wl,-bM:SRE'
   # -brtllib indicates binaries should use runtime-loaded shared libraries.
diff --git a/src/backend/Makefile b/src/backend/Makefile
index fe717001951..ba53cd9d998 100644
--- a/src/backend/Makefile
+++ b/src/backend/Makefile
@@ -131,7 +131,7 @@ postgres: $(POSTGRES_IMP)
 # trivially work with gcc, due to gcc specific static libraries linked in with
 # -r.
 $(POSTGRES_IMP): $(OBJS)
-	ld -r -o SUBSYS.o $(call expand_subsys,$^)
+	ld -b64 -r -o SUBSYS.o $(call expand_subsys,$^)
 	$(MKLDEXPORT) SUBSYS.o . > $@
 	@rm -f SUBSYS.o
 
diff --git a/src/backend/port/aix/mkldexport.sh b/src/backend/port/aix/mkldexport.sh
index 85631ce672a..9d016e7afd5 100755
--- a/src/backend/port/aix/mkldexport.sh
+++ b/src/backend/port/aix/mkldexport.sh
@@ -40,6 +40,9 @@ else echo "Fatal error: cannot find `nm' ... please check your installation."
      exit 1
 fi
 
+# instruct nm to process 64-bit objects
+export OBJECT_MODE=64
+
 CMDNAME=`basename $0`
 if [ -z "$1" ]; then
 	echo "Usage: $CMDNAME object [location]"
diff --git a/src/makefiles/Makefile.aix b/src/makefiles/Makefile.aix
index 828641655aa..ecba693b6a9 100644
--- a/src/makefiles/Makefile.aix
+++ b/src/makefiles/Makefile.aix
@@ -20,6 +20,9 @@ ifeq ($(GCC), yes)
 LDFLAGS_SL += -shared
 endif
 
+# instruct ar to process 64-bit objects
+AROPT := -X64 $(AROPT)
+
 # env var name to use in place of LD_LIBRARY_PATH
 ld_library_path_var = LIBPATH
 
diff --git a/src/template/aix b/src/template/aix
index c7c8706fea5..9abe1efacd4 100644
--- a/src/template/aix
+++ b/src/template/aix
@@ -7,3 +7,13 @@ fi
 
 # Extra CFLAGS for code that will go into a shared library
 CFLAGS_SL=""
+
+if test "$GCC" = yes; then
+  # We force 64-bit builds, because AIX doesn't play very nice with dynamic
+  # library loading in 32-bit mode: there's not enough address space.
+  CPPFLAGS="$CPPFLAGS -maix64"
+
+  # For large binaries/libraries, there will be TOC overflows in AIX. To
+  # avoid this, pass -bbigtoc linker option to enlarge TOC access range.
+  LDFLAGS="$LDFLAGS -maix64 -Wl,-bbigtoc"
+fi
-- 
2.43.7

