File: link_tool_exe_darwin.in

package info (click to toggle)
valgrind 1%3A3.24.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 176,332 kB
  • sloc: ansic: 795,029; exp: 26,134; xml: 23,472; asm: 14,393; cpp: 9,397; makefile: 7,464; sh: 6,122; perl: 5,446; python: 1,498; javascript: 981; awk: 166; csh: 1
file content (199 lines) | stat: -rw-r--r-- 5,454 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#! @PERL@

# This script handles linking the tool executables on Linux,
# statically and at an alternative load address.
#
# Linking statically sidesteps all sorts of complications to do with
# having two copies of the dynamic linker (valgrind's and the
# client's) coexisting in the same process.  The alternative load
# address is needed because Valgrind itself will load the client at
# whatever address it specifies, which is almost invariably the
# default load address.  Hence we can't allow Valgrind itself (viz,
# the tool executable) to be loaded at that address.
#
# Unfortunately there's no standard way to do 'static link at
# alternative address', so these link_tool_exe_*.in scripts handle
# the per-platform hoop-jumping.
#
# What we get passed here is:
#   first arg
#      the alternative load address
#   all the rest of the args
#      the gcc invocation to do the final link, that
#      the build system would have done, left to itself
#
# We just let the script 'die' if something is wrong, rather than do
# proper error reporting.  We don't expect the users to run this 
# directly.  It is only run as part of the build process, with 
# carefully constrained inputs.
#
#
# So: what we actually do is:
#
# Look at the specified gcc invocation.  Ignore all parts of it except
# the *.a, *.o and -o outfile parts.  Wrap them up in a new command
# which looks (eg) as follows:
#
#   (64-bit):
#
#   /usr/bin/ld -static -arch x86_64 -macosx_version_min 10.6 \
#      -o memcheck-amd64-darwin -u __start -e __start \
#      -image_base 0x158000000 -stack_addr 0x13c000000 \
#      -stack_size 0x800000 \
#      memcheck_amd*.o \
#      ../coregrind/libcoregrind-amd64-darwin.a \
#      ../VEX/libvex-amd64-darwin.a
#
#   (32-bit)
#
#   /usr/bin/ld -static -arch i386 -macosx_version_min 10.6 \
#      -o memcheck-x86-darwin -u __start -e __start \
#      -image_base 0x58000000 -stack_addr 0x3c000000 \
#      -stack_size 0x800000 \
#      memcheck_x86*.o \
#      ../coregrind/libcoregrind-x86-darwin.a \
#      ../VEX/libvex-x86-darwin.a
#
# The addresses shown above will actually work, although "for real" we
# of course need to take it from argv[1].  In these examples the stack
# is placed 64M after the executable start.  It is probably safer to
# place it 64M before the executable's start point, so the executable
# + data + bss can grow arbitrarily in future without colliding with
# the stack.
#
# There's one more twist: we need to know the word size of the
# executable for which we are linking.  We need to know this because
# we must tell the linker that, by handing it either "-arch x86_64" or
# "-arch i386".  Fortunately we can figure this out by scanning the
# gcc invocation, which itself must contain either "-arch x86_64" or
# "-arch i386".

use warnings;
use strict;
# we need to be able to do 64-bit arithmetic:
use Math::BigInt;


# User configurable constants: how far before the exe should we
# place the stack?
my $TX_STACK_OFFSET_BEFORE_TEXT = 64 * 1024 * 1024;

# and how big should the stack be?
my $TX_STACK_SIZE = 8 * 1024 * 1024;


# string -> bool
sub is_dota_or_doto($)
{
   my ($str) = @_;
   if ($str =~ /.\.a$/ || $str =~ /.\.o$/) {
      return 1;
   } else {
      return 0;
   }
}


# expect at least: alt-load-address gcc -o foo bar.o
die "Not enough arguments"
    if (($#ARGV + 1) < 5);

my $ala = $ARGV[0];  # the load address to use
my $cc  = $ARGV[1];  # the C compiler in use

# check for plausible-ish alt load address
die "Bogus alt-load address (1)"
    if (length($ala) < 3 || index($ala, "0x") != 0);

die "Bogus alt-load address (2)"
    if ($ala !~ /^0x[0-9a-fA-F]+$/);


# get hold of the outfile name (following "-o")
my $outname = "";

foreach my $n (2 .. $#ARGV - 1) {
    my $str = $ARGV[$n];
    if ($str eq "-o" && $outname eq "") {
        $outname = $ARGV[$n + 1];
    }
}

die "Can't find '-o outfilename' in command line"
    if ($outname eq "");


# get hold of the string following "-arch"
my $archstr = "";

foreach my $n (2 .. $#ARGV - 1) {
    my $str = $ARGV[$n];
    if ($str eq "-arch" && $archstr eq "") {
        $archstr = $ARGV[$n + 1];
    }
}

die "Can't find '-arch archstr' in command line"
    if ($archstr eq "");


# build the command line
my $cmd = "/usr/bin/ld";

$cmd = "$cmd -static";

# If we're building with clang (viz, the C compiler as specified
# by the 2nd arg ends in "clang"), we also need -new_linker.  See
# https://bugs.kde.org/show_bug.cgi?id=295427
if ("$cc" =~ /clang$/) {
    $cmd = "$cmd -new_linker";
}

$cmd = "$cmd -arch $archstr";
$cmd = "$cmd -macosx_version_min 10.6";
$cmd = "$cmd -o $outname";
$cmd = "$cmd -u __start -e __start";

my $stack_addr = Math::BigInt->new( $ala ) - $TX_STACK_OFFSET_BEFORE_TEXT;
my $stack_addr_str = $stack_addr->as_hex();
my $stack_size_str = Math::BigInt::as_hex($TX_STACK_SIZE);

$cmd = "$cmd -image_base $ala";
$cmd = "$cmd -stack_addr $stack_addr_str";
$cmd = "$cmd -stack_size $stack_size_str";

foreach my $n (2 .. $#ARGV) {
    my $str = $ARGV[$n];
    if (is_dota_or_doto($str)) {
        $cmd = "$cmd $str";
    }
}

print "link_tool_exe_darwin: $cmd\n";

# Execute the command:
my $r = system("$cmd");

if ($r != 0) {
   exit 1;
}


# and now kludge the tool exe
# see bug 267997

$cmd = "../coregrind/fixup_macho_loadcmds";
$cmd = "$cmd $stack_addr_str $stack_size_str $outname";

print "link_tool_exe_darwin: $cmd\n";

$r = system("$cmd");

if ($r != 0) {
   exit 1;
}




exit 0;