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 invokation 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