This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Using binutils-2.12.1 on sparc64-sun-solaris2.8 to build gcc-3.1 results in relocation errors
On Thursday 18 July 2002 03:21, David S. Miller wrote:
> I did make a brain fart though, "call" is valid in several situations,
> PIC function calls in particular because that goes through the PLT
> which will be near the code itself.
All the failing symbols are in gnu.linkonce sections. What happens when
symbols get deleted.
> A repeatable testcase from the bug reporter posted here and in GNATS
> would be highly appreciated so that something concrete can be done
> about this problem. Currently we are groveling over the bug because
> not enough information is present. A reproducable testcase would
> eliminate this problem.
I finally managed to create test case that fails. See the attached perl
script that creates files, libraries and tries to link them in the current
directory.
The script is slightly complex, since I had trouble reproducing it, and I
thought it must be number or size of the libraries. But it turns out that it
starts failing only when there is more than one object in the "main" program.
$ perl link-test.pl
g++ -m64 -mcpu=ultrasparc -fPIC -c l_1_1.cc
g++ -m64 -mcpu=ultrasparc -fPIC -c l_1_2.cc
g++ -m64 -mcpu=ultrasparc --shared -o libl_1.so l_1_1.o l_1_2.o -L`pwd`
g++ -m64 -mcpu=ultrasparc -c main_1.cc
g++ -m64 -mcpu=ultrasparc -c main_2.cc
g++ -m64 -mcpu=ultrasparc -o link-test main_1.o main_2.o -L`pwd` -ll_1
main_2.o(.eh_frame+0x70): relocation truncated to fit: R_SPARC_DISP32
.gnu.linkonce.t._ZN7foo_1_1D1Ev
main_2.o(.eh_frame+0x90): relocation truncated to fit: R_SPARC_DISP32
.gnu.linkonce.t._ZN7foo_1_110to_destroyC1Ev
main_2.o(.eh_frame+0xb0): relocation truncated to fit: R_SPARC_DISP32
.gnu.linkonce.t._ZN7foo_1_110to_destroyD1Ev
main_2.o(.eh_frame+0xd0): relocation truncated to fit: R_SPARC_DISP32
.gnu.linkonce.t._ZN7foo_1_18method_1Ev
main_2.o(.eh_frame+0xf0): relocation truncated to fit: R_SPARC_DISP32
.gnu.linkonce.t._ZN7foo_1_18method_2Ev
main_2.o(.eh_frame+0x110): relocation truncated to fit: R_SPARC_DISP32
.gnu.linkonce.t._ZN7foo_1_1C1Ev
collect2: ld returned 1 exit status
Teemu
#!/usr/bin/env perl
$num_libs = 1;
$num_classes = 2;
$num_methods = 2;
$num_mains = 2;
$gxx = "g++ -m64 -mcpu=ultrasparc";
# Build method declarations.
my $method_decl, @method_decl;
my $method_call, @method_call;
foreach $method (1 .. $num_methods) {
push (@method_decl, "void method_${method} () { throw 1; }");
push (@method_call, "to_destroy d_${method}; method_${method} ();");
}
$method_decl = join ("\n ", @method_decl);
$method_call = join ("\n ", @method_call);
foreach $lib (1 .. $num_libs) {
my @objs;
foreach $class (1 .. $num_classes) {
my $header = "l_${lib}_${class}.h";
open (HEADER, ">${header}") || die "Can not open $header";
print HEADER <<EOH;
#include <iostream>
#include <string>
struct foo_${lib}_${class}
{
typedef foo_${lib}_${class} self_type;
struct to_destroy
{
to_destroy () { self_type tem; tem.method_1 (); }
~to_destroy () { self_type tem; tem.method_1 (); }
};
foo_${lib}_${class} ()
{
$method_call
}
foo_${lib}_${class} (const self_type &)
{
$method_call
}
~foo_${lib}_${class} ()
{
$method_call
}
$method_decl
static self_type bar ();
std::string _a_string;
};
EOH
close (HEADER);
}
foreach $class (1 .. $num_classes) {
my $source = "l_${lib}_${class}.cc";
my $object = "l_${lib}_${class}.o";
open (SOURCE, ">${source}") || die "Can not open $source";
foreach $j (1 .. $lib) {
foreach $i (1 .. $num_classes) {
print SOURCE <<EOS1;
#include "l_${j}_${i}.h"
EOS1
}
}
print SOURCE <<EOS2;
foo_${lib}_${class}
foo_${lib}_${class}::bar ()
{
std::cout << "something to instanciate templates\\n";
EOS2
foreach $j (1 .. $lib) {
foreach $i (1 .. $num_classes) {
print SOURCE <<EOS3;
foo_${j}_${i}::bar ();
EOS3
}
}
print SOURCE <<EOS4;
return foo_${lib}_${class} ();
}
EOS4
close SOURCE;
my $compile = "${gxx} -fPIC -c $source";
print $compile, "\n";
system ($compile) && die "Compilation failed";
push (@objs, $object);
}
my $link
= "${gxx} --shared -o libl_${lib}.so "
. join (' ', @objs)
. " -L`pwd` "
. join (' ', @libs);
print $link, "\n";
system ($link) && die "Link failed";
push (@libs, "-ll_${lib}");
}
foreach $main (1 .. $num_mains) {
my $source = "main_${main}.cc";
my $object = "main_${main}.o";
open (MAIN, ">${source}") || die "Can not open ${source}";
foreach $lib (1 .. $num_libs) {
foreach $class (1 .. $num_classes) {
print MAIN <<EOM1;
#include "l_${lib}_${class}.h"
EOM1
}
}
my $main_name = ($main == 1 ? "main" : "main_${main}");
print MAIN <<EOM2;
int
${main_name} ()
{
EOM2
foreach $lib (1 .. $num_libs) {
foreach $class (1 .. $num_classes) {
next if ($class % 2 == 0);
print MAIN <<EOM3;
foo_${lib}_${class}::bar ();
EOM3
}
}
print MAIN <<EOM4;
return 0;
}
EOM4
close MAIN;
my $compile = "${gxx} -c $source";
print $compile, "\n";
system ($compile) && die "Compilation failed";
push (@mains, $object);
}
my $link = "${gxx} -o link-test "
. join (' ', @mains)
. " -L`pwd` " . join (' ', @libs);
print $link, "\n";
system ($link) && die "Link failed";