Home | History | Annotate | Download | only in coregrind
      1 #! @PERL@
      2 
      3 # Generic information about a purpose of this script can be found in
      4 # link_tool_exe_linux.in.
      5 #
      6 # Solaris specific notes:
      7 #
      8 # - load address has to be specified in the mapfile, there is no command line
      9 #   option to achieve that
     10 #
     11 # - mapfile version 2 is used
     12 #
     13 # - information about Solaris linker can be found in its man page
     14 #   (http://download.oracle.com/docs/cd/E19253-01/816-5165/ld-1/index.html)
     15 #   and in Oracle's Linker and Libraries Guide
     16 #   (http://download.oracle.com/docs/cd/E19963-01/html/819-0690/index.html)
     17 #
     18 
     19 use warnings;
     20 use strict;
     21 use File::Temp qw/tempfile unlink0/;
     22 use Fcntl qw/F_SETFD/;
     23 
     24 # expect at least: alt-load-address gcc -o foo bar.o
     25 die "Not enough arguments"
     26     if (($#ARGV + 1) < 5);
     27 
     28 my $ala = $ARGV[0];
     29 
     30 # check for plausible-ish alt load address
     31 die "Bogus alt-load address"
     32     if (length($ala) < 3 || index($ala, "0x") != 0);
     33 
     34 # the cc invocation to do the final link
     35 my $cc = $ARGV[1];
     36 
     37 # and the 'restargs' are argv[2 ..]
     38 
     39 # create a temporary mapfile
     40 (my $fh, my $path) = tempfile();
     41 
     42 # reset FD_CLOEXEC flag
     43 fcntl($fh, F_SETFD, 0)
     44     or die "Can't clear close-on-exec flag on temp fh: $!";
     45 
     46 # safely unlink the file
     47 unlink0($fh, $path)
     48     or die "Error unlinking file $path safely";
     49 undef $path;
     50 
     51 # fill it with data
     52 #
     53 # this is a bit tricky, the problem is that the following condition has to be
     54 # true for both PT_LOAD segments:
     55 # (phdr->p_vaddr & PAGEOFFSET) == (phdr->p_offset & PAGEOFFSET)
     56 # if it doesn't hold then the kernel maps a segment as an anon mapping instead
     57 # of a file mapping (which, for example, breaks reading debug information)
     58 print $fh <<"END";
     59 \$mapfile_version 2
     60 LOAD_SEGMENT text { VADDR = $ala; ROUND = 0x1000 };
     61 LOAD_SEGMENT data { ROUND = 0x1000 };
     62 END
     63 
     64 # build up the complete command here:
     65 # 'cc' -Wl,-Mtmpfile 'restargs'
     66 
     67 my $cmd="$cc -Wl,-M/proc/$$/fd/" . fileno($fh);
     68 
     69 # add the rest of the parameters
     70 foreach my $n (2 .. $#ARGV) {
     71     $cmd = "$cmd $ARGV[$n]";
     72 }
     73 
     74 #print "link_tool_exe_solaris: $cmd\n";
     75 
     76 
     77 # execute the command:
     78 my $r = system("$cmd");
     79 
     80 if ($r == 0) {
     81     exit 0;
     82 } else {
     83     exit 1;
     84 }
     85