Bug 38607 - AIX error messages about TOC during build
Summary: AIX error messages about TOC during build
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: bootstrap (show other bugs)
Version: 4.2.4
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL: http://gcc.gnu.org/ml/gcc-patches/201...
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2008-12-23 07:27 UTC by Rainer Tammer
Modified: 2013-03-25 20:53 UTC (History)
4 users (show)

See Also:
Host: powerpc-ibm-aix5.3.0.0
Target: powerpc-ibm-aix5.3.0.0
Build: powerpc-ibm-aix5.3.0.0
Known to work:
Known to fail:
Last reconfirmed: 2012-09-13 00:00:00


Attachments
build log (4.86 KB, text/plain)
2008-12-23 07:28 UTC, Rainer Tammer
Details
gcc-4.2.4-aix.patch (635 bytes, text/plain)
2008-12-23 07:28 UTC, Rainer Tammer
Details
gcc-4.2.4-1.spec (3.73 KB, text/plain)
2008-12-23 07:28 UTC, Rainer Tammer
Details
g++.sum (10.90 KB, text/plain)
2008-12-26 09:06 UTC, Rainer Tammer
Details
gcc.sum (481 bytes, text/plain)
2008-12-26 09:07 UTC, Rainer Tammer
Details
libstdc++.sum (2.02 KB, text/plain)
2008-12-26 09:10 UTC, Rainer Tammer
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Rainer Tammer 2008-12-23 07:27:13 UTC
Hello,
I just started my own build of 4.2.4. During stage3 I get the following errors:

ld: 0711-768 WARNING: Object
../libsupc++/.libs/libsupc++convenience.a[eh_terminate.o], section 1, function
.__cxxabiv1::__terminate(void (*)()):
        The branch at address 0x13c is not followed by a recognized no-op
        or TOC-reload instruction. The unrecognized instruction is 0x0.
ld: 0711-768 WARNING: Object
../libsupc++/.libs/libsupc++convenience.a[eh_terminate.o], section 1, function
.std::terminate():
        The branch at address 0x194 is not followed by a recognized no-op
        or TOC-reload instruction. The unrecognized instruction is 0x0.

see attached log...

I found one interesting thing:

The call (for .libs/libstdc++.so.6) which produced the error messaged ends in:
  ${wl}-berok
Should this not be:
  -Wl,-berok
??

Bye
  Rainer Tammer

P.S.: Please see the last updates in http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38547
Comment 1 Rainer Tammer 2008-12-23 07:28:11 UTC
Created attachment 16971 [details]
build log
Comment 2 Rainer Tammer 2008-12-23 07:28:34 UTC
Created attachment 16972 [details]
gcc-4.2.4-aix.patch
Comment 3 Rainer Tammer 2008-12-23 07:28:52 UTC
Created attachment 16973 [details]
gcc-4.2.4-1.spec
Comment 4 Andrew Pinski 2008-12-23 17:15:40 UTC
First off, stop building with patches, that makes it harder to figure out what is going on.
Comment 5 Rainer Tammer 2008-12-24 11:13:18 UTC
Hello,
the patch did not affect this problem. 
I have started a new build without the patch and the problem is still the same.

I especially do not understand why the linker call for libstdc++.so.6 ends in ${wl}-berok and not in -Wl,-berok. It looks like something got not substituted. Could this be related to libtool ?? The build machine has libtool 1.5.26 installed.

Bye
  Rainer
Comment 6 Rainer Tammer 2008-12-24 15:45:45 UTC
Hello,
in addition to IBM XLC/C++ V9 I have tried gcc 4.2.4 (from www.perzl.org) to bootstrap 4.2.4. The error is always the same. The build finishes but according to the log the libstdc++.so.6 is not OK. 

I have used the unmodified source. With the following options:

export PATH=/opt/freeware/bin:$PATH
export CONFIG_SHELL=/opt/freeware/bin/bash
export CONFIGURE_ENV_ARGS=/opt/freeware/bin/bash
export CC=gcc
export BOOT_CFLAGS="-O2 -I/opt/freeware/include"
export CFLAGS="-O2 -I/opt/freeware/include"
export CXXFLAGS="-I/opt/freeware/include"
export LIBCFLAGS="-g -O2 -I/opt/freeware/include"
export LIBCXXFLAGS="-g -O2 -I/opt/freeware/include -fno-implicit-templates"
export LDFLAGS="-L/opt/freeware/lib"

./configure \
 --with-as=/usr/bin/as \
 --with-ld=/usr/bin/ld \
 --enable-languages="c,c++,fortran" \
 --prefix=/opt/freeware \
 --enable-threads \
 --enable-version-specific-runtime-libs \
 --disable-nls \
 --enable-decimal-float=dpd \
 --host=powerpc-ibm-aix5.3.0.0

