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 19use warnings; 20use strict; 21use File::Temp qw/tempfile unlink0/; 22use Fcntl qw/F_SETFD/; 23 24# expect at least: alt-load-address gcc -o foo bar.o 25die "Not enough arguments" 26 if (($#ARGV + 1) < 5); 27 28my $ala = $ARGV[0]; 29 30# check for plausible-ish alt load address 31die "Bogus alt-load address" 32 if (length($ala) < 3 || index($ala, "0x") != 0); 33 34# the cc invocation to do the final link 35my $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 43fcntl($fh, F_SETFD, 0) 44 or die "Can't clear close-on-exec flag on temp fh: $!"; 45 46# safely unlink the file 47unlink0($fh, $path) 48 or die "Error unlinking file $path safely"; 49undef $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) 58print $fh <<"END"; 59\$mapfile_version 2 60LOAD_SEGMENT text { VADDR = $ala; ROUND = 0x1000 }; 61LOAD_SEGMENT data { ROUND = 0x1000 }; 62END 63 64# build up the complete command here: 65# 'cc' -Wl,-Mtmpfile 'restargs' 66 67my $cmd="$cc -Wl,-M/proc/$$/fd/" . fileno($fh); 68 69# add the rest of the parameters 70foreach 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: 78my $r = system("$cmd"); 79 80if ($r == 0) { 81 exit 0; 82} else { 83 exit 1; 84} 85