This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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";

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]