ulimit -d unlimited
ulimit -s unlimited
gmake bootstrap-lean


I see two problems:

1. substitution problem in the linker call for libstdc++.so.6,libgfortran.so.2, libgomp.so.1,  :

... -Wl,-bnoentry ${wl}-berok

Why is ${wl} not replaced with -Wl, as for -bnoentry ??

2. TOC problem for libstdc++.so.6

ld: 0711-768 WARNING: Object ../libsupc++/.libs/libsupc++convenience.a[eh_terminate.o], section 1
, function .__cxxabiv1::__terminate(void (*)()):
        The branch at address 0x310 is not followed by a recognized no-op
        or TOC-reload instruction. The unrecognized instruction is 0x0.
ld: 0711-768 WARNING: Object ../libsupc++/.libs/libsupc++convenience.a[eh_terminate.o], section 1
, function .std::terminate():
        The branch at address 0x370 is not followed by a recognized no-op
        or TOC-reload instruction. The unrecognized instruction is 0x0.
ld: 0711-768 WARNING: Object ../libsupc++/.libs/libsupc++convenience.a[tinfo.o], section 1, funct
ion .std::type_info::~type_info():
        The branch at address 0x12a0 is not followed by a recognized no-op
        or TOC-reload instruction. The unrecognized instruction is 0x38000000.
.... 

The resulting library is not OK. This is definitely a problem.

Bye
  Rainer
Comment 7 Rainer Tammer 2008-12-26 08:37:51 UTC
Hello,
this problem is present for every call to xgcc with the output of "-o .libs/libstdc++.so.6".

The resulting library is not correct for AIX.

The error message (example):

ld: 0711-768 WARNING: Object ../libsupc++/.libs/libsupc++convenience.a[vec.o], section 1, function .__cxa_vec_ctor:
        The branch at address 0xef4 is not followed by a recognized no-op
        or TOC-reload instruction. The unrecognized instruction is 0x801F0038.

says that a function is marked as local but instead resolves to a shared library function.

See: http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=/com.ibm.xlcpp8a.doc/compiler/ref/ruoptprc.htm

Bye
  Rainer
Comment 8 Rainer Tammer 2008-12-26 08:52:19 UTC
Hello,
one small addition. I have tried to add -Wl,-brtl to the xgcc calls (which produces the libstdc++.so.6) and as a result the ld errors are gone.

/powerpc-ibm-aix5.3.0.0/libstdc++-v3/src/Makefile

OPT_LDFLAGS = -Wl,-G -Wl,-brtl

Bye
  Rainer

Comment 9 Rainer Tammer 2008-12-26 09:06:43 UTC
Created attachment 16986 [details]
g++.sum
Comment 10 Rainer Tammer 2008-12-26 09:07:05 UTC
Created attachment 16987 [details]
gcc.sum
Comment 11 Rainer Tammer 2008-12-26 09:10:22 UTC
Created attachment 16988 [details]
libstdc++.sum
Comment 12 Rainer Tammer 2009-01-12 07:13:47 UTC
Hello,
any news ??
Bye
  Rainer
Comment 13 Michael Haubenwallner 2010-06-02 14:15:23 UTC
Very similar problem here with gcc-4.2.4 when using std:map<std:string, std:string> somewhere in application code - but not everywhere.

Linker warning is:
ld: 0711-768 WARNING: Object /path/to/library.a[objectfile.o], section 1, function .std::_Rb_tree<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::_Select1st<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::_M_erase(std::_Rb_tree_node<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >*):
    The branch at address 0x26a0 is not followed by a recognized no-op
    or TOC-reload instruction. The unrecognized instruction is 0x801F0048.

Maybe I'm completely wrong here, but this is what I found out:

On AIX, to-be-relocated branch-calls need a subsequent nop-call - ok so far.

Now there is above function, having mangled name _ZNSt8_Rb_treeISsSt4pairIKSsSsESt10_Select1stIS2_ESt4lessISsESaIS2_EE8_M_eraseEPSt13_Rb_tree_nodeIS2_E.
When compiling this function to assembly, or doing "/usr/vac/exe/dis objectfile.o", there is a bl-call to this very same function _not_ being followed by a nop-call (it is "lwz 0,124(31)" instead), but the linker still sees it as to-be-relocated - thus the warning.

This assembly can easily be generated by doing "g++ -S" on this code:

  #include <string>
  #include <map>
  void foo()
  {
    std::map<std::string, std::string> bar;
  }

Interesting enough, when I add an extra file containing this sample code to the application (objectfile ordering seems to matter), this linker warning goes away - so I'm still unable to create a small testcase to trigger this linker warning.

