I am trying to determine if this change in behavior is intentional or if there is something that can be done to work with the linker default behavior... GCC 6+ started generating sections named `_<file>.ro_` that when passed to AIX `ld` produce the following error: ld: 0711-308 SEVERE ERROR: Object main.cc.o, csect <_main.ro_> The csect is part of the .text section. This happens for any such `.ro` symbol, not just the one for `main`. These are generated in gcc/config/rs6000/rs6000.c: rs6000_gen_section_name (&xcoff_read_only_section_name, main_input_filename, ".ro_"); GCC 5 compiled objects link properly with default `ld` invocation. In order to "fix" this and link an executable, the following flag must be passed to deviate from default linker behavior: notextro or nro Does not check to ensure that there are no load time relocation entries for the text section of the output object file. This is the default. That implies default linker behavior is to reject any load time relocation entries against the `.text` section. Can anything be done to eliminate the need for this non-standard option or is this now required for all linking of GCC-compiled objects?
This line has been there for a long time now. Maybe what is in main_input_filename changed ...
Specifying -bnotextro does not make a working binary: Could not load program x: Relocation failed for x because: Relocation entry 3 (at address 0x10416AD3) has an invalid l_rsecnm field. Relocation entry 4 (at address 0x10416AD3) has an invalid l_rsecnm field. Relocation entry 5 (at address 0x10416EC3) has an invalid l_rsecnm field. Relocation entry 6 (at address 0x10416EC3) has an invalid l_rsecnm field. Relocation entry 7 (at address 0x1041A3D3) has an invalid l_rsecnm field. Relocation entry 8 (at address 0x1041A3D3) has an invalid l_rsecnm field. Relocation entry 9 (at address 0x1041B813) has an invalid l_rsecnm field. Relocation entry 10 (at address 0x1041B813) has an invalid l_rsecnm field. Relocation entry 11 (at address 0x1041BF93) has an invalid l_rsecnm field. Relocation entry 12 (at address 0x1041BF93) has an invalid l_rsecnm field. Relocation entry 13 (at address 0x1041D2F3) has an invalid l_rsecnm field. Relocation entry 14 (at address 0x1041D2F3) has an invalid l_rsecnm field. ...
This is not new. You need to provide more information about how this is occurring. "main.cc.o" implies this this is C++. The "ro" section is used for read-only data. There have been other changes in GCC about the placement of data and that may have caused some type of object to be placed in read-only data that is not correct for AIX. AIX only really has three sections: Text, Data and BSS. Read-only data is placed in the text section, so that message is correct. It implies that some read-write data / relocatable data is being placed in the read-only section. On the other hand, GCC itself is C++ code. There are many other C++ application that compile, link and run correctly. So there is something more about the specific application that is eliciting this error.
This occurs while building a project that depends on the protobuf library. I'll attach main.cc.s, and command lines are below. If I take the exact main.cc.o compilation line and simply swap out GCC 8.2.0 for g++-7, g++-6, g++-5, both GCC 7.3.0 & GCC 6.4.0 fail in the same manner, but GCC 5.5.0 succeeds. This is how main.cc.o is compiled: g++-8 -maix64 -pthread -DGOOGLE_PROTOBUF_CMAKE_BUILD -DHAVE_PTHREAD -DHAVE_ZLIB -D_LIBCXXABI_FUNC_VIS="" -I/path/to/third_party/protobuf/cmake -I/path/to/third_party/protobuf/src -D__STDC_FORMAT_MACROS -O2 -g -DNDEBUG -std=c++11 -o CMakeFiles/protoc.dir/__/src/google/protobuf/compiler/main.cc.o -c /path/to/third_party/protobuf/src/google/protobuf/compiler/main.cc ... verbose output shows cc1plus invocation: cc1plus -quiet -v -I /path/to/third_party/protobuf/cmake -I /path/to/third_party/protobuf/src -imultilib pthread/ppc64 -iprefix /path/to/gcc/bin/../lib/gcc/powerpc-ibm-aix7.1.0.0/8.2.0/ -D_ALL_SOURCE -D__COMPATMATH__ -D__64BIT__ -D_THREAD_SAFE -D GOOGLE_PROTOBUF_CMAKE_BUILD -D HAVE_PTHREAD -D HAVE_ZLIB -D _LIBCXXABI_FUNC_VIS= -D __STDC_FORMAT_MACROS -D NDEBUG /path/to/third_party/protobuf/src/google/protobuf/compiler/main.cc -quiet -dumpbase main.cc -maix64 -auxbase-strip CMakeFiles/protoc.dir/__/src/google/protobuf/compiler/main.cc.o -g -O2 -std=c++11 -version -o /tmp/ccVqNDE3.s ... verbose output shows as invocation: as -u -a64 -mppc64 -many -o CMakeFiles/protoc.dir/__/src/google/protobuf/compiler/main.cc.o /tmp/ccVqNDE3.s This is how the build is attempting to link main.cc.o into a binary: g++-8 -maix64 -pthread -D__STDC_FORMAT_MACROS -O2 -g -DNDEBUG -Wl,-bnoipath -Wl,-brtl -Wl,-bbigtoc -Wl,-bexpall CMakeFiles/protoc.dir/__/src/google/protobuf/compiler/main.cc.o -o protoc-3.6.1 -Wl,-blibpath:/path/to/lib64:/usr/lib:/lib libprotobuf.a libprotoc.a libprotobuf.a /path/to/lib64/libz.so Result of running verbose output on the link: COLLECT_GCC_OPTIONS='-maix64' '-pthread' '-D' '__STDC_FORMAT_MACROS' '-O2' '-g' '-D' 'NDEBUG' '-o' 'protoc-3.6.1' '-v' '-shared-libgcc' /path/to/gcc/bin/../libexec/gcc/powerpc-ibm-aix7.1.0.0/8.2.0/collect2 -bpT:0x10000000 -bpD:0x20000000 -btextro -b64 -L/path/to/lib64 -brtl -R /path/to/lib64 -bsvr4 -o protoc-3.6.1 /lib/crt0_64.o /path/to/gcc/bin/../lib/gcc/powerpc-ibm-aix7.1.0.0/8.2.0/pthread/ppc64/crtcxa.o /path/to/gcc/bin/../lib/gcc/powerpc-ibm-aix7.1.0.0/8.2.0/pthread/ppc64/crtdbase.o -L/path/to/gcc/lib/pthread/ppc64 -R /path/to/gcc/lib/pthread/ppc64 -L/path/to/gcc/bin/../lib/gcc/powerpc-ibm-aix7.1.0.0/8.2.0/pthread/ppc64 -L/path/to/gcc/bin/../lib/gcc/powerpc-ibm-aix7.1.0.0/8.2.0/../../../pthread/ppc64 -L/path/to/gcc/bin/../lib/gcc/powerpc-ibm-aix7.1.0.0/8.2.0 -L/path/to/gcc/bin/../lib/gcc -L/path/to/gcc/bin/../lib/gcc/powerpc-ibm-aix7.1.0.0/8.2.0/../../.. -bnoipath -brtl -bbigtoc -bexpall CMakeFiles/protoc.dir/__/src/google/protobuf/compiler/main.cc.o -blibpath:/path/to/lib64:/usr/lib:/lib libprotobuf.a libprotoc.a libprotobuf.a /path/to/lib64/libz.so -lstdc++ -lm -lgcc_s /path/to/gcc/bin/../lib/gcc/powerpc-ibm-aix7.1.0.0/8.2.0/pthread/ppc64/libgcc.a -lpthreads -lc -lgcc_s /path/to/gcc/bin/../lib/gcc/powerpc-ibm-aix7.1.0.0/8.2.0/pthread/ppc64/libgcc.a -brtl -R /path/to/lib64 ld: 0711-308 SEVERE ERROR: Object CMakeFiles/protoc.dir/__/src/google/protobuf/compiler/main.cc.o, csect <_main.ro_> The csect is part of the .text section. collect2: error: ld returned 12 exit status
Created attachment 45571 [details] g++-8 -S output for main.cc
The source code for main.cc is found here: https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/compiler/main.cc
Is protobufs even known to build on AIX? Whoever wrote the link command for AIX didn't know what they were doing and threw every option they could at the problem until it appeared to work. This is wrong. -bexpall -bsvr4 -brtl likely is very wrong. Until it's proven that this isn't cockpit error, this won't be analyzed or fixed.
David, -brtl and -bexpall are coming from CMake itself: https://gitlab.kitware.com/cmake/cmake/blob/master/Modules/Platform/AIX-XL.cmake *All* software (open-source and closed-source) using CMake as a build system uses these flags by default when building on AIX. AIX is hard enough to wrangle open-source software on -- don't shoot the messenger. I'm just trying to determine the root cause of the failure and I have no problem putting in the time to PR CMake or multiple projects to override these settings if I have to in order to fix their worldview of AIX. > Is protobufs even known to build on AIX? Like I said above, protobufs builds and runs fine on AIX using GCC 5. I only hit this when I try GCC 6+.
(In reply to Andrew Paprocki from comment #8) > David, -brtl and -bexpall are coming from CMake itself: > https://gitlab.kitware.com/cmake/cmake/blob/master/Modules/Platform/AIX-XL. > cmake > > *All* software (open-source and closed-source) using CMake as a build system > uses these flags by default when building on AIX. AIX is hard enough to > wrangle open-source software on -- don't shoot the messenger. And this is why I keep on saying to people CMAKE is much worse than auto-tools. They don't know what they are doing.
Protobufs didn't used to work on AIX. If it does, great. CMake on AIX is broken. AIX behaves differently for export of global symbols, yes, but -bexpall -- exporting all symbols -- is completely wrong. Also, I strongly doubt that Protobufs or the application requires runtime linking (-brtl). And this likely is the reason that -bbigtoc is added because rtl is pulling in all global functions for symbolic overriding which overflows the TOC. This is layer upon layer of incompetence. -bexpall likely is exporting symbols that should not be exported, causing collisions and/or forcing symbols into the a conflicting section. If one looks at libtool support for AIX (and GCC build), it explicitly builds an export file from a shell pipeline that utilizes "nm". It's not perfect, but a lot better and safer than exporting everything and hoping that nothing bad happens. Guess what? Something bad happened.
Not a GCC bug then?
There was a separately reported problem of _<filename>.rw_ in the text section. This was due to read_only_private_data_section. I have a patch proposed for that. _<filename>.ro_ should be part of the .text section. I don't see why it would contain relocations. Whoever wrote the AIX support for CMake did a very poor job and apparently didn't try to understand the semantics of AIX. It's sad that the CMake maintainers accepted such a broken patch.
What is the other bug number w/ patch that you're referring to?
I can reproduce this error with a much simpler project, pcre, that uses autotools and libtool. Using pcre 8.42 from https://ftp.pcre.org/pub/pcre/pcre-8.42.tar.gz $ mkdir build $ cd build $ CC=gcc-6 CXX=g++-6 OBJECT_MODE=32 CFLAGS="-maix32 -O" CXXFLAGS="-maix32 -O" ../configure --enable-unicode-properties --enable-pcre16 --enable-pcre32 --enable-jit $ OBJECT_MODE=32 make V=1 ... g++-6 -DHAVE_CONFIG_H -I. -I.. -maix32 -O -MT pcrecpp_unittest-pcrecpp_unittest.o -MD -MP -MF .deps/pcrecpp_unittest-pcrecpp_unittest.Tpo -c -o pcrecpp_unittest-pcrecpp_unittest.o `test -f 'pcrecpp_unittest.cc' || echo '../'`pcrecpp_unittest.cc mv -f .deps/pcrecpp_unittest-pcrecpp_unittest.Tpo .deps/pcrecpp_unittest-pcrecpp_unittest.Po /bin/sh ./libtool --tag=CXX --mode=link g++-6 -maix32 -O -o pcrecpp_unittest pcrecpp_unittest-pcrecpp_unittest.o libpcrecpp.la -lpthreads libtool: link: g++-6 -maix32 -O -o .libs/pcrecpp_unittest pcrecpp_unittest-pcrecpp_unittest.o -L/tmp/pcre/build/.libs -L./.libs -lpcrecpp -lpcre -L/path/to/gcc/lib -lstdc++ -lm -lpthreads -Wl,-blibpath:/usr/local/lib:/path/to/gcc/lib:/path/to/gcc/lib/.:/usr/lib:/lib ld: 0711-308 SEVERE ERROR: Object pcrecpp_unittest-pcrecpp_unittest.o, csect <_pcrecppunittest.ro_> The csect is part of the .text section. collect2: error: ld returned 12 exit status Makefile:1518: recipe for target 'pcrecpp_unittest' failed make[1]: *** [pcrecpp_unittest] Error 1 I've narrowed this down to the usage of the -bsvr4 linker flag, which we use because we depend on passing multiple -R parameters and the linker behavior described in the man page: -R Path ... Multiple instances of this option are concatenated together with each Path separated by a colon. If -bsvr4 is placed on the collect2 command line (obtained from -v output of the link), the link fails with the output above. I know in the past flag ordering has mattered, and in this case it fails in the same manner when it is both the first flag and last flag on the command line. This fails without any usage of -bexpall and -brtl.
Created attachment 46597 [details] g++-6 -S output of pcrecpp_unittest.cc Generated with the command line: g++-6 -DHAVE_CONFIG_H -I. -I.. -maix32 -O -MT pcrecpp_unittest-pcrecpp_unittest.o -MD -MP -MF .deps/pcrecpp_unittest-pcrecpp_unittest.Tpo -S ../pcrecpp_unittest.cc
I applied the patch to GCC to fix this. ATOS and IBM also are trying to work with CMake to fix the broken patches, but Kitware isn't being helpful and accommodating.
Thanks, I’m just interested in the URL / bug / commit for the patch(es) you created so that I can apply them to our in-house GCC and test everything out. If you could point me to them I’d appreciate it.
https://gcc.gnu.org/ml/gcc-patches/2019-04/msg00219.html
Thanks, I’ll give it a try. From memory, the .s file I attached did not contain any RW csect by the same name like you mention in the description, but perhaps the patch still addresses the issue.
I applied the patch and attempted to rebuild pcre and it still fails in the same manner: ld: 0711-308 SEVERE ERROR: Object pcrecpp_unittest-pcrecpp_unittest.o, csect <_pcrecppunittest.ro_> The csect is part of the .text section. Dumping the assembler (same as last attachment) shows only use of .ro_ as RO: $ grep _pcrecppunittest.ro_ pcrecpp_unittest.s .csect _pcrecppunittest.ro_[RO],4 .csect _pcrecppunittest.ro_[RO],4 .csect _pcrecppunittest.ro_[RO],4 .csect _pcrecppunittest.ro_[RO],4 .csect _pcrecppunittest.ro_[RO],4 .csect _pcrecppunittest.ro_[RO],4 .csect _pcrecppunittest.ro_[RO],4 .csect _pcrecppunittest.ro_[RO],4 .csect _pcrecppunittest.ro_[RO],4 .csect _pcrecppunittest.ro_[RO],4 .csect _pcrecppunittest.ro_[RO],4 There are a few places where this csect immediately follows a reference to .text, but I don't know if that is related at all. Those cases look like this: .csect .text[PR] .ref Lframe..1 .csect _pcrecppunittest.ro_[RO],4
This error message does not make any sense. The patch fixed the earlier error.
The GCC 7 branch is being closed, re-targeting to GCC 8.4.
we are seeing a similar error building our software stack. ld: 0711-308 SEVERE ERROR: Object /home/jnorth/builds/11-5.dev.4/obj/cosmos_9.engine.cli/engine/main.o, csect <_main.ro_> The csect is part of the .text section. collect2: error: ld returned 12 exit status any idea if this will make it into 8.4?
Confirmed. The patch already was applied to the GCC 8 branch. It's not clear what exact user code is continuing to triggering GCC to emit this unusual mapping.
GCC 8.4.0 has been released, adjusting target milestone.
Just re-summarizing now for 2020 since there have been a few twists and turns and distractions. This issue has nothing to do with CMake, -brtl, or -bexpall linker flags. This issue only occurs when GCC is told to pass the -bsvr4 linker flag, because the application wishes to use multiple -R parameters as documented in the man page (see comment 14). When that occurs, the error in this ticket happens. The already applied patches to GCC mentioned throughout the bug do not change any behavior -- it still fails to link. David, can you or someone on the linker team determine if this is an issue with the GCC side of things, or it is simply a bug in the linker? It is difficult for an outsider to determine if this is purely on the linker side or if GCC is not conforming somehow to what the linker expects.
60 second reproduction steps: $ curl -O https://ftp.pcre.org/pub/pcre/pcre-8.42.tar.gz $ tar zxvf pcre-8.42.tar.gz && cd pcre-8.42 $ CC="gcc-7" \ CXX="g++-7" \ CFLAGS="-maix32 -pthread" \ CXXFLAGS="-maix32 -pthread" \ LDFLAGS="-Wl,-bsvr4" \ ./configure && make -j It will fail: ld: 0711-308 SEVERE ERROR: Object pcre_stringpiece_unittest-pcre_stringpiece_unittest.o, csect <_pcrestringpieceunittest.ro_> The csect is part of the .text section. ld: 0711-308 SEVERE ERROR: Object pcre_scanner_unittest-pcre_scanner_unittest.o, csect <_pcrescannerunittest.ro_> The csect is part of the .text section. collect2: error: ld returned 12 exit status collect2: error: ld returned 12 exit status ld: 0711-308 SEVERE ERROR: Object pcrecpp_unittest-pcrecpp_unittest.o, csect <_pcrecppunittest.ro_> The csect is part of the .text section. collect2: error: ld returned 12 exit status
GCC 7 is no longer supported. The patch was backported and released in GCC 8.4 and GCC 9.1.
David, Using GCC 9.2.0 I can reproduce using the steps from comment 27. Did you run them yourself?
Yes, I can reproduce the error, but it only occurs when -bsvr4 is used. Have you looked at what -bsvr4 enables in the ld man page? Not just the -R comment. -brtl -brtllib -bexpfull -R, instead of being ignored, takes one suboption that defines the runtime library search path It seems that you're utilizing the -bsvr4 option to change the behavior of -R without regard for the other effects of the option. And the other changes to the default behavior of the AIX are breaking the build. -bsvr4 tries to provide a lot of SVR4 behavior, but is too course and big a club. [ ] Instead of using -bsvr4, I strongly suggest that you adjust / adapt the Makefile of your project and use the AIX linker -blibpath command line option to set the runtime library search path. I realize that there is no other AIX linker option to change the behavior of just -R, but you incorrectly are blaming the compiler for an error elicited by other, documented effects of the -bsvr4 linker option. AIX is not Solaris or Linux. There is no magic command line option to make AIX pretend to be Linux. The failure is not caused by a GCC bug and it's not caused by an AIX linker bug. GCC is behaving as designed. AIX linker is behaving as designed and documented. The -bsvr4 option has too many other effects to be used solely to work around the -R option.
Just to be clear, the -brtl allows runtime overriding symbols. GCC is correctly placing some symbols that should not be overridden in the text section. To allow the runtime overriding, which is not needed for this application/library, one needs to instruct the AIX linker to make the text section read-write. All of these other changes in behavior are triggered by the need to use -R to specify runtime library search path.
GCC 11.1 has been released, retargeting bugs to GCC 11.2.