• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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