Thank you!
Comment 14 Michael Haubenwallner 2010-06-18 13:44:58 UTC
(In reply to comment #13)
>   #include <string>
>   #include <map>
>   void foo()
>   {
>     std::map<std::string, std::string> bar;
>   }

Simply compiling this source code into an rtl-enabled shared library leads to that linker warning, with both vanilla gcc-4.5.0 and gcc-4.4.4, configured to use native as and ld each, on AIX5.3 TL8.

$ g++ -shared -Wl,-G -o libshare.so test.cpp
ld: 0711-768 WARNING: Object /tmp//ccIju3gQ.o, section 1, function *SNIP*:
    The branch at address 0x618 is not followed by a recognized no-op
    or TOC-reload instruction. The unrecognized instruction is 0x801F007C.

The warning isn't shown with the '-bsymbolic' linker flag, as this one relocation is finally resolved locally and the subsequent 'nop' isn't needed.
But doing symbolic linking doesn't fit as workaround.
Thank you!
Comment 15 Lukasz Filipkowski 2011-09-23 10:10:58 UTC
Hello,
 
regarding ld: 0711-768 WARNING when compiling:

>   #include <string>
>   #include <map>
>   void foo()
>   {
>     std::map<std::string, std::string> bar;
>   }

into rtl-enabled shared library. Warning is caused by code construction similar to the one presented in the following example:

   //g++ -save-temps -shared -Wl,-G -o libshare.so share.cc
   #include <iostream>
   #include <string>
   using namespace std;

   template<typename Key> class MyClass
   {
    public:
     typedef Key KeyType;
     MyClass(KeyType aNumber)
     {
         cout << aNumber << "! = " << factorial(aNumber) << endl;
     }
     ~MyClass(){}
    private:
     long factorial(KeyType __x);
     long factorialHelper(KeyType __x);
   };

   template<typename Key> long MyClass<Key>::factorial(KeyType __x)
   {
    if (__x <= 0) return 1;
    else return __x * factorial(__x-1);
    //else return __x * factorialHelper(__x-1);
   }

   template<typename Key> long MyClass<Key>::factorialHelper(KeyType __x)
   {
    return factorial(__x);
   }

   void foo()
   {
    MyClass<int> myClass(5);
   }


$ g++ -save-temps -shared -Wl,-G -o libshare.so share.cc
ld: 0711-768 WARNING: Object share.o, section 1, function .MyClass<int>::factorial(int):
        The branch at address 0x36c is not followed by a recognized no-op
        or TOC-reload instruction. The unrecognized instruction is 0x7C691B78.


Example code is based on contents of stl_tree.h file in which class _Rb_tree is defined. 
Warning is generated in case creation of shared libraries using TEMPLATE CLASSES with RECURSIVE METHODS.
In the presented example "factorial" method is a recursive one.

When modifying:

   template<typename Key> long MyClass<Key>::factorial(KeyType __x)
   {
    if (__x <= 0) return 1;
    else return __x * factorial(__x-1);
    //else return __x * factorialHelper(__x-1);
   }

into:

   template<typename Key> long MyClass<Key>::factorial(KeyType __x)
   {
    if (__x <= 0) return 1;
    //else return __x * factorial(__x-1);
    else return __x * factorialHelper(__x-1);
   }

there is no linker warning.


The _Rb_tree class, defined in stl_tree.h, contains _M_erase and _M_copy methods, both recursive.

Warning is present when using both GCC4.4.5 and GCC4.6.1 on AIX 5300-11-03-1013 (AIX5.3 TL11 SP03)
When using assembler program (as) from AIX 5300-08-02-0822 (AIX5.3 TL08 SP02) there is no warning generated.

I'm not sure but problematic warning might be a result of fixes similar to https://www-304.ibm.com/support/docview.wss?uid=isg1IZ24688
Comment 16 sumamb 2012-06-20 11:25:30 UTC
This is a compiler problem. This issue is not generated due to the apar IZ24688.

The g++ code is as below.
   #include 
   #include 
   using namespace std;

   template class MyClass
   {
    public:
     typedef Key KeyType;
     MyClass(KeyType aNumber)
     {
         cout << aNumber << "! = " << factorial(aNumber)
 << endl;
     }
     ~MyClass(){}
    private:
     long factorial(KeyType __x);
     long factorialHelper(KeyType __x);
   };

   template long MyClass::factorial
(KeyType __x)
   {
    if (__x <= 0) return 1;
    else return __x * factorial(__x-1);
    //else return __x * factorialHelper(__x-1);
   }

   template long MyClass::
factorialHelper(KeyType __x)
   {
    return factorial(__x);
   }

   void foo()
   {
    MyClass myClass(5);
   }




Compile with:
g++ -save-temps -shared -Wl,-G -o libshare.so share.cc


The error received will be:
ld: 0711-768 WARNING: Object share.o, section 1,
function .MyClass::factorial(int):
        The branch at address 0x36c is not followed
 by a recognized no-op
        or TOC-reload instruction. The unrecognized
instruction is 0x7C691B78.


Here is an explanation from the problem we see with a below example.


	.csect .foo[PR]
.x:	code for x...
.globl .x

.z:	nop
.y:	code for y...
.globl .y

	.csect .bar[PR]
	...
	bl	.y

The "bl .y" and ".y:" are in different csects, so the "bl" requires an
RLD.  Note that the "bl .y" could also be written as:

	bl	.z + 4
or as
	bl	.foo[PR] + (.y - .x)

The generated code would look the same, but the corresponding RLDs
might refer to different symbols.  That is, "bl .y" would have an RLD
referring to .y, "bl .z+4" would have an RLD referring to .z, and
"bl .foo[PR] + (.y-.x)" would have an RLD referring to .foo[PR].

In the g++ example above, the -G linker flag causes glink code to be used
for all function calls to exported symobls.  These calls need to be
followed by a TOC reload instruction.  If .y were not exported, no
warning would occur.

There are a few possible compiler fixes:

1)	Use ".lglobl .y" instead of ".globl .y"  This will keep .y from
	being exported.
2)	Add another label at the same address and use .lglobl with the
	label.  (The assembler could do this, but it would change the
	behavior of the program, because .y would no longer be superceded by
	the runtime linker.

.y:	
	.globl .y
.y_local: .lglobl .y_local
	...
	bl	.y_local

Since .y_local cannot be exported, no nop instruction is needed after "bl".

Finally, it is possible for the compiler source code to be:

	.csect .foo[PR]
	...
.y:	
	...
	.csect .bar[PR]
	...
	bl	.y

In this case, .y is not in the output symbol table at all, so the RLD
must refer to the csect .foo[PR].  If this symbol is global and
exported, a warning will still be seen for the missing nop.
Regardless, if branch overflow occurs, this particular branch might
not be able to be fixed up.
Comment 17 sumamb 2012-06-20 12:01:51 UTC
(In reply to comment #16)
Comment 18 François Bissey 2012-06-21 00:54:06 UTC
I also got this on aix 6.1 with gcc-4.6.3 and 4.7.0. I also see it affecting program compiled with g++ (gnu octave 3.6.1 in fact). I get the same kind of TOC warning for octave and when I try to launch it misses two symbols that should be in libstdc++ (or possibly liibsup++).

I tried to add -Wl,-brtl into configure.host while the warning did go away while compiling gcc, octave still had the same problem so that's just hiding the symptoms and not curing the disease.
Comment 19 David Edelsohn 2012-09-13 20:10:17 UTC
First, this is a warning from the AIX linker, not an error and not a failure.  The warning technically is correct but slightly misleading and should not cause problems.

When the libstdc++ shared library is created for AIX, all global symbols are exported.  AIX does not understand "visibility" decorations, but GCC uses it to determine if a function will be local to a translation unit, not requiring a "nop" after the call. Because they symbols are global and exported, the linker complains.

GCC -fpic/-fPIC (XLC -qpic) no longer means position independent code, but that the code will be used in a shared library.  XLC defaults to -qpic, GCC does not.  Changing GCC for AIX to the XLC default causes other problems, so the best solution is to add -fPIC to the link line of shared libraries so that GCC on AIX looks more like GCC on Linux, which is what the patch does.  This removes all but one warning, which probably is due to a latent bug in G++ itself.
Comment 20 David Edelsohn 2012-09-14 23:23:45 UTC
Author: dje
Date: Fri Sep 14 23:23:41 2012
New Revision: 191316

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=191316
Log:
        PR target/38607
        Merge upstream change.
        * libtool.m4 (_LT_COMPILER_PIC): Add -fPIC to GCC and GXX for AIX.

	* configure.ac: Add target-libquadmath to noconfigdirs for AIX.
        Add libgomp*.o to compare_exclusions for AIX.
        * configure: Regenerate.

Modified:
    trunk/ChangeLog
    trunk/configure.ac
    trunk/libtool.m4
Comment 21 David Edelsohn 2013-03-25 20:53:17 UTC
The change to libtool to invoke GCC with -fPIC fixes most of the issues.  The remaining issue (tail recursion in libstdc++) is a incorrect warning from the AIX linker because it does not recognize that the target of the call -- a function declared weak because it could be overridden -- is itself.