Merge lp:~bkerensa/ubuntu/raring/valgrind/merge-from-deb into lp:ubuntu/raring/valgrind
- Raring (13.04)
- merge-from-deb
- Merge into raring
Proposed by
Benjamin Kerensa
Status: | Work in progress |
---|---|
Proposed branch: | lp:~bkerensa/ubuntu/raring/valgrind/merge-from-deb |
Merge into: | lp:ubuntu/raring/valgrind |
Diff against target: | 551497 lines |
To merge this branch: | bzr merge lp:~bkerensa/ubuntu/raring/valgrind/merge-from-deb |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Logan Rosen (community) | Needs Fixing | ||
Ubuntu branches | Pending | ||
Review via email: mp+135558@code.launchpad.net |
Commit message
Description of the change
Merge from debian unstable
To post a comment you must log in.
Revision history for this message
Sebastien Bacher (seb128) wrote : | # |
setting to "work in progress" until the previous review comments are addressed, please set it back to "needs review" once that happens
Unmerged revisions
- 50. By Benjamin Kerensa
-
Merge from debian unstable
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === removed directory '.pc/0001-more-vg-n-segments.patch' |
2 | === removed directory '.pc/0001-more-vg-n-segments.patch/coregrind' |
3 | === removed directory '.pc/0001-more-vg-n-segments.patch/coregrind/m_aspacemgr' |
4 | === removed file '.pc/0001-more-vg-n-segments.patch/coregrind/m_aspacemgr/aspacemgr-linux.c' |
5 | --- .pc/0001-more-vg-n-segments.patch/coregrind/m_aspacemgr/aspacemgr-linux.c 2012-01-06 19:01:30 +0000 |
6 | +++ .pc/0001-more-vg-n-segments.patch/coregrind/m_aspacemgr/aspacemgr-linux.c 1970-01-01 00:00:00 +0000 |
7 | @@ -1,3594 +0,0 @@ |
8 | - |
9 | -/*--------------------------------------------------------------------*/ |
10 | -/*--- The address space manager: segment initialisation and ---*/ |
11 | -/*--- tracking, stack operations ---*/ |
12 | -/*--- ---*/ |
13 | -/*--- Implementation for Linux (and Darwin!) m_aspacemgr-linux.c ---*/ |
14 | -/*--------------------------------------------------------------------*/ |
15 | - |
16 | -/* |
17 | - This file is part of Valgrind, a dynamic binary instrumentation |
18 | - framework. |
19 | - |
20 | - Copyright (C) 2000-2011 Julian Seward |
21 | - jseward@acm.org |
22 | - |
23 | - This program is free software; you can redistribute it and/or |
24 | - modify it under the terms of the GNU General Public License as |
25 | - published by the Free Software Foundation; either version 2 of the |
26 | - License, or (at your option) any later version. |
27 | - |
28 | - This program is distributed in the hope that it will be useful, but |
29 | - WITHOUT ANY WARRANTY; without even the implied warranty of |
30 | - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
31 | - General Public License for more details. |
32 | - |
33 | - You should have received a copy of the GNU General Public License |
34 | - along with this program; if not, write to the Free Software |
35 | - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
36 | - 02111-1307, USA. |
37 | - |
38 | - The GNU General Public License is contained in the file COPYING. |
39 | -*/ |
40 | - |
41 | -#if defined(VGO_linux) || defined(VGO_darwin) |
42 | - |
43 | -/* ************************************************************* |
44 | - DO NOT INCLUDE ANY OTHER FILES HERE. |
45 | - ADD NEW INCLUDES ONLY TO priv_aspacemgr.h |
46 | - AND THEN ONLY AFTER READING DIRE WARNINGS THERE TOO. |
47 | - ************************************************************* */ |
48 | - |
49 | -#include "priv_aspacemgr.h" |
50 | -#include "config.h" |
51 | - |
52 | - |
53 | -/* Note: many of the exported functions implemented below are |
54 | - described more fully in comments in pub_core_aspacemgr.h. |
55 | -*/ |
56 | - |
57 | - |
58 | -/*-----------------------------------------------------------------*/ |
59 | -/*--- ---*/ |
60 | -/*--- Overview. ---*/ |
61 | -/*--- ---*/ |
62 | -/*-----------------------------------------------------------------*/ |
63 | - |
64 | -/* Purpose |
65 | - ~~~~~~~ |
66 | - The purpose of the address space manager (aspacem) is: |
67 | - |
68 | - (1) to record the disposition of all parts of the process' address |
69 | - space at all times. |
70 | - |
71 | - (2) to the extent that it can, influence layout in ways favourable |
72 | - to our purposes. |
73 | - |
74 | - It is important to appreciate that whilst it can and does attempt |
75 | - to influence layout, and usually succeeds, it isn't possible to |
76 | - impose absolute control: in the end, the kernel is the final |
77 | - arbiter, and can always bounce our requests. |
78 | - |
79 | - Strategy |
80 | - ~~~~~~~~ |
81 | - The strategy is therefore as follows: |
82 | - |
83 | - * Track ownership of mappings. Each one can belong either to |
84 | - Valgrind or to the client. |
85 | - |
86 | - * Try to place the client's fixed and hinted mappings at the |
87 | - requested addresses. Fixed mappings are allowed anywhere except |
88 | - in areas reserved by Valgrind; the client can trash its own |
89 | - mappings if it wants. Hinted mappings are allowed providing they |
90 | - fall entirely in free areas; if not, they will be placed by |
91 | - aspacem in a free area. |
92 | - |
93 | - * Anonymous mappings are allocated so as to keep Valgrind and |
94 | - client areas widely separated when possible. If address space |
95 | - runs low, then they may become intermingled: aspacem will attempt |
96 | - to use all possible space. But under most circumstances lack of |
97 | - address space is not a problem and so the areas will remain far |
98 | - apart. |
99 | - |
100 | - Searches for client space start at aspacem_cStart and will wrap |
101 | - around the end of the available space if needed. Searches for |
102 | - Valgrind space start at aspacem_vStart and will also wrap around. |
103 | - Because aspacem_cStart is approximately at the start of the |
104 | - available space and aspacem_vStart is approximately in the |
105 | - middle, for the most part the client anonymous mappings will be |
106 | - clustered towards the start of available space, and Valgrind ones |
107 | - in the middle. |
108 | - |
109 | - The available space is delimited by aspacem_minAddr and |
110 | - aspacem_maxAddr. aspacem is flexible and can operate with these |
111 | - at any (sane) setting. For 32-bit Linux, aspacem_minAddr is set |
112 | - to some low-ish value at startup (64M) and aspacem_maxAddr is |
113 | - derived from the stack pointer at system startup. This seems a |
114 | - reliable way to establish the initial boundaries. |
115 | - |
116 | - 64-bit Linux is similar except for the important detail that the |
117 | - upper boundary is set to 32G. The reason is so that all |
118 | - anonymous mappings (basically all client data areas) are kept |
119 | - below 32G, since that is the maximum range that memcheck can |
120 | - track shadow memory using a fast 2-level sparse array. It can go |
121 | - beyond that but runs much more slowly. The 32G limit is |
122 | - arbitrary and is trivially changed. So, with the current |
123 | - settings, programs on 64-bit Linux will appear to run out of |
124 | - address space and presumably fail at the 32G limit. Given the |
125 | - 9/8 space overhead of Memcheck, that means you should be able to |
126 | - memcheckify programs that use up to about 14G natively. |
127 | - |
128 | - Note that the aspacem_minAddr/aspacem_maxAddr limits apply only to |
129 | - anonymous mappings. The client can still do fixed and hinted maps |
130 | - at any addresses provided they do not overlap Valgrind's segments. |
131 | - This makes Valgrind able to load prelinked .so's at their requested |
132 | - addresses on 64-bit platforms, even if they are very high (eg, |
133 | - 112TB). |
134 | - |
135 | - At startup, aspacem establishes the usable limits, and advises |
136 | - m_main to place the client stack at the top of the range, which on |
137 | - a 32-bit machine will be just below the real initial stack. One |
138 | - effect of this is that self-hosting sort-of works, because an inner |
139 | - valgrind will then place its client's stack just below its own |
140 | - initial stack. |
141 | - |
142 | - The segment array and segment kinds |
143 | - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
144 | - The central data structure is the segment array (segments[0 |
145 | - .. nsegments_used-1]). This covers the entire address space in |
146 | - order, giving account of every byte of it. Free spaces are |
147 | - represented explicitly as this makes many operations simpler. |
148 | - Mergeable adjacent segments are aggressively merged so as to create |
149 | - a "normalised" representation (preen_nsegments). |
150 | - |
151 | - There are 7 (mutually-exclusive) segment kinds, the meaning of |
152 | - which is important: |
153 | - |
154 | - SkFree: a free space, which may be allocated either to Valgrind (V) |
155 | - or the client (C). |
156 | - |
157 | - SkAnonC: an anonymous mapping belonging to C. For these, aspacem |
158 | - tracks a boolean indicating whether or not is is part of the |
159 | - client's heap area (can't remember why). |
160 | - |
161 | - SkFileC: a file mapping belonging to C. |
162 | - |
163 | - SkShmC: a shared memory segment belonging to C. |
164 | - |
165 | - SkAnonV: an anonymous mapping belonging to V. These cover all V's |
166 | - dynamic memory needs, including non-client malloc/free areas, |
167 | - shadow memory, and the translation cache. |
168 | - |
169 | - SkFileV: a file mapping belonging to V. As far as I know these are |
170 | - only created transiently for the purposes of reading debug info. |
171 | - |
172 | - SkResvn: a reservation segment. |
173 | - |
174 | - These are mostly straightforward. Reservation segments have some |
175 | - subtlety, however. |
176 | - |
177 | - A reservation segment is unmapped from the kernel's point of view, |
178 | - but is an area in which aspacem will not create anonymous maps |
179 | - (either Vs or Cs). The idea is that we will try to keep it clear |
180 | - when the choice to do so is ours. Reservation segments are |
181 | - 'invisible' from the client's point of view: it may choose to park |
182 | - a fixed mapping in the middle of one, and that's just tough -- we |
183 | - can't do anything about that. From the client's perspective |
184 | - reservations are semantically equivalent to (although |
185 | - distinguishable from, if it makes enquiries) free areas. |
186 | - |
187 | - Reservations are a primitive mechanism provided for whatever |
188 | - purposes the rest of the system wants. Currently they are used to |
189 | - reserve the expansion space into which a growdown stack is |
190 | - expanded, and into which the data segment is extended. Note, |
191 | - though, those uses are entirely external to this module, which only |
192 | - supplies the primitives. |
193 | - |
194 | - Reservations may be shrunk in order that an adjoining anonymous |
195 | - mapping may be extended. This makes dataseg/stack expansion work. |
196 | - A reservation may not be shrunk below one page. |
197 | - |
198 | - The advise/notify concept |
199 | - ~~~~~~~~~~~~~~~~~~~~~~~~~ |
200 | - All mmap-related calls must be routed via aspacem. Calling |
201 | - sys_mmap directly from the rest of the system is very dangerous |
202 | - because aspacem's data structures will become out of date. |
203 | - |
204 | - The fundamental mode of operation of aspacem is to support client |
205 | - mmaps. Here's what happens (in ML_(generic_PRE_sys_mmap)): |
206 | - |
207 | - * m_syswrap intercepts the mmap call. It examines the parameters |
208 | - and identifies the requested placement constraints. There are |
209 | - three possibilities: no constraint (MAny), hinted (MHint, "I |
210 | - prefer X but will accept anything"), and fixed (MFixed, "X or |
211 | - nothing"). |
212 | - |
213 | - * This request is passed to VG_(am_get_advisory). This decides on |
214 | - a placement as described in detail in Strategy above. It may |
215 | - also indicate that the map should fail, because it would trash |
216 | - one of Valgrind's areas, which would probably kill the system. |
217 | - |
218 | - * Control returns to the wrapper. If VG_(am_get_advisory) has |
219 | - declared that the map should fail, then it must be made to do so. |
220 | - Usually, though, the request is considered acceptable, in which |
221 | - case an "advised" address is supplied. The advised address |
222 | - replaces the original address supplied by the client, and |
223 | - MAP_FIXED is set. |
224 | - |
225 | - Note at this point that although aspacem has been asked for |
226 | - advice on where to place the mapping, no commitment has yet been |
227 | - made by either it or the kernel. |
228 | - |
229 | - * The adjusted request is handed off to the kernel. |
230 | - |
231 | - * The kernel's result is examined. If the map succeeded, aspacem |
232 | - is told of the outcome (VG_(am_notify_client_mmap)), so it can |
233 | - update its records accordingly. |
234 | - |
235 | - This then is the central advise-notify idiom for handling client |
236 | - mmap/munmap/mprotect/shmat: |
237 | - |
238 | - * ask aspacem for an advised placement (or a veto) |
239 | - |
240 | - * if not vetoed, hand request to kernel, using the advised placement |
241 | - |
242 | - * examine result, and if successful, notify aspacem of the result. |
243 | - |
244 | - There are also many convenience functions, eg |
245 | - VG_(am_mmap_anon_fixed_client), which do both phases entirely within |
246 | - aspacem. |
247 | - |
248 | - To debug all this, a sync-checker is provided. It reads |
249 | - /proc/self/maps, compares what it sees with aspacem's records, and |
250 | - complains if there is a difference. --sanity-level=3 runs it before |
251 | - and after each syscall, which is a powerful, if slow way of finding |
252 | - buggy syscall wrappers. |
253 | - |
254 | - Loss of pointercheck |
255 | - ~~~~~~~~~~~~~~~~~~~~ |
256 | - Up to and including Valgrind 2.4.1, x86 segmentation was used to |
257 | - enforce seperation of V and C, so that wild writes by C could not |
258 | - trash V. This got called "pointercheck". Unfortunately, the new |
259 | - more flexible memory layout, plus the need to be portable across |
260 | - different architectures, means doing this in hardware is no longer |
261 | - viable, and doing it in software is expensive. So at the moment we |
262 | - don't do it at all. |
263 | -*/ |
264 | - |
265 | - |
266 | -/*-----------------------------------------------------------------*/ |
267 | -/*--- ---*/ |
268 | -/*--- The Address Space Manager's state. ---*/ |
269 | -/*--- ---*/ |
270 | -/*-----------------------------------------------------------------*/ |
271 | - |
272 | -/* ------ start of STATE for the address-space manager ------ */ |
273 | - |
274 | -/* Max number of segments we can track. */ |
275 | -#define VG_N_SEGMENTS 5000 |
276 | - |
277 | -/* Max number of segment file names we can track. */ |
278 | -#define VG_N_SEGNAMES 1000 |
279 | - |
280 | -/* Max length of a segment file name. */ |
281 | -#define VG_MAX_SEGNAMELEN 1000 |
282 | - |
283 | - |
284 | -typedef |
285 | - struct { |
286 | - Bool inUse; |
287 | - Bool mark; |
288 | - HChar fname[VG_MAX_SEGNAMELEN]; |
289 | - } |
290 | - SegName; |
291 | - |
292 | -/* Filename table. _used is the high water mark; an entry is only |
293 | - valid if its index >= 0, < _used, and its .inUse field == True. |
294 | - The .mark field is used to garbage-collect dead entries. |
295 | -*/ |
296 | -static SegName segnames[VG_N_SEGNAMES]; |
297 | -static Int segnames_used = 0; |
298 | - |
299 | - |
300 | -/* Array [0 .. nsegments_used-1] of all mappings. */ |
301 | -/* Sorted by .addr field. */ |
302 | -/* I: len may not be zero. */ |
303 | -/* I: overlapping segments are not allowed. */ |
304 | -/* I: the segments cover the entire address space precisely. */ |
305 | -/* Each segment can optionally hold an index into the filename table. */ |
306 | - |
307 | -static NSegment nsegments[VG_N_SEGMENTS]; |
308 | -static Int nsegments_used = 0; |
309 | - |
310 | -#define Addr_MIN ((Addr)0) |
311 | -#define Addr_MAX ((Addr)(-1ULL)) |
312 | - |
313 | -/* Limits etc */ |
314 | - |
315 | -// The smallest address that aspacem will try to allocate |
316 | -static Addr aspacem_minAddr = 0; |
317 | - |
318 | -// The largest address that aspacem will try to allocate |
319 | -static Addr aspacem_maxAddr = 0; |
320 | - |
321 | -// Where aspacem will start looking for client space |
322 | -static Addr aspacem_cStart = 0; |
323 | - |
324 | -// Where aspacem will start looking for Valgrind space |
325 | -static Addr aspacem_vStart = 0; |
326 | - |
327 | - |
328 | -#define AM_SANITY_CHECK \ |
329 | - do { \ |
330 | - if (VG_(clo_sanity_level >= 3)) \ |
331 | - aspacem_assert(VG_(am_do_sync_check) \ |
332 | - (__PRETTY_FUNCTION__,__FILE__,__LINE__)); \ |
333 | - } while (0) |
334 | - |
335 | -/* ------ end of STATE for the address-space manager ------ */ |
336 | - |
337 | -/* ------ Forwards decls ------ */ |
338 | -inline |
339 | -static Int find_nsegment_idx ( Addr a ); |
340 | - |
341 | -static void parse_procselfmaps ( |
342 | - void (*record_mapping)( Addr addr, SizeT len, UInt prot, |
343 | - ULong dev, ULong ino, Off64T offset, |
344 | - const UChar* filename ), |
345 | - void (*record_gap)( Addr addr, SizeT len ) |
346 | - ); |
347 | - |
348 | -/* ----- Hacks to do with the "commpage" on arm-linux ----- */ |
349 | -/* Not that I have anything against the commpage per se. It's just |
350 | - that it's not listed in /proc/self/maps, which is a royal PITA -- |
351 | - we have to fake it up, in parse_procselfmaps. |
352 | - |
353 | - But note also bug 254556 comment #2: this is now fixed in newer |
354 | - kernels -- it is listed as a "[vectors]" entry. Presumably the |
355 | - fake entry made here duplicates the [vectors] entry, and so, if at |
356 | - some point in the future, we can stop supporting buggy kernels, |
357 | - then this kludge can be removed entirely, since the procmap parser |
358 | - below will read that entry in the normal way. */ |
359 | -#if defined(VGP_arm_linux) |
360 | -# define ARM_LINUX_FAKE_COMMPAGE_START 0xFFFF0000 |
361 | -# define ARM_LINUX_FAKE_COMMPAGE_END1 0xFFFF1000 |
362 | -#endif |
363 | - |
364 | - |
365 | -/*-----------------------------------------------------------------*/ |
366 | -/*--- ---*/ |
367 | -/*--- SegName array management. ---*/ |
368 | -/*--- ---*/ |
369 | -/*-----------------------------------------------------------------*/ |
370 | - |
371 | -/* Searches the filename table to find an index for the given name. |
372 | - If none is found, an index is allocated and the name stored. If no |
373 | - space is available we just give up. If the string is too long to |
374 | - store, return -1. |
375 | -*/ |
376 | -static Int allocate_segname ( const HChar* name ) |
377 | -{ |
378 | - Int i, j, len; |
379 | - |
380 | - aspacem_assert(name); |
381 | - |
382 | - if (0) VG_(debugLog)(0,"aspacem","allocate_segname %s\n", name); |
383 | - |
384 | - len = VG_(strlen)(name); |
385 | - if (len >= VG_MAX_SEGNAMELEN-1) { |
386 | - return -1; |
387 | - } |
388 | - |
389 | - /* first see if we already have the name. */ |
390 | - for (i = 0; i < segnames_used; i++) { |
391 | - if (!segnames[i].inUse) |
392 | - continue; |
393 | - if (0 == VG_(strcmp)(name, &segnames[i].fname[0])) { |
394 | - return i; |
395 | - } |
396 | - } |
397 | - |
398 | - /* no we don't. So look for a free slot. */ |
399 | - for (i = 0; i < segnames_used; i++) |
400 | - if (!segnames[i].inUse) |
401 | - break; |
402 | - |
403 | - if (i == segnames_used) { |
404 | - /* no free slots .. advance the high-water mark. */ |
405 | - if (segnames_used+1 < VG_N_SEGNAMES) { |
406 | - i = segnames_used; |
407 | - segnames_used++; |
408 | - } else { |
409 | - ML_(am_barf_toolow)("VG_N_SEGNAMES"); |
410 | - } |
411 | - } |
412 | - |
413 | - /* copy it in */ |
414 | - segnames[i].inUse = True; |
415 | - for (j = 0; j < len; j++) |
416 | - segnames[i].fname[j] = name[j]; |
417 | - aspacem_assert(len < VG_MAX_SEGNAMELEN); |
418 | - segnames[i].fname[len] = 0; |
419 | - return i; |
420 | -} |
421 | - |
422 | - |
423 | -/*-----------------------------------------------------------------*/ |
424 | -/*--- ---*/ |
425 | -/*--- Displaying the segment array. ---*/ |
426 | -/*--- ---*/ |
427 | -/*-----------------------------------------------------------------*/ |
428 | - |
429 | -static HChar* show_SegKind ( SegKind sk ) |
430 | -{ |
431 | - switch (sk) { |
432 | - case SkFree: return " "; |
433 | - case SkAnonC: return "anon"; |
434 | - case SkAnonV: return "ANON"; |
435 | - case SkFileC: return "file"; |
436 | - case SkFileV: return "FILE"; |
437 | - case SkShmC: return "shm "; |
438 | - case SkResvn: return "RSVN"; |
439 | - default: return "????"; |
440 | - } |
441 | -} |
442 | - |
443 | -static HChar* show_ShrinkMode ( ShrinkMode sm ) |
444 | -{ |
445 | - switch (sm) { |
446 | - case SmLower: return "SmLower"; |
447 | - case SmUpper: return "SmUpper"; |
448 | - case SmFixed: return "SmFixed"; |
449 | - default: return "Sm?????"; |
450 | - } |
451 | -} |
452 | - |
453 | -static void show_len_concisely ( /*OUT*/HChar* buf, Addr start, Addr end ) |
454 | -{ |
455 | - HChar* fmt; |
456 | - ULong len = ((ULong)end) - ((ULong)start) + 1; |
457 | - |
458 | - if (len < 10*1000*1000ULL) { |
459 | - fmt = "%7llu"; |
460 | - } |
461 | - else if (len < 999999ULL * (1ULL<<20)) { |
462 | - fmt = "%6llum"; |
463 | - len >>= 20; |
464 | - } |
465 | - else if (len < 999999ULL * (1ULL<<30)) { |
466 | - fmt = "%6llug"; |
467 | - len >>= 30; |
468 | - } |
469 | - else if (len < 999999ULL * (1ULL<<40)) { |
470 | - fmt = "%6llut"; |
471 | - len >>= 40; |
472 | - } |
473 | - else { |
474 | - fmt = "%6llue"; |
475 | - len >>= 50; |
476 | - } |
477 | - ML_(am_sprintf)(buf, fmt, len); |
478 | -} |
479 | - |
480 | - |
481 | -/* Show full details of an NSegment */ |
482 | - |
483 | -static void __attribute__ ((unused)) |
484 | - show_nsegment_full ( Int logLevel, Int segNo, NSegment* seg ) |
485 | -{ |
486 | - HChar len_buf[20]; |
487 | - HChar* name = "(none)"; |
488 | - |
489 | - if (seg->fnIdx >= 0 && seg->fnIdx < segnames_used |
490 | - && segnames[seg->fnIdx].inUse |
491 | - && segnames[seg->fnIdx].fname[0] != 0) |
492 | - name = segnames[seg->fnIdx].fname; |
493 | - |
494 | - show_len_concisely(len_buf, seg->start, seg->end); |
495 | - |
496 | - VG_(debugLog)( |
497 | - logLevel, "aspacem", |
498 | - "%3d: %s %010llx-%010llx %s %c%c%c%c%c %s " |
499 | - "d=0x%03llx i=%-7lld o=%-7lld (%d) m=%d %s\n", |
500 | - segNo, show_SegKind(seg->kind), |
501 | - (ULong)seg->start, (ULong)seg->end, len_buf, |
502 | - seg->hasR ? 'r' : '-', seg->hasW ? 'w' : '-', |
503 | - seg->hasX ? 'x' : '-', seg->hasT ? 'T' : '-', |
504 | - seg->isCH ? 'H' : '-', |
505 | - show_ShrinkMode(seg->smode), |
506 | - seg->dev, seg->ino, seg->offset, seg->fnIdx, |
507 | - (Int)seg->mark, name |
508 | - ); |
509 | -} |
510 | - |
511 | - |
512 | -/* Show an NSegment in a user-friendly-ish way. */ |
513 | - |
514 | -static void show_nsegment ( Int logLevel, Int segNo, NSegment* seg ) |
515 | -{ |
516 | - HChar len_buf[20]; |
517 | - show_len_concisely(len_buf, seg->start, seg->end); |
518 | - |
519 | - switch (seg->kind) { |
520 | - |
521 | - case SkFree: |
522 | - VG_(debugLog)( |
523 | - logLevel, "aspacem", |
524 | - "%3d: %s %010llx-%010llx %s\n", |
525 | - segNo, show_SegKind(seg->kind), |
526 | - (ULong)seg->start, (ULong)seg->end, len_buf |
527 | - ); |
528 | - break; |
529 | - |
530 | - case SkAnonC: case SkAnonV: case SkShmC: |
531 | - VG_(debugLog)( |
532 | - logLevel, "aspacem", |
533 | - "%3d: %s %010llx-%010llx %s %c%c%c%c%c\n", |
534 | - segNo, show_SegKind(seg->kind), |
535 | - (ULong)seg->start, (ULong)seg->end, len_buf, |
536 | - seg->hasR ? 'r' : '-', seg->hasW ? 'w' : '-', |
537 | - seg->hasX ? 'x' : '-', seg->hasT ? 'T' : '-', |
538 | - seg->isCH ? 'H' : '-' |
539 | - ); |
540 | - break; |
541 | - |
542 | - case SkFileC: case SkFileV: |
543 | - VG_(debugLog)( |
544 | - logLevel, "aspacem", |
545 | - "%3d: %s %010llx-%010llx %s %c%c%c%c%c d=0x%03llx " |
546 | - "i=%-7lld o=%-7lld (%d)\n", |
547 | - segNo, show_SegKind(seg->kind), |
548 | - (ULong)seg->start, (ULong)seg->end, len_buf, |
549 | - seg->hasR ? 'r' : '-', seg->hasW ? 'w' : '-', |
550 | - seg->hasX ? 'x' : '-', seg->hasT ? 'T' : '-', |
551 | - seg->isCH ? 'H' : '-', |
552 | - seg->dev, seg->ino, seg->offset, seg->fnIdx |
553 | - ); |
554 | - break; |
555 | - |
556 | - case SkResvn: |
557 | - VG_(debugLog)( |
558 | - logLevel, "aspacem", |
559 | - "%3d: %s %010llx-%010llx %s %c%c%c%c%c %s\n", |
560 | - segNo, show_SegKind(seg->kind), |
561 | - (ULong)seg->start, (ULong)seg->end, len_buf, |
562 | - seg->hasR ? 'r' : '-', seg->hasW ? 'w' : '-', |
563 | - seg->hasX ? 'x' : '-', seg->hasT ? 'T' : '-', |
564 | - seg->isCH ? 'H' : '-', |
565 | - show_ShrinkMode(seg->smode) |
566 | - ); |
567 | - break; |
568 | - |
569 | - default: |
570 | - VG_(debugLog)( |
571 | - logLevel, "aspacem", |
572 | - "%3d: ???? UNKNOWN SEGMENT KIND\n", |
573 | - segNo |
574 | - ); |
575 | - break; |
576 | - } |
577 | -} |
578 | - |
579 | -/* Print out the segment array (debugging only!). */ |
580 | -void VG_(am_show_nsegments) ( Int logLevel, HChar* who ) |
581 | -{ |
582 | - Int i; |
583 | - VG_(debugLog)(logLevel, "aspacem", |
584 | - "<<< SHOW_SEGMENTS: %s (%d segments, %d segnames)\n", |
585 | - who, nsegments_used, segnames_used); |
586 | - for (i = 0; i < segnames_used; i++) { |
587 | - if (!segnames[i].inUse) |
588 | - continue; |
589 | - VG_(debugLog)(logLevel, "aspacem", |
590 | - "(%2d) %s\n", i, segnames[i].fname); |
591 | - } |
592 | - for (i = 0; i < nsegments_used; i++) |
593 | - show_nsegment( logLevel, i, &nsegments[i] ); |
594 | - VG_(debugLog)(logLevel, "aspacem", |
595 | - ">>>\n"); |
596 | -} |
597 | - |
598 | - |
599 | -/* Get the filename corresponding to this segment, if known and if it |
600 | - has one. The returned name's storage cannot be assumed to be |
601 | - persistent, so the caller should immediately copy the name |
602 | - elsewhere. */ |
603 | -HChar* VG_(am_get_filename)( NSegment const * seg ) |
604 | -{ |
605 | - Int i; |
606 | - aspacem_assert(seg); |
607 | - i = seg->fnIdx; |
608 | - if (i < 0 || i >= segnames_used || !segnames[i].inUse) |
609 | - return NULL; |
610 | - else |
611 | - return &segnames[i].fname[0]; |
612 | -} |
613 | - |
614 | -/* Collect up the start addresses of all non-free, non-resvn segments. |
615 | - The interface is a bit strange in order to avoid potential |
616 | - segment-creation races caused by dynamic allocation of the result |
617 | - buffer *starts. |
618 | - |
619 | - The function first computes how many entries in the result |
620 | - buffer *starts will be needed. If this number <= nStarts, |
621 | - they are placed in starts[0..], and the number is returned. |
622 | - If nStarts is not large enough, nothing is written to |
623 | - starts[0..], and the negation of the size is returned. |
624 | - |
625 | - Correct use of this function may mean calling it multiple times in |
626 | - order to establish a suitably-sized buffer. */ |
627 | - |
628 | -Int VG_(am_get_segment_starts)( Addr* starts, Int nStarts ) |
629 | -{ |
630 | - Int i, j, nSegs; |
631 | - |
632 | - /* don't pass dumbass arguments */ |
633 | - aspacem_assert(nStarts >= 0); |
634 | - |
635 | - nSegs = 0; |
636 | - for (i = 0; i < nsegments_used; i++) { |
637 | - if (nsegments[i].kind == SkFree || nsegments[i].kind == SkResvn) |
638 | - continue; |
639 | - nSegs++; |
640 | - } |
641 | - |
642 | - if (nSegs > nStarts) { |
643 | - /* The buffer isn't big enough. Tell the caller how big it needs |
644 | - to be. */ |
645 | - return -nSegs; |
646 | - } |
647 | - |
648 | - /* There's enough space. So write into the result buffer. */ |
649 | - aspacem_assert(nSegs <= nStarts); |
650 | - |
651 | - j = 0; |
652 | - for (i = 0; i < nsegments_used; i++) { |
653 | - if (nsegments[i].kind == SkFree || nsegments[i].kind == SkResvn) |
654 | - continue; |
655 | - starts[j] = nsegments[i].start; |
656 | - j++; |
657 | - } |
658 | - |
659 | - aspacem_assert(j == nSegs); /* this should not fail */ |
660 | - return nSegs; |
661 | -} |
662 | - |
663 | - |
664 | -/*-----------------------------------------------------------------*/ |
665 | -/*--- ---*/ |
666 | -/*--- Sanity checking and preening of the segment array. ---*/ |
667 | -/*--- ---*/ |
668 | -/*-----------------------------------------------------------------*/ |
669 | - |
670 | -/* Check representational invariants for NSegments. */ |
671 | - |
672 | -static Bool sane_NSegment ( NSegment* s ) |
673 | -{ |
674 | - if (s == NULL) return False; |
675 | - |
676 | - /* No zero sized segments and no wraparounds. */ |
677 | - if (s->start >= s->end) return False; |
678 | - |
679 | - /* .mark is used for admin purposes only. */ |
680 | - if (s->mark) return False; |
681 | - |
682 | - /* require page alignment */ |
683 | - if (!VG_IS_PAGE_ALIGNED(s->start)) return False; |
684 | - if (!VG_IS_PAGE_ALIGNED(s->end+1)) return False; |
685 | - |
686 | - switch (s->kind) { |
687 | - |
688 | - case SkFree: |
689 | - return |
690 | - s->smode == SmFixed |
691 | - && s->dev == 0 && s->ino == 0 && s->offset == 0 && s->fnIdx == -1 |
692 | - && !s->hasR && !s->hasW && !s->hasX && !s->hasT |
693 | - && !s->isCH; |
694 | - |
695 | - case SkAnonC: case SkAnonV: case SkShmC: |
696 | - return |
697 | - s->smode == SmFixed |
698 | - && s->dev == 0 && s->ino == 0 && s->offset == 0 && s->fnIdx == -1 |
699 | - && (s->kind==SkAnonC ? True : !s->isCH); |
700 | - |
701 | - case SkFileC: case SkFileV: |
702 | - return |
703 | - s->smode == SmFixed |
704 | - && (s->fnIdx == -1 || |
705 | - (s->fnIdx >= 0 && s->fnIdx < segnames_used |
706 | - && segnames[s->fnIdx].inUse)) |
707 | - && !s->isCH; |
708 | - |
709 | - case SkResvn: |
710 | - return |
711 | - s->dev == 0 && s->ino == 0 && s->offset == 0 && s->fnIdx == -1 |
712 | - && !s->hasR && !s->hasW && !s->hasX && !s->hasT |
713 | - && !s->isCH; |
714 | - |
715 | - default: |
716 | - return False; |
717 | - } |
718 | -} |
719 | - |
720 | - |
721 | -/* Try merging s2 into s1, if possible. If successful, s1 is |
722 | - modified, and True is returned. Otherwise s1 is unchanged and |
723 | - False is returned. */ |
724 | - |
725 | -static Bool maybe_merge_nsegments ( NSegment* s1, NSegment* s2 ) |
726 | -{ |
727 | - if (s1->kind != s2->kind) |
728 | - return False; |
729 | - |
730 | - if (s1->end+1 != s2->start) |
731 | - return False; |
732 | - |
733 | - /* reject cases which would cause wraparound */ |
734 | - if (s1->start > s2->end) |
735 | - return False; |
736 | - |
737 | - switch (s1->kind) { |
738 | - |
739 | - case SkFree: |
740 | - s1->end = s2->end; |
741 | - return True; |
742 | - |
743 | - case SkAnonC: case SkAnonV: |
744 | - if (s1->hasR == s2->hasR && s1->hasW == s2->hasW |
745 | - && s1->hasX == s2->hasX && s1->isCH == s2->isCH) { |
746 | - s1->end = s2->end; |
747 | - s1->hasT |= s2->hasT; |
748 | - return True; |
749 | - } |
750 | - break; |
751 | - |
752 | - case SkFileC: case SkFileV: |
753 | - if (s1->hasR == s2->hasR |
754 | - && s1->hasW == s2->hasW && s1->hasX == s2->hasX |
755 | - && s1->dev == s2->dev && s1->ino == s2->ino |
756 | - && s2->offset == s1->offset |
757 | - + ((ULong)s2->start) - ((ULong)s1->start) ) { |
758 | - s1->end = s2->end; |
759 | - s1->hasT |= s2->hasT; |
760 | - return True; |
761 | - } |
762 | - break; |
763 | - |
764 | - case SkShmC: |
765 | - return False; |
766 | - |
767 | - case SkResvn: |
768 | - if (s1->smode == SmFixed && s2->smode == SmFixed) { |
769 | - s1->end = s2->end; |
770 | - return True; |
771 | - } |
772 | - |
773 | - default: |
774 | - break; |
775 | - |
776 | - } |
777 | - |
778 | - return False; |
779 | -} |
780 | - |
781 | - |
782 | -/* Sanity-check and canonicalise the segment array (merge mergable |
783 | - segments). Returns True if any segments were merged. */ |
784 | - |
785 | -static Bool preen_nsegments ( void ) |
786 | -{ |
787 | - Int i, j, r, w, nsegments_used_old = nsegments_used; |
788 | - |
789 | - /* Pass 1: check the segment array covers the entire address space |
790 | - exactly once, and also that each segment is sane. */ |
791 | - aspacem_assert(nsegments_used > 0); |
792 | - aspacem_assert(nsegments[0].start == Addr_MIN); |
793 | - aspacem_assert(nsegments[nsegments_used-1].end == Addr_MAX); |
794 | - |
795 | - aspacem_assert(sane_NSegment(&nsegments[0])); |
796 | - for (i = 1; i < nsegments_used; i++) { |
797 | - aspacem_assert(sane_NSegment(&nsegments[i])); |
798 | - aspacem_assert(nsegments[i-1].end+1 == nsegments[i].start); |
799 | - } |
800 | - |
801 | - /* Pass 2: merge as much as possible, using |
802 | - maybe_merge_segments. */ |
803 | - w = 0; |
804 | - for (r = 1; r < nsegments_used; r++) { |
805 | - if (maybe_merge_nsegments(&nsegments[w], &nsegments[r])) { |
806 | - /* nothing */ |
807 | - } else { |
808 | - w++; |
809 | - if (w != r) |
810 | - nsegments[w] = nsegments[r]; |
811 | - } |
812 | - } |
813 | - w++; |
814 | - aspacem_assert(w > 0 && w <= nsegments_used); |
815 | - nsegments_used = w; |
816 | - |
817 | - /* Pass 3: free up unused string table slots */ |
818 | - /* clear mark bits */ |
819 | - for (i = 0; i < segnames_used; i++) |
820 | - segnames[i].mark = False; |
821 | - /* mark */ |
822 | - for (i = 0; i < nsegments_used; i++) { |
823 | - j = nsegments[i].fnIdx; |
824 | - aspacem_assert(j >= -1 && j < segnames_used); |
825 | - if (j >= 0) { |
826 | - aspacem_assert(segnames[j].inUse); |
827 | - segnames[j].mark = True; |
828 | - } |
829 | - } |
830 | - /* release */ |
831 | - for (i = 0; i < segnames_used; i++) { |
832 | - if (segnames[i].mark == False) { |
833 | - segnames[i].inUse = False; |
834 | - segnames[i].fname[0] = 0; |
835 | - } |
836 | - } |
837 | - |
838 | - return nsegments_used != nsegments_used_old; |
839 | -} |
840 | - |
841 | - |
842 | -/* Check the segment array corresponds with the kernel's view of |
843 | - memory layout. sync_check_ok returns True if no anomalies were |
844 | - found, else False. In the latter case the mismatching segments are |
845 | - displayed. |
846 | - |
847 | - The general idea is: we get the kernel to show us all its segments |
848 | - and also the gaps in between. For each such interval, try and find |
849 | - a sequence of appropriate intervals in our segment array which |
850 | - cover or more than cover the kernel's interval, and which all have |
851 | - suitable kinds/permissions etc. |
852 | - |
853 | - Although any specific kernel interval is not matched exactly to a |
854 | - valgrind interval or sequence thereof, eventually any disagreement |
855 | - on mapping boundaries will be detected. This is because, if for |
856 | - example valgrind's intervals cover a greater range than the current |
857 | - kernel interval, it must be the case that a neighbouring free-space |
858 | - interval belonging to valgrind cannot cover the neighbouring |
859 | - free-space interval belonging to the kernel. So the disagreement |
860 | - is detected. |
861 | - |
862 | - In other words, we examine each kernel interval in turn, and check |
863 | - we do not disagree over the range of that interval. Because all of |
864 | - the address space is examined, any disagreements must eventually be |
865 | - detected. |
866 | -*/ |
867 | - |
868 | -static Bool sync_check_ok = False; |
869 | - |
870 | -static void sync_check_mapping_callback ( Addr addr, SizeT len, UInt prot, |
871 | - ULong dev, ULong ino, Off64T offset, |
872 | - const UChar* filename ) |
873 | -{ |
874 | - Int iLo, iHi, i; |
875 | - Bool sloppyXcheck; |
876 | - |
877 | - /* If a problem has already been detected, don't continue comparing |
878 | - segments, so as to avoid flooding the output with error |
879 | - messages. */ |
880 | -#if !defined(VGO_darwin) |
881 | - /* GrP fixme not */ |
882 | - if (!sync_check_ok) |
883 | - return; |
884 | -#endif |
885 | - if (len == 0) |
886 | - return; |
887 | - |
888 | - /* The kernel should not give us wraparounds. */ |
889 | - aspacem_assert(addr <= addr + len - 1); |
890 | - |
891 | - iLo = find_nsegment_idx( addr ); |
892 | - iHi = find_nsegment_idx( addr + len - 1 ); |
893 | - |
894 | - /* These 5 should be guaranteed by find_nsegment_idx. */ |
895 | - aspacem_assert(0 <= iLo && iLo < nsegments_used); |
896 | - aspacem_assert(0 <= iHi && iHi < nsegments_used); |
897 | - aspacem_assert(iLo <= iHi); |
898 | - aspacem_assert(nsegments[iLo].start <= addr ); |
899 | - aspacem_assert(nsegments[iHi].end >= addr + len - 1 ); |
900 | - |
901 | - /* x86 doesn't differentiate 'x' and 'r' (at least, all except the |
902 | - most recent NX-bit enabled CPUs) and so recent kernels attempt |
903 | - to provide execute protection by placing all executable mappings |
904 | - low down in the address space and then reducing the size of the |
905 | - code segment to prevent code at higher addresses being executed. |
906 | - |
907 | - These kernels report which mappings are really executable in |
908 | - the /proc/self/maps output rather than mirroring what was asked |
909 | - for when each mapping was created. In order to cope with this we |
910 | - have a sloppyXcheck mode which we enable on x86 and s390 - in this |
911 | - mode we allow the kernel to report execute permission when we weren't |
912 | - expecting it but not vice versa. */ |
913 | -# if defined(VGA_x86) || defined (VGA_s390x) |
914 | - sloppyXcheck = True; |
915 | -# else |
916 | - sloppyXcheck = False; |
917 | -# endif |
918 | - |
919 | - /* NSegments iLo .. iHi inclusive should agree with the presented |
920 | - data. */ |
921 | - for (i = iLo; i <= iHi; i++) { |
922 | - |
923 | - Bool same, cmp_offsets, cmp_devino; |
924 | - UInt seg_prot; |
925 | - |
926 | - /* compare the kernel's offering against ours. */ |
927 | - same = nsegments[i].kind == SkAnonC |
928 | - || nsegments[i].kind == SkAnonV |
929 | - || nsegments[i].kind == SkFileC |
930 | - || nsegments[i].kind == SkFileV |
931 | - || nsegments[i].kind == SkShmC; |
932 | - |
933 | - seg_prot = 0; |
934 | - if (nsegments[i].hasR) seg_prot |= VKI_PROT_READ; |
935 | - if (nsegments[i].hasW) seg_prot |= VKI_PROT_WRITE; |
936 | - if (nsegments[i].hasX) seg_prot |= VKI_PROT_EXEC; |
937 | - |
938 | - cmp_offsets |
939 | - = nsegments[i].kind == SkFileC || nsegments[i].kind == SkFileV; |
940 | - |
941 | - cmp_devino |
942 | - = nsegments[i].dev != 0 || nsegments[i].ino != 0; |
943 | - |
944 | - /* Consider other reasons to not compare dev/inode */ |
945 | -#if defined(VGO_linux) |
946 | - /* bproc does some godawful hack on /dev/zero at process |
947 | - migration, which changes the name of it, and its dev & ino */ |
948 | - if (filename && 0==VG_(strcmp)(filename, "/dev/zero (deleted)")) |
949 | - cmp_devino = False; |
950 | - |
951 | - /* hack apparently needed on MontaVista Linux */ |
952 | - if (filename && VG_(strstr)(filename, "/.lib-ro/")) |
953 | - cmp_devino = False; |
954 | -#endif |
955 | - |
956 | -#if defined(VGO_darwin) |
957 | - // GrP fixme kernel info doesn't have dev/inode |
958 | - cmp_devino = False; |
959 | - |
960 | - // GrP fixme V and kernel don't agree on offsets |
961 | - cmp_offsets = False; |
962 | -#endif |
963 | - |
964 | - /* If we are doing sloppy execute permission checks then we |
965 | - allow segment to have X permission when we weren't expecting |
966 | - it (but not vice versa) so if the kernel reported execute |
967 | - permission then pretend that this segment has it regardless |
968 | - of what we were expecting. */ |
969 | - if (sloppyXcheck && (prot & VKI_PROT_EXEC) != 0) { |
970 | - seg_prot |= VKI_PROT_EXEC; |
971 | - } |
972 | - |
973 | - same = same |
974 | - && seg_prot == prot |
975 | - && (cmp_devino |
976 | - ? (nsegments[i].dev == dev && nsegments[i].ino == ino) |
977 | - : True) |
978 | - && (cmp_offsets |
979 | - ? nsegments[i].start-nsegments[i].offset == addr-offset |
980 | - : True); |
981 | - if (!same) { |
982 | - Addr start = addr; |
983 | - Addr end = start + len - 1; |
984 | - HChar len_buf[20]; |
985 | - show_len_concisely(len_buf, start, end); |
986 | - |
987 | - sync_check_ok = False; |
988 | - |
989 | - VG_(debugLog)( |
990 | - 0,"aspacem", |
991 | - "segment mismatch: V's seg 1st, kernel's 2nd:\n"); |
992 | - show_nsegment_full( 0, i, &nsegments[i] ); |
993 | - VG_(debugLog)(0,"aspacem", |
994 | - "...: .... %010llx-%010llx %s %c%c%c.. ....... " |
995 | - "d=0x%03llx i=%-7lld o=%-7lld (.) m=. %s\n", |
996 | - (ULong)start, (ULong)end, len_buf, |
997 | - prot & VKI_PROT_READ ? 'r' : '-', |
998 | - prot & VKI_PROT_WRITE ? 'w' : '-', |
999 | - prot & VKI_PROT_EXEC ? 'x' : '-', |
1000 | - dev, ino, offset, filename ? (HChar*)filename : "(none)" ); |
1001 | - |
1002 | - return; |
1003 | - } |
1004 | - } |
1005 | - |
1006 | - /* Looks harmless. Keep going. */ |
1007 | - return; |
1008 | -} |
1009 | - |
1010 | -static void sync_check_gap_callback ( Addr addr, SizeT len ) |
1011 | -{ |
1012 | - Int iLo, iHi, i; |
1013 | - |
1014 | - /* If a problem has already been detected, don't continue comparing |
1015 | - segments, so as to avoid flooding the output with error |
1016 | - messages. */ |
1017 | -#if !defined(VGO_darwin) |
1018 | - /* GrP fixme not */ |
1019 | - if (!sync_check_ok) |
1020 | - return; |
1021 | -#endif |
1022 | - if (len == 0) |
1023 | - return; |
1024 | - |
1025 | - /* The kernel should not give us wraparounds. */ |
1026 | - aspacem_assert(addr <= addr + len - 1); |
1027 | - |
1028 | - iLo = find_nsegment_idx( addr ); |
1029 | - iHi = find_nsegment_idx( addr + len - 1 ); |
1030 | - |
1031 | - /* These 5 should be guaranteed by find_nsegment_idx. */ |
1032 | - aspacem_assert(0 <= iLo && iLo < nsegments_used); |
1033 | - aspacem_assert(0 <= iHi && iHi < nsegments_used); |
1034 | - aspacem_assert(iLo <= iHi); |
1035 | - aspacem_assert(nsegments[iLo].start <= addr ); |
1036 | - aspacem_assert(nsegments[iHi].end >= addr + len - 1 ); |
1037 | - |
1038 | - /* NSegments iLo .. iHi inclusive should agree with the presented |
1039 | - data. */ |
1040 | - for (i = iLo; i <= iHi; i++) { |
1041 | - |
1042 | - Bool same; |
1043 | - |
1044 | - /* compare the kernel's offering against ours. */ |
1045 | - same = nsegments[i].kind == SkFree |
1046 | - || nsegments[i].kind == SkResvn; |
1047 | - |
1048 | - if (!same) { |
1049 | - Addr start = addr; |
1050 | - Addr end = start + len - 1; |
1051 | - HChar len_buf[20]; |
1052 | - show_len_concisely(len_buf, start, end); |
1053 | - |
1054 | - sync_check_ok = False; |
1055 | - |
1056 | - VG_(debugLog)( |
1057 | - 0,"aspacem", |
1058 | - "segment mismatch: V's gap 1st, kernel's 2nd:\n"); |
1059 | - show_nsegment_full( 0, i, &nsegments[i] ); |
1060 | - VG_(debugLog)(0,"aspacem", |
1061 | - " : .... %010llx-%010llx %s", |
1062 | - (ULong)start, (ULong)end, len_buf); |
1063 | - return; |
1064 | - } |
1065 | - } |
1066 | - |
1067 | - /* Looks harmless. Keep going. */ |
1068 | - return; |
1069 | -} |
1070 | - |
1071 | - |
1072 | -/* Sanity check: check that Valgrind and the kernel agree on the |
1073 | - address space layout. Prints offending segments and call point if |
1074 | - a discrepancy is detected, but does not abort the system. Returned |
1075 | - Bool is False if a discrepancy was found. */ |
1076 | - |
1077 | -Bool VG_(am_do_sync_check) ( const HChar* fn, |
1078 | - const HChar* file, Int line ) |
1079 | -{ |
1080 | - sync_check_ok = True; |
1081 | - if (0) |
1082 | - VG_(debugLog)(0,"aspacem", "do_sync_check %s:%d\n", file,line); |
1083 | - parse_procselfmaps( sync_check_mapping_callback, |
1084 | - sync_check_gap_callback ); |
1085 | - if (!sync_check_ok) { |
1086 | - VG_(debugLog)(0,"aspacem", |
1087 | - "sync check at %s:%d (%s): FAILED\n", |
1088 | - file, line, fn); |
1089 | - VG_(debugLog)(0,"aspacem", "\n"); |
1090 | - |
1091 | -# if 0 |
1092 | - { |
1093 | - HChar buf[100]; |
1094 | - VG_(am_show_nsegments)(0,"post syncheck failure"); |
1095 | - VG_(sprintf)(buf, "/bin/cat /proc/%d/maps", VG_(getpid)()); |
1096 | - VG_(system)(buf); |
1097 | - } |
1098 | -# endif |
1099 | - |
1100 | - } |
1101 | - return sync_check_ok; |
1102 | -} |
1103 | - |
1104 | -/* Hook to allow sanity checks to be done from aspacemgr-common.c. */ |
1105 | -void ML_(am_do_sanity_check)( void ) |
1106 | -{ |
1107 | - AM_SANITY_CHECK; |
1108 | -} |
1109 | - |
1110 | - |
1111 | -/*-----------------------------------------------------------------*/ |
1112 | -/*--- ---*/ |
1113 | -/*--- Low level access / modification of the segment array. ---*/ |
1114 | -/*--- ---*/ |
1115 | -/*-----------------------------------------------------------------*/ |
1116 | - |
1117 | -/* Binary search the interval array for a given address. Since the |
1118 | - array covers the entire address space the search cannot fail. The |
1119 | - _WRK function does the real work. Its caller (just below) caches |
1120 | - the results thereof, to save time. With N_CACHE of 63 we get a hit |
1121 | - rate exceeding 90% when running OpenOffice. |
1122 | - |
1123 | - Re ">> 12", it doesn't matter that the page size of some targets |
1124 | - might be different from 12. Really "(a >> 12) % N_CACHE" is merely |
1125 | - a hash function, and the actual cache entry is always validated |
1126 | - correctly against the selected cache entry before use. |
1127 | -*/ |
1128 | -/* Don't call find_nsegment_idx_WRK; use find_nsegment_idx instead. */ |
1129 | -__attribute__((noinline)) |
1130 | -static Int find_nsegment_idx_WRK ( Addr a ) |
1131 | -{ |
1132 | - Addr a_mid_lo, a_mid_hi; |
1133 | - Int mid, |
1134 | - lo = 0, |
1135 | - hi = nsegments_used-1; |
1136 | - while (True) { |
1137 | - /* current unsearched space is from lo to hi, inclusive. */ |
1138 | - if (lo > hi) { |
1139 | - /* Not found. This can't happen. */ |
1140 | - ML_(am_barf)("find_nsegment_idx: not found"); |
1141 | - } |
1142 | - mid = (lo + hi) / 2; |
1143 | - a_mid_lo = nsegments[mid].start; |
1144 | - a_mid_hi = nsegments[mid].end; |
1145 | - |
1146 | - if (a < a_mid_lo) { hi = mid-1; continue; } |
1147 | - if (a > a_mid_hi) { lo = mid+1; continue; } |
1148 | - aspacem_assert(a >= a_mid_lo && a <= a_mid_hi); |
1149 | - aspacem_assert(0 <= mid && mid < nsegments_used); |
1150 | - return mid; |
1151 | - } |
1152 | -} |
1153 | - |
1154 | -inline static Int find_nsegment_idx ( Addr a ) |
1155 | -{ |
1156 | -# define N_CACHE 131 /*prime*/ |
1157 | - static Addr cache_pageno[N_CACHE]; |
1158 | - static Int cache_segidx[N_CACHE]; |
1159 | - static Bool cache_inited = False; |
1160 | - |
1161 | - static UWord n_q = 0; |
1162 | - static UWord n_m = 0; |
1163 | - |
1164 | - UWord ix; |
1165 | - |
1166 | - if (LIKELY(cache_inited)) { |
1167 | - /* do nothing */ |
1168 | - } else { |
1169 | - for (ix = 0; ix < N_CACHE; ix++) { |
1170 | - cache_pageno[ix] = 0; |
1171 | - cache_segidx[ix] = -1; |
1172 | - } |
1173 | - cache_inited = True; |
1174 | - } |
1175 | - |
1176 | - ix = (a >> 12) % N_CACHE; |
1177 | - |
1178 | - n_q++; |
1179 | - if (0 && 0 == (n_q & 0xFFFF)) |
1180 | - VG_(debugLog)(0,"xxx","find_nsegment_idx: %lu %lu\n", n_q, n_m); |
1181 | - |
1182 | - if ((a >> 12) == cache_pageno[ix] |
1183 | - && cache_segidx[ix] >= 0 |
1184 | - && cache_segidx[ix] < nsegments_used |
1185 | - && nsegments[cache_segidx[ix]].start <= a |
1186 | - && a <= nsegments[cache_segidx[ix]].end) { |
1187 | - /* hit */ |
1188 | - /* aspacem_assert( cache_segidx[ix] == find_nsegment_idx_WRK(a) ); */ |
1189 | - return cache_segidx[ix]; |
1190 | - } |
1191 | - /* miss */ |
1192 | - n_m++; |
1193 | - cache_segidx[ix] = find_nsegment_idx_WRK(a); |
1194 | - cache_pageno[ix] = a >> 12; |
1195 | - return cache_segidx[ix]; |
1196 | -# undef N_CACHE |
1197 | -} |
1198 | - |
1199 | - |
1200 | - |
1201 | -/* Finds the segment containing 'a'. Only returns file/anon/resvn |
1202 | - segments. This returns a 'NSegment const *' - a pointer to |
1203 | - readonly data. */ |
1204 | -NSegment const * VG_(am_find_nsegment) ( Addr a ) |
1205 | -{ |
1206 | - Int i = find_nsegment_idx(a); |
1207 | - aspacem_assert(i >= 0 && i < nsegments_used); |
1208 | - aspacem_assert(nsegments[i].start <= a); |
1209 | - aspacem_assert(a <= nsegments[i].end); |
1210 | - if (nsegments[i].kind == SkFree) |
1211 | - return NULL; |
1212 | - else |
1213 | - return &nsegments[i]; |
1214 | -} |
1215 | - |
1216 | - |
1217 | -/* Given a pointer to a seg, tries to figure out which one it is in |
1218 | - nsegments[..]. Very paranoid. */ |
1219 | -static Int segAddr_to_index ( NSegment* seg ) |
1220 | -{ |
1221 | - Int i; |
1222 | - if (seg < &nsegments[0] || seg >= &nsegments[nsegments_used]) |
1223 | - return -1; |
1224 | - i = ((UChar*)seg - (UChar*)(&nsegments[0])) / sizeof(NSegment); |
1225 | - if (i < 0 || i >= nsegments_used) |
1226 | - return -1; |
1227 | - if (seg == &nsegments[i]) |
1228 | - return i; |
1229 | - return -1; |
1230 | -} |
1231 | - |
1232 | - |
1233 | -/* Find the next segment along from 'here', if it is a file/anon/resvn |
1234 | - segment. */ |
1235 | -NSegment const * VG_(am_next_nsegment) ( NSegment* here, Bool fwds ) |
1236 | -{ |
1237 | - Int i = segAddr_to_index(here); |
1238 | - if (i < 0 || i >= nsegments_used) |
1239 | - return NULL; |
1240 | - if (fwds) { |
1241 | - i++; |
1242 | - if (i >= nsegments_used) |
1243 | - return NULL; |
1244 | - } else { |
1245 | - i--; |
1246 | - if (i < 0) |
1247 | - return NULL; |
1248 | - } |
1249 | - switch (nsegments[i].kind) { |
1250 | - case SkFileC: case SkFileV: case SkShmC: |
1251 | - case SkAnonC: case SkAnonV: case SkResvn: |
1252 | - return &nsegments[i]; |
1253 | - default: |
1254 | - break; |
1255 | - } |
1256 | - return NULL; |
1257 | -} |
1258 | - |
1259 | - |
1260 | -/* Trivial fn: return the total amount of space in anonymous mappings, |
1261 | - both for V and the client. Is used for printing stats in |
1262 | - out-of-memory messages. */ |
1263 | -ULong VG_(am_get_anonsize_total)( void ) |
1264 | -{ |
1265 | - Int i; |
1266 | - ULong total = 0; |
1267 | - for (i = 0; i < nsegments_used; i++) { |
1268 | - if (nsegments[i].kind == SkAnonC || nsegments[i].kind == SkAnonV) { |
1269 | - total += (ULong)nsegments[i].end |
1270 | - - (ULong)nsegments[i].start + 1ULL; |
1271 | - } |
1272 | - } |
1273 | - return total; |
1274 | -} |
1275 | - |
1276 | - |
1277 | -/* Test if a piece of memory is addressable by the client with at |
1278 | - least the "prot" protection permissions by examining the underlying |
1279 | - segments. If freeOk is True then SkFree areas are also allowed. |
1280 | -*/ |
1281 | -static |
1282 | -Bool is_valid_for_client( Addr start, SizeT len, UInt prot, Bool freeOk ) |
1283 | -{ |
1284 | - Int i, iLo, iHi; |
1285 | - Bool needR, needW, needX; |
1286 | - |
1287 | - if (len == 0) |
1288 | - return True; /* somewhat dubious case */ |
1289 | - if (start + len < start) |
1290 | - return False; /* reject wraparounds */ |
1291 | - |
1292 | - needR = toBool(prot & VKI_PROT_READ); |
1293 | - needW = toBool(prot & VKI_PROT_WRITE); |
1294 | - needX = toBool(prot & VKI_PROT_EXEC); |
1295 | - |
1296 | - iLo = find_nsegment_idx(start); |
1297 | - aspacem_assert(start >= nsegments[iLo].start); |
1298 | - |
1299 | - if (start+len-1 <= nsegments[iLo].end) { |
1300 | - /* This is a speedup hack which avoids calling find_nsegment_idx |
1301 | - a second time when possible. It is always correct to just |
1302 | - use the "else" clause below, but is_valid_for_client is |
1303 | - called a lot by the leak checker, so avoiding pointless calls |
1304 | - to find_nsegment_idx, which can be expensive, is helpful. */ |
1305 | - iHi = iLo; |
1306 | - } else { |
1307 | - iHi = find_nsegment_idx(start + len - 1); |
1308 | - } |
1309 | - |
1310 | - for (i = iLo; i <= iHi; i++) { |
1311 | - if ( (nsegments[i].kind == SkFileC |
1312 | - || nsegments[i].kind == SkAnonC |
1313 | - || nsegments[i].kind == SkShmC |
1314 | - || (nsegments[i].kind == SkFree && freeOk) |
1315 | - || (nsegments[i].kind == SkResvn && freeOk)) |
1316 | - && (needR ? nsegments[i].hasR : True) |
1317 | - && (needW ? nsegments[i].hasW : True) |
1318 | - && (needX ? nsegments[i].hasX : True) ) { |
1319 | - /* ok */ |
1320 | - } else { |
1321 | - return False; |
1322 | - } |
1323 | - } |
1324 | - return True; |
1325 | -} |
1326 | - |
1327 | -/* Test if a piece of memory is addressable by the client with at |
1328 | - least the "prot" protection permissions by examining the underlying |
1329 | - segments. */ |
1330 | -Bool VG_(am_is_valid_for_client)( Addr start, SizeT len, |
1331 | - UInt prot ) |
1332 | -{ |
1333 | - return is_valid_for_client( start, len, prot, False/*free not OK*/ ); |
1334 | -} |
1335 | - |
1336 | -/* Variant of VG_(am_is_valid_for_client) which allows free areas to |
1337 | - be consider part of the client's addressable space. It also |
1338 | - considers reservations to be allowable, since from the client's |
1339 | - point of view they don't exist. */ |
1340 | -Bool VG_(am_is_valid_for_client_or_free_or_resvn) |
1341 | - ( Addr start, SizeT len, UInt prot ) |
1342 | -{ |
1343 | - return is_valid_for_client( start, len, prot, True/*free is OK*/ ); |
1344 | -} |
1345 | - |
1346 | - |
1347 | -/* Test if a piece of memory is addressable by valgrind with at least |
1348 | - PROT_NONE protection permissions by examining the underlying |
1349 | - segments. */ |
1350 | -static Bool is_valid_for_valgrind( Addr start, SizeT len ) |
1351 | -{ |
1352 | - Int i, iLo, iHi; |
1353 | - |
1354 | - if (len == 0) |
1355 | - return True; /* somewhat dubious case */ |
1356 | - if (start + len < start) |
1357 | - return False; /* reject wraparounds */ |
1358 | - |
1359 | - iLo = find_nsegment_idx(start); |
1360 | - iHi = find_nsegment_idx(start + len - 1); |
1361 | - for (i = iLo; i <= iHi; i++) { |
1362 | - if (nsegments[i].kind == SkFileV || nsegments[i].kind == SkAnonV) { |
1363 | - /* ok */ |
1364 | - } else { |
1365 | - return False; |
1366 | - } |
1367 | - } |
1368 | - return True; |
1369 | -} |
1370 | - |
1371 | - |
1372 | -/* Returns True if any part of the address range is marked as having |
1373 | - translations made from it. This is used to determine when to |
1374 | - discard code, so if in doubt return True. */ |
1375 | - |
1376 | -static Bool any_Ts_in_range ( Addr start, SizeT len ) |
1377 | -{ |
1378 | - Int iLo, iHi, i; |
1379 | - aspacem_assert(len > 0); |
1380 | - aspacem_assert(start + len > start); |
1381 | - iLo = find_nsegment_idx(start); |
1382 | - iHi = find_nsegment_idx(start + len - 1); |
1383 | - for (i = iLo; i <= iHi; i++) { |
1384 | - if (nsegments[i].hasT) |
1385 | - return True; |
1386 | - } |
1387 | - return False; |
1388 | -} |
1389 | - |
1390 | - |
1391 | -/*-----------------------------------------------------------------*/ |
1392 | -/*--- ---*/ |
1393 | -/*--- Modifying the segment array, and constructing segments. ---*/ |
1394 | -/*--- ---*/ |
1395 | -/*-----------------------------------------------------------------*/ |
1396 | - |
1397 | -/* Split the segment containing 'a' into two, so that 'a' is |
1398 | - guaranteed to be the start of a new segment. If 'a' is already the |
1399 | - start of a segment, do nothing. */ |
1400 | - |
1401 | -static void split_nsegment_at ( Addr a ) |
1402 | -{ |
1403 | - Int i, j; |
1404 | - |
1405 | - aspacem_assert(a > 0); |
1406 | - aspacem_assert(VG_IS_PAGE_ALIGNED(a)); |
1407 | - |
1408 | - i = find_nsegment_idx(a); |
1409 | - aspacem_assert(i >= 0 && i < nsegments_used); |
1410 | - |
1411 | - if (nsegments[i].start == a) |
1412 | - /* 'a' is already the start point of a segment, so nothing to be |
1413 | - done. */ |
1414 | - return; |
1415 | - |
1416 | - /* else we have to slide the segments upwards to make a hole */ |
1417 | - if (nsegments_used >= VG_N_SEGMENTS) |
1418 | - ML_(am_barf_toolow)("VG_N_SEGMENTS"); |
1419 | - for (j = nsegments_used-1; j > i; j--) |
1420 | - nsegments[j+1] = nsegments[j]; |
1421 | - nsegments_used++; |
1422 | - |
1423 | - nsegments[i+1] = nsegments[i]; |
1424 | - nsegments[i+1].start = a; |
1425 | - nsegments[i].end = a-1; |
1426 | - |
1427 | - if (nsegments[i].kind == SkFileV || nsegments[i].kind == SkFileC) |
1428 | - nsegments[i+1].offset |
1429 | - += ((ULong)nsegments[i+1].start) - ((ULong)nsegments[i].start); |
1430 | - |
1431 | - aspacem_assert(sane_NSegment(&nsegments[i])); |
1432 | - aspacem_assert(sane_NSegment(&nsegments[i+1])); |
1433 | -} |
1434 | - |
1435 | - |
1436 | -/* Do the minimum amount of segment splitting necessary to ensure that |
1437 | - sLo is the first address denoted by some segment and sHi is the |
1438 | - highest address denoted by some other segment. Returns the indices |
1439 | - of the lowest and highest segments in the range. */ |
1440 | - |
1441 | -static |
1442 | -void split_nsegments_lo_and_hi ( Addr sLo, Addr sHi, |
1443 | - /*OUT*/Int* iLo, |
1444 | - /*OUT*/Int* iHi ) |
1445 | -{ |
1446 | - aspacem_assert(sLo < sHi); |
1447 | - aspacem_assert(VG_IS_PAGE_ALIGNED(sLo)); |
1448 | - aspacem_assert(VG_IS_PAGE_ALIGNED(sHi+1)); |
1449 | - |
1450 | - if (sLo > 0) |
1451 | - split_nsegment_at(sLo); |
1452 | - if (sHi < sHi+1) |
1453 | - split_nsegment_at(sHi+1); |
1454 | - |
1455 | - *iLo = find_nsegment_idx(sLo); |
1456 | - *iHi = find_nsegment_idx(sHi); |
1457 | - aspacem_assert(0 <= *iLo && *iLo < nsegments_used); |
1458 | - aspacem_assert(0 <= *iHi && *iHi < nsegments_used); |
1459 | - aspacem_assert(*iLo <= *iHi); |
1460 | - aspacem_assert(nsegments[*iLo].start == sLo); |
1461 | - aspacem_assert(nsegments[*iHi].end == sHi); |
1462 | - /* Not that I'm overly paranoid or anything, definitely not :-) */ |
1463 | -} |
1464 | - |
1465 | - |
1466 | -/* Add SEG to the collection, deleting/truncating any it overlaps. |
1467 | - This deals with all the tricky cases of splitting up segments as |
1468 | - needed. */ |
1469 | - |
1470 | -static void add_segment ( NSegment* seg ) |
1471 | -{ |
1472 | - Int i, iLo, iHi, delta; |
1473 | - Bool segment_is_sane; |
1474 | - |
1475 | - Addr sStart = seg->start; |
1476 | - Addr sEnd = seg->end; |
1477 | - |
1478 | - aspacem_assert(sStart <= sEnd); |
1479 | - aspacem_assert(VG_IS_PAGE_ALIGNED(sStart)); |
1480 | - aspacem_assert(VG_IS_PAGE_ALIGNED(sEnd+1)); |
1481 | - |
1482 | - segment_is_sane = sane_NSegment(seg); |
1483 | - if (!segment_is_sane) show_nsegment_full(0,-1,seg); |
1484 | - aspacem_assert(segment_is_sane); |
1485 | - |
1486 | - split_nsegments_lo_and_hi( sStart, sEnd, &iLo, &iHi ); |
1487 | - |
1488 | - /* Now iLo .. iHi inclusive is the range of segment indices which |
1489 | - seg will replace. If we're replacing more than one segment, |
1490 | - slide those above the range down to fill the hole. */ |
1491 | - delta = iHi - iLo; |
1492 | - aspacem_assert(delta >= 0); |
1493 | - if (delta > 0) { |
1494 | - for (i = iLo; i < nsegments_used-delta; i++) |
1495 | - nsegments[i] = nsegments[i+delta]; |
1496 | - nsegments_used -= delta; |
1497 | - } |
1498 | - |
1499 | - nsegments[iLo] = *seg; |
1500 | - |
1501 | - (void)preen_nsegments(); |
1502 | - if (0) VG_(am_show_nsegments)(0,"AFTER preen (add_segment)"); |
1503 | -} |
1504 | - |
1505 | - |
1506 | -/* Clear out an NSegment record. */ |
1507 | - |
1508 | -static void init_nsegment ( /*OUT*/NSegment* seg ) |
1509 | -{ |
1510 | - seg->kind = SkFree; |
1511 | - seg->start = 0; |
1512 | - seg->end = 0; |
1513 | - seg->smode = SmFixed; |
1514 | - seg->dev = 0; |
1515 | - seg->ino = 0; |
1516 | - seg->mode = 0; |
1517 | - seg->offset = 0; |
1518 | - seg->fnIdx = -1; |
1519 | - seg->hasR = seg->hasW = seg->hasX = seg->hasT = seg->isCH = False; |
1520 | - seg->mark = False; |
1521 | -} |
1522 | - |
1523 | -/* Make an NSegment which holds a reservation. */ |
1524 | - |
1525 | -static void init_resvn ( /*OUT*/NSegment* seg, Addr start, Addr end ) |
1526 | -{ |
1527 | - aspacem_assert(start < end); |
1528 | - aspacem_assert(VG_IS_PAGE_ALIGNED(start)); |
1529 | - aspacem_assert(VG_IS_PAGE_ALIGNED(end+1)); |
1530 | - init_nsegment(seg); |
1531 | - seg->kind = SkResvn; |
1532 | - seg->start = start; |
1533 | - seg->end = end; |
1534 | -} |
1535 | - |
1536 | - |
1537 | -/*-----------------------------------------------------------------*/ |
1538 | -/*--- ---*/ |
1539 | -/*--- Startup, including reading /proc/self/maps. ---*/ |
1540 | -/*--- ---*/ |
1541 | -/*-----------------------------------------------------------------*/ |
1542 | - |
1543 | -static void read_maps_callback ( Addr addr, SizeT len, UInt prot, |
1544 | - ULong dev, ULong ino, Off64T offset, |
1545 | - const UChar* filename ) |
1546 | -{ |
1547 | - NSegment seg; |
1548 | - init_nsegment( &seg ); |
1549 | - seg.start = addr; |
1550 | - seg.end = addr+len-1; |
1551 | - seg.dev = dev; |
1552 | - seg.ino = ino; |
1553 | - seg.offset = offset; |
1554 | - seg.hasR = toBool(prot & VKI_PROT_READ); |
1555 | - seg.hasW = toBool(prot & VKI_PROT_WRITE); |
1556 | - seg.hasX = toBool(prot & VKI_PROT_EXEC); |
1557 | - seg.hasT = False; |
1558 | - |
1559 | - /* Don't use the presence of a filename to decide if a segment in |
1560 | - the initial /proc/self/maps to decide if the segment is an AnonV |
1561 | - or FileV segment as some systems don't report the filename. Use |
1562 | - the device and inode numbers instead. Fixes bug #124528. */ |
1563 | - seg.kind = SkAnonV; |
1564 | - if (dev != 0 && ino != 0) |
1565 | - seg.kind = SkFileV; |
1566 | - |
1567 | -# if defined(VGO_darwin) |
1568 | - // GrP fixme no dev/ino on darwin |
1569 | - if (offset != 0) |
1570 | - seg.kind = SkFileV; |
1571 | -# endif // defined(VGO_darwin) |
1572 | - |
1573 | -# if defined(VGP_arm_linux) |
1574 | - /* The standard handling of entries read from /proc/self/maps will |
1575 | - cause the faked up commpage segment to have type SkAnonV, which |
1576 | - is a problem because it contains code we want the client to |
1577 | - execute, and so later m_translate will segfault the client when |
1578 | - it tries to go in there. Hence change the ownership of it here |
1579 | - to the client (SkAnonC). The least-worst kludge I could think |
1580 | - of. */ |
1581 | - if (addr == ARM_LINUX_FAKE_COMMPAGE_START |
1582 | - && addr + len == ARM_LINUX_FAKE_COMMPAGE_END1 |
1583 | - && seg.kind == SkAnonV) |
1584 | - seg.kind = SkAnonC; |
1585 | -# endif // defined(VGP_arm_linux) |
1586 | - |
1587 | - if (filename) |
1588 | - seg.fnIdx = allocate_segname( filename ); |
1589 | - |
1590 | - if (0) show_nsegment( 2,0, &seg ); |
1591 | - add_segment( &seg ); |
1592 | -} |
1593 | - |
1594 | -/* Initialise the address space manager, setting up the initial |
1595 | - segment list, and reading /proc/self/maps into it. This must |
1596 | - be called before any other function. |
1597 | - |
1598 | - Takes a pointer to the SP at the time V gained control. This is |
1599 | - taken to be the highest usable address (more or less). Based on |
1600 | - that (and general consultation of tea leaves, etc) return a |
1601 | - suggested end address for the client's stack. */ |
1602 | - |
1603 | -Addr VG_(am_startup) ( Addr sp_at_startup ) |
1604 | -{ |
1605 | - NSegment seg; |
1606 | - Addr suggested_clstack_top; |
1607 | - |
1608 | - aspacem_assert(sizeof(Word) == sizeof(void*)); |
1609 | - aspacem_assert(sizeof(Addr) == sizeof(void*)); |
1610 | - aspacem_assert(sizeof(SizeT) == sizeof(void*)); |
1611 | - aspacem_assert(sizeof(SSizeT) == sizeof(void*)); |
1612 | - |
1613 | - /* Check that we can store the largest imaginable dev, ino and |
1614 | - offset numbers in an NSegment. */ |
1615 | - aspacem_assert(sizeof(seg.dev) == 8); |
1616 | - aspacem_assert(sizeof(seg.ino) == 8); |
1617 | - aspacem_assert(sizeof(seg.offset) == 8); |
1618 | - aspacem_assert(sizeof(seg.mode) == 4); |
1619 | - |
1620 | - /* Add a single interval covering the entire address space. */ |
1621 | - init_nsegment(&seg); |
1622 | - seg.kind = SkFree; |
1623 | - seg.start = Addr_MIN; |
1624 | - seg.end = Addr_MAX; |
1625 | - nsegments[0] = seg; |
1626 | - nsegments_used = 1; |
1627 | - |
1628 | -#if defined(VGO_darwin) |
1629 | - |
1630 | -# if VG_WORDSIZE == 4 |
1631 | - aspacem_minAddr = (Addr) 0x00001000; |
1632 | - aspacem_maxAddr = (Addr) 0xffffffff; |
1633 | - |
1634 | - aspacem_cStart = aspacem_minAddr; |
1635 | - aspacem_vStart = 0xf0000000; // 0xc0000000..0xf0000000 available |
1636 | -# else |
1637 | - aspacem_minAddr = (Addr) 0x100000000; // 4GB page zero |
1638 | - aspacem_maxAddr = (Addr) 0x7fffffffffff; |
1639 | - |
1640 | - aspacem_cStart = aspacem_minAddr; |
1641 | - aspacem_vStart = 0x700000000000; // 0x7000:00000000..0x7fff:5c000000 avail |
1642 | - // 0x7fff:5c000000..0x7fff:ffe00000? is stack, dyld, shared cache |
1643 | -# endif |
1644 | - |
1645 | - suggested_clstack_top = -1; // ignored; Mach-O specifies its stack |
1646 | - |
1647 | -#else |
1648 | - |
1649 | - /* Establish address limits and block out unusable parts |
1650 | - accordingly. */ |
1651 | - |
1652 | - VG_(debugLog)(2, "aspacem", |
1653 | - " sp_at_startup = 0x%010llx (supplied)\n", |
1654 | - (ULong)sp_at_startup ); |
1655 | - |
1656 | - aspacem_minAddr = (Addr) 0x04000000; // 64M |
1657 | - |
1658 | -# if VG_WORDSIZE == 8 |
1659 | - aspacem_maxAddr = (Addr)0x800000000 - 1; // 32G |
1660 | -# ifdef ENABLE_INNER |
1661 | - { Addr cse = VG_PGROUNDDN( sp_at_startup ) - 1; |
1662 | - if (aspacem_maxAddr > cse) |
1663 | - aspacem_maxAddr = cse; |
1664 | - } |
1665 | -# endif |
1666 | -# else |
1667 | - aspacem_maxAddr = VG_PGROUNDDN( sp_at_startup ) - 1; |
1668 | -# endif |
1669 | - |
1670 | - aspacem_cStart = aspacem_minAddr; // 64M |
1671 | - aspacem_vStart = VG_PGROUNDUP((aspacem_minAddr + aspacem_maxAddr + 1) / 2); |
1672 | -# ifdef ENABLE_INNER |
1673 | - aspacem_vStart -= 0x10000000; // 256M |
1674 | -# endif |
1675 | - |
1676 | - suggested_clstack_top = aspacem_maxAddr - 16*1024*1024ULL |
1677 | - + VKI_PAGE_SIZE; |
1678 | - |
1679 | -#endif |
1680 | - |
1681 | - aspacem_assert(VG_IS_PAGE_ALIGNED(aspacem_minAddr)); |
1682 | - aspacem_assert(VG_IS_PAGE_ALIGNED(aspacem_maxAddr + 1)); |
1683 | - aspacem_assert(VG_IS_PAGE_ALIGNED(aspacem_cStart)); |
1684 | - aspacem_assert(VG_IS_PAGE_ALIGNED(aspacem_vStart)); |
1685 | - aspacem_assert(VG_IS_PAGE_ALIGNED(suggested_clstack_top + 1)); |
1686 | - |
1687 | - VG_(debugLog)(2, "aspacem", |
1688 | - " minAddr = 0x%010llx (computed)\n", |
1689 | - (ULong)aspacem_minAddr); |
1690 | - VG_(debugLog)(2, "aspacem", |
1691 | - " maxAddr = 0x%010llx (computed)\n", |
1692 | - (ULong)aspacem_maxAddr); |
1693 | - VG_(debugLog)(2, "aspacem", |
1694 | - " cStart = 0x%010llx (computed)\n", |
1695 | - (ULong)aspacem_cStart); |
1696 | - VG_(debugLog)(2, "aspacem", |
1697 | - " vStart = 0x%010llx (computed)\n", |
1698 | - (ULong)aspacem_vStart); |
1699 | - VG_(debugLog)(2, "aspacem", |
1700 | - "suggested_clstack_top = 0x%010llx (computed)\n", |
1701 | - (ULong)suggested_clstack_top); |
1702 | - |
1703 | - if (aspacem_cStart > Addr_MIN) { |
1704 | - init_resvn(&seg, Addr_MIN, aspacem_cStart-1); |
1705 | - add_segment(&seg); |
1706 | - } |
1707 | - if (aspacem_maxAddr < Addr_MAX) { |
1708 | - init_resvn(&seg, aspacem_maxAddr+1, Addr_MAX); |
1709 | - add_segment(&seg); |
1710 | - } |
1711 | - |
1712 | - /* Create a 1-page reservation at the notional initial |
1713 | - client/valgrind boundary. This isn't strictly necessary, but |
1714 | - because the advisor does first-fit and starts searches for |
1715 | - valgrind allocations at the boundary, this is kind of necessary |
1716 | - in order to get it to start allocating in the right place. */ |
1717 | - init_resvn(&seg, aspacem_vStart, aspacem_vStart + VKI_PAGE_SIZE - 1); |
1718 | - add_segment(&seg); |
1719 | - |
1720 | - VG_(am_show_nsegments)(2, "Initial layout"); |
1721 | - |
1722 | - VG_(debugLog)(2, "aspacem", "Reading /proc/self/maps\n"); |
1723 | - parse_procselfmaps( read_maps_callback, NULL ); |
1724 | - /* NB: on arm-linux, parse_procselfmaps automagically kludges up |
1725 | - (iow, hands to its callbacks) a description of the ARM Commpage, |
1726 | - since that's not listed in /proc/self/maps (kernel bug IMO). We |
1727 | - have to fake up its existence in parse_procselfmaps and not |
1728 | - merely add it here as an extra segment, because doing the latter |
1729 | - causes sync checking to fail: we see we have an extra segment in |
1730 | - the segments array, which isn't listed in /proc/self/maps. |
1731 | - Hence we must make it appear that /proc/self/maps contained this |
1732 | - segment all along. Sigh. */ |
1733 | - |
1734 | - VG_(am_show_nsegments)(2, "With contents of /proc/self/maps"); |
1735 | - |
1736 | - AM_SANITY_CHECK; |
1737 | - return suggested_clstack_top; |
1738 | -} |
1739 | - |
1740 | - |
1741 | -/*-----------------------------------------------------------------*/ |
1742 | -/*--- ---*/ |
1743 | -/*--- The core query-notify mechanism. ---*/ |
1744 | -/*--- ---*/ |
1745 | -/*-----------------------------------------------------------------*/ |
1746 | - |
1747 | -/* Query aspacem to ask where a mapping should go. */ |
1748 | - |
1749 | -Addr VG_(am_get_advisory) ( MapRequest* req, |
1750 | - Bool forClient, |
1751 | - /*OUT*/Bool* ok ) |
1752 | -{ |
1753 | - /* This function implements allocation policy. |
1754 | - |
1755 | - The nature of the allocation request is determined by req, which |
1756 | - specifies the start and length of the request and indicates |
1757 | - whether the start address is mandatory, a hint, or irrelevant, |
1758 | - and by forClient, which says whether this is for the client or |
1759 | - for V. |
1760 | - |
1761 | - Return values: the request can be vetoed (*ok is set to False), |
1762 | - in which case the caller should not attempt to proceed with |
1763 | - making the mapping. Otherwise, *ok is set to True, the caller |
1764 | - may proceed, and the preferred address at which the mapping |
1765 | - should happen is returned. |
1766 | - |
1767 | - Note that this is an advisory system only: the kernel can in |
1768 | - fact do whatever it likes as far as placement goes, and we have |
1769 | - no absolute control over it. |
1770 | - |
1771 | - Allocations will never be granted in a reserved area. |
1772 | - |
1773 | - The Default Policy is: |
1774 | - |
1775 | - Search the address space for two free intervals: one of them |
1776 | - big enough to contain the request without regard to the |
1777 | - specified address (viz, as if it was a floating request) and |
1778 | - the other being able to contain the request at the specified |
1779 | - address (viz, as if were a fixed request). Then, depending on |
1780 | - the outcome of the search and the kind of request made, decide |
1781 | - whether the request is allowable and what address to advise. |
1782 | - |
1783 | - The Default Policy is overriden by Policy Exception #1: |
1784 | - |
1785 | - If the request is for a fixed client map, we are prepared to |
1786 | - grant it providing all areas inside the request are either |
1787 | - free, reservations, or mappings belonging to the client. In |
1788 | - other words we are prepared to let the client trash its own |
1789 | - mappings if it wants to. |
1790 | - |
1791 | - The Default Policy is overriden by Policy Exception #2: |
1792 | - |
1793 | - If the request is for a hinted client map, we are prepared to |
1794 | - grant it providing all areas inside the request are either |
1795 | - free or reservations. In other words we are prepared to let |
1796 | - the client have a hinted mapping anywhere it likes provided |
1797 | - it does not trash either any of its own mappings or any of |
1798 | - valgrind's mappings. |
1799 | - */ |
1800 | - Int i, j; |
1801 | - Addr holeStart, holeEnd, holeLen; |
1802 | - Bool fixed_not_required; |
1803 | - |
1804 | - Addr startPoint = forClient ? aspacem_cStart : aspacem_vStart; |
1805 | - |
1806 | - Addr reqStart = req->rkind==MAny ? 0 : req->start; |
1807 | - Addr reqEnd = reqStart + req->len - 1; |
1808 | - Addr reqLen = req->len; |
1809 | - |
1810 | - /* These hold indices for segments found during search, or -1 if not |
1811 | - found. */ |
1812 | - Int floatIdx = -1; |
1813 | - Int fixedIdx = -1; |
1814 | - |
1815 | - aspacem_assert(nsegments_used > 0); |
1816 | - |
1817 | - if (0) { |
1818 | - VG_(am_show_nsegments)(0,"getAdvisory"); |
1819 | - VG_(debugLog)(0,"aspacem", "getAdvisory 0x%llx %lld\n", |
1820 | - (ULong)req->start, (ULong)req->len); |
1821 | - } |
1822 | - |
1823 | - /* Reject zero-length requests */ |
1824 | - if (req->len == 0) { |
1825 | - *ok = False; |
1826 | - return 0; |
1827 | - } |
1828 | - |
1829 | - /* Reject wraparounds */ |
1830 | - if ((req->rkind==MFixed || req->rkind==MHint) |
1831 | - && req->start + req->len < req->start) { |
1832 | - *ok = False; |
1833 | - return 0; |
1834 | - } |
1835 | - |
1836 | - /* ------ Implement Policy Exception #1 ------ */ |
1837 | - |
1838 | - if (forClient && req->rkind == MFixed) { |
1839 | - Int iLo = find_nsegment_idx(reqStart); |
1840 | - Int iHi = find_nsegment_idx(reqEnd); |
1841 | - Bool allow = True; |
1842 | - for (i = iLo; i <= iHi; i++) { |
1843 | - if (nsegments[i].kind == SkFree |
1844 | - || nsegments[i].kind == SkFileC |
1845 | - || nsegments[i].kind == SkAnonC |
1846 | - || nsegments[i].kind == SkShmC |
1847 | - || nsegments[i].kind == SkResvn) { |
1848 | - /* ok */ |
1849 | - } else { |
1850 | - allow = False; |
1851 | - break; |
1852 | - } |
1853 | - } |
1854 | - if (allow) { |
1855 | - /* Acceptable. Granted. */ |
1856 | - *ok = True; |
1857 | - return reqStart; |
1858 | - } |
1859 | - /* Not acceptable. Fail. */ |
1860 | - *ok = False; |
1861 | - return 0; |
1862 | - } |
1863 | - |
1864 | - /* ------ Implement Policy Exception #2 ------ */ |
1865 | - |
1866 | - if (forClient && req->rkind == MHint) { |
1867 | - Int iLo = find_nsegment_idx(reqStart); |
1868 | - Int iHi = find_nsegment_idx(reqEnd); |
1869 | - Bool allow = True; |
1870 | - for (i = iLo; i <= iHi; i++) { |
1871 | - if (nsegments[i].kind == SkFree |
1872 | - || nsegments[i].kind == SkResvn) { |
1873 | - /* ok */ |
1874 | - } else { |
1875 | - allow = False; |
1876 | - break; |
1877 | - } |
1878 | - } |
1879 | - if (allow) { |
1880 | - /* Acceptable. Granted. */ |
1881 | - *ok = True; |
1882 | - return reqStart; |
1883 | - } |
1884 | - /* Not acceptable. Fall through to the default policy. */ |
1885 | - } |
1886 | - |
1887 | - /* ------ Implement the Default Policy ------ */ |
1888 | - |
1889 | - /* Don't waste time looking for a fixed match if not requested to. */ |
1890 | - fixed_not_required = req->rkind == MAny; |
1891 | - |
1892 | - i = find_nsegment_idx(startPoint); |
1893 | - |
1894 | - /* Examine holes from index i back round to i-1. Record the |
1895 | - index first fixed hole and the first floating hole which would |
1896 | - satisfy the request. */ |
1897 | - for (j = 0; j < nsegments_used; j++) { |
1898 | - |
1899 | - if (nsegments[i].kind != SkFree) { |
1900 | - i++; |
1901 | - if (i >= nsegments_used) i = 0; |
1902 | - continue; |
1903 | - } |
1904 | - |
1905 | - holeStart = nsegments[i].start; |
1906 | - holeEnd = nsegments[i].end; |
1907 | - |
1908 | - /* Stay sane .. */ |
1909 | - aspacem_assert(holeStart <= holeEnd); |
1910 | - aspacem_assert(aspacem_minAddr <= holeStart); |
1911 | - aspacem_assert(holeEnd <= aspacem_maxAddr); |
1912 | - |
1913 | - /* See if it's any use to us. */ |
1914 | - holeLen = holeEnd - holeStart + 1; |
1915 | - |
1916 | - if (fixedIdx == -1 && holeStart <= reqStart && reqEnd <= holeEnd) |
1917 | - fixedIdx = i; |
1918 | - |
1919 | - if (floatIdx == -1 && holeLen >= reqLen) |
1920 | - floatIdx = i; |
1921 | - |
1922 | - /* Don't waste time searching once we've found what we wanted. */ |
1923 | - if ((fixed_not_required || fixedIdx >= 0) && floatIdx >= 0) |
1924 | - break; |
1925 | - |
1926 | - i++; |
1927 | - if (i >= nsegments_used) i = 0; |
1928 | - } |
1929 | - |
1930 | - aspacem_assert(fixedIdx >= -1 && fixedIdx < nsegments_used); |
1931 | - if (fixedIdx >= 0) |
1932 | - aspacem_assert(nsegments[fixedIdx].kind == SkFree); |
1933 | - |
1934 | - aspacem_assert(floatIdx >= -1 && floatIdx < nsegments_used); |
1935 | - if (floatIdx >= 0) |
1936 | - aspacem_assert(nsegments[floatIdx].kind == SkFree); |
1937 | - |
1938 | - AM_SANITY_CHECK; |
1939 | - |
1940 | - /* Now see if we found anything which can satisfy the request. */ |
1941 | - switch (req->rkind) { |
1942 | - case MFixed: |
1943 | - if (fixedIdx >= 0) { |
1944 | - *ok = True; |
1945 | - return req->start; |
1946 | - } else { |
1947 | - *ok = False; |
1948 | - return 0; |
1949 | - } |
1950 | - break; |
1951 | - case MHint: |
1952 | - if (fixedIdx >= 0) { |
1953 | - *ok = True; |
1954 | - return req->start; |
1955 | - } |
1956 | - if (floatIdx >= 0) { |
1957 | - *ok = True; |
1958 | - return nsegments[floatIdx].start; |
1959 | - } |
1960 | - *ok = False; |
1961 | - return 0; |
1962 | - case MAny: |
1963 | - if (floatIdx >= 0) { |
1964 | - *ok = True; |
1965 | - return nsegments[floatIdx].start; |
1966 | - } |
1967 | - *ok = False; |
1968 | - return 0; |
1969 | - default: |
1970 | - break; |
1971 | - } |
1972 | - |
1973 | - /*NOTREACHED*/ |
1974 | - ML_(am_barf)("getAdvisory: unknown request kind"); |
1975 | - *ok = False; |
1976 | - return 0; |
1977 | -} |
1978 | - |
1979 | -/* Convenience wrapper for VG_(am_get_advisory) for client floating or |
1980 | - fixed requests. If start is zero, a floating request is issued; if |
1981 | - nonzero, a fixed request at that address is issued. Same comments |
1982 | - about return values apply. */ |
1983 | - |
1984 | -Addr VG_(am_get_advisory_client_simple) ( Addr start, SizeT len, |
1985 | - /*OUT*/Bool* ok ) |
1986 | -{ |
1987 | - MapRequest mreq; |
1988 | - mreq.rkind = start==0 ? MAny : MFixed; |
1989 | - mreq.start = start; |
1990 | - mreq.len = len; |
1991 | - return VG_(am_get_advisory)( &mreq, True/*client*/, ok ); |
1992 | -} |
1993 | - |
1994 | - |
1995 | -/* Notifies aspacem that the client completed an mmap successfully. |
1996 | - The segment array is updated accordingly. If the returned Bool is |
1997 | - True, the caller should immediately discard translations from the |
1998 | - specified address range. */ |
1999 | - |
2000 | -Bool |
2001 | -VG_(am_notify_client_mmap)( Addr a, SizeT len, UInt prot, UInt flags, |
2002 | - Int fd, Off64T offset ) |
2003 | -{ |
2004 | - HChar buf[VKI_PATH_MAX]; |
2005 | - ULong dev, ino; |
2006 | - UInt mode; |
2007 | - NSegment seg; |
2008 | - Bool needDiscard; |
2009 | - |
2010 | - aspacem_assert(len > 0); |
2011 | - aspacem_assert(VG_IS_PAGE_ALIGNED(a)); |
2012 | - aspacem_assert(VG_IS_PAGE_ALIGNED(len)); |
2013 | - aspacem_assert(VG_IS_PAGE_ALIGNED(offset)); |
2014 | - |
2015 | - /* Discard is needed if any of the just-trashed range had T. */ |
2016 | - needDiscard = any_Ts_in_range( a, len ); |
2017 | - |
2018 | - init_nsegment( &seg ); |
2019 | - seg.kind = (flags & VKI_MAP_ANONYMOUS) ? SkAnonC : SkFileC; |
2020 | - seg.start = a; |
2021 | - seg.end = a + len - 1; |
2022 | - seg.hasR = toBool(prot & VKI_PROT_READ); |
2023 | - seg.hasW = toBool(prot & VKI_PROT_WRITE); |
2024 | - seg.hasX = toBool(prot & VKI_PROT_EXEC); |
2025 | - if (!(flags & VKI_MAP_ANONYMOUS)) { |
2026 | - // Nb: We ignore offset requests in anonymous mmaps (see bug #126722) |
2027 | - seg.offset = offset; |
2028 | - if (ML_(am_get_fd_d_i_m)(fd, &dev, &ino, &mode)) { |
2029 | - seg.dev = dev; |
2030 | - seg.ino = ino; |
2031 | - seg.mode = mode; |
2032 | - } |
2033 | - if (ML_(am_resolve_filename)(fd, buf, VKI_PATH_MAX)) { |
2034 | - seg.fnIdx = allocate_segname( buf ); |
2035 | - } |
2036 | - } |
2037 | - add_segment( &seg ); |
2038 | - AM_SANITY_CHECK; |
2039 | - return needDiscard; |
2040 | -} |
2041 | - |
2042 | -/* Notifies aspacem that the client completed a shmat successfully. |
2043 | - The segment array is updated accordingly. If the returned Bool is |
2044 | - True, the caller should immediately discard translations from the |
2045 | - specified address range. */ |
2046 | - |
2047 | -Bool |
2048 | -VG_(am_notify_client_shmat)( Addr a, SizeT len, UInt prot ) |
2049 | -{ |
2050 | - NSegment seg; |
2051 | - Bool needDiscard; |
2052 | - |
2053 | - aspacem_assert(len > 0); |
2054 | - aspacem_assert(VG_IS_PAGE_ALIGNED(a)); |
2055 | - aspacem_assert(VG_IS_PAGE_ALIGNED(len)); |
2056 | - |
2057 | - /* Discard is needed if any of the just-trashed range had T. */ |
2058 | - needDiscard = any_Ts_in_range( a, len ); |
2059 | - |
2060 | - init_nsegment( &seg ); |
2061 | - seg.kind = SkShmC; |
2062 | - seg.start = a; |
2063 | - seg.end = a + len - 1; |
2064 | - seg.offset = 0; |
2065 | - seg.hasR = toBool(prot & VKI_PROT_READ); |
2066 | - seg.hasW = toBool(prot & VKI_PROT_WRITE); |
2067 | - seg.hasX = toBool(prot & VKI_PROT_EXEC); |
2068 | - add_segment( &seg ); |
2069 | - AM_SANITY_CHECK; |
2070 | - return needDiscard; |
2071 | -} |
2072 | - |
2073 | -/* Notifies aspacem that an mprotect was completed successfully. The |
2074 | - segment array is updated accordingly. Note, as with |
2075 | - VG_(am_notify_munmap), it is not the job of this function to reject |
2076 | - stupid mprotects, for example the client doing mprotect of |
2077 | - non-client areas. Such requests should be intercepted earlier, by |
2078 | - the syscall wrapper for mprotect. This function merely records |
2079 | - whatever it is told. If the returned Bool is True, the caller |
2080 | - should immediately discard translations from the specified address |
2081 | - range. */ |
2082 | - |
2083 | -Bool VG_(am_notify_mprotect)( Addr start, SizeT len, UInt prot ) |
2084 | -{ |
2085 | - Int i, iLo, iHi; |
2086 | - Bool newR, newW, newX, needDiscard; |
2087 | - |
2088 | - aspacem_assert(VG_IS_PAGE_ALIGNED(start)); |
2089 | - aspacem_assert(VG_IS_PAGE_ALIGNED(len)); |
2090 | - |
2091 | - if (len == 0) |
2092 | - return False; |
2093 | - |
2094 | - newR = toBool(prot & VKI_PROT_READ); |
2095 | - newW = toBool(prot & VKI_PROT_WRITE); |
2096 | - newX = toBool(prot & VKI_PROT_EXEC); |
2097 | - |
2098 | - /* Discard is needed if we're dumping X permission */ |
2099 | - needDiscard = any_Ts_in_range( start, len ) && !newX; |
2100 | - |
2101 | - split_nsegments_lo_and_hi( start, start+len-1, &iLo, &iHi ); |
2102 | - |
2103 | - iLo = find_nsegment_idx(start); |
2104 | - iHi = find_nsegment_idx(start + len - 1); |
2105 | - |
2106 | - for (i = iLo; i <= iHi; i++) { |
2107 | - /* Apply the permissions to all relevant segments. */ |
2108 | - switch (nsegments[i].kind) { |
2109 | - case SkAnonC: case SkAnonV: case SkFileC: case SkFileV: case SkShmC: |
2110 | - nsegments[i].hasR = newR; |
2111 | - nsegments[i].hasW = newW; |
2112 | - nsegments[i].hasX = newX; |
2113 | - aspacem_assert(sane_NSegment(&nsegments[i])); |
2114 | - break; |
2115 | - default: |
2116 | - break; |
2117 | - } |
2118 | - } |
2119 | - |
2120 | - /* Changing permissions could have made previously un-mergable |
2121 | - segments mergeable. Therefore have to re-preen them. */ |
2122 | - (void)preen_nsegments(); |
2123 | - AM_SANITY_CHECK; |
2124 | - return needDiscard; |
2125 | -} |
2126 | - |
2127 | - |
2128 | -/* Notifies aspacem that an munmap completed successfully. The |
2129 | - segment array is updated accordingly. As with |
2130 | - VG_(am_notify_munmap), we merely record the given info, and don't |
2131 | - check it for sensibleness. If the returned Bool is True, the |
2132 | - caller should immediately discard translations from the specified |
2133 | - address range. */ |
2134 | - |
2135 | -Bool VG_(am_notify_munmap)( Addr start, SizeT len ) |
2136 | -{ |
2137 | - NSegment seg; |
2138 | - Bool needDiscard; |
2139 | - aspacem_assert(VG_IS_PAGE_ALIGNED(start)); |
2140 | - aspacem_assert(VG_IS_PAGE_ALIGNED(len)); |
2141 | - |
2142 | - if (len == 0) |
2143 | - return False; |
2144 | - |
2145 | - needDiscard = any_Ts_in_range( start, len ); |
2146 | - |
2147 | - init_nsegment( &seg ); |
2148 | - seg.start = start; |
2149 | - seg.end = start + len - 1; |
2150 | - |
2151 | - /* The segment becomes unused (free). Segments from above |
2152 | - aspacem_maxAddr were originally SkResvn and so we make them so |
2153 | - again. Note, this isn't really right when the segment straddles |
2154 | - the aspacem_maxAddr boundary - then really it should be split in |
2155 | - two, the lower part marked as SkFree and the upper part as |
2156 | - SkResvn. Ah well. */ |
2157 | - if (start > aspacem_maxAddr |
2158 | - && /* check previous comparison is meaningful */ |
2159 | - aspacem_maxAddr < Addr_MAX) |
2160 | - seg.kind = SkResvn; |
2161 | - else |
2162 | - /* Ditto for segments from below aspacem_minAddr. */ |
2163 | - if (seg.end < aspacem_minAddr && aspacem_minAddr > 0) |
2164 | - seg.kind = SkResvn; |
2165 | - else |
2166 | - seg.kind = SkFree; |
2167 | - |
2168 | - add_segment( &seg ); |
2169 | - |
2170 | - /* Unmapping could create two adjacent free segments, so a preen is |
2171 | - needed. add_segment() will do that, so no need to here. */ |
2172 | - AM_SANITY_CHECK; |
2173 | - return needDiscard; |
2174 | -} |
2175 | - |
2176 | - |
2177 | -/*-----------------------------------------------------------------*/ |
2178 | -/*--- ---*/ |
2179 | -/*--- Handling mappings which do not arise directly from the ---*/ |
2180 | -/*--- simulation of the client. ---*/ |
2181 | -/*--- ---*/ |
2182 | -/*-----------------------------------------------------------------*/ |
2183 | - |
2184 | -/* --- --- --- map, unmap, protect --- --- --- */ |
2185 | - |
2186 | -/* Map a file at a fixed address for the client, and update the |
2187 | - segment array accordingly. */ |
2188 | - |
2189 | -SysRes VG_(am_mmap_file_fixed_client) |
2190 | - ( Addr start, SizeT length, UInt prot, Int fd, Off64T offset ) |
2191 | -{ |
2192 | - return VG_(am_mmap_named_file_fixed_client)(start, length, prot, fd, offset, NULL); |
2193 | -} |
2194 | - |
2195 | -SysRes VG_(am_mmap_named_file_fixed_client) |
2196 | - ( Addr start, SizeT length, UInt prot, Int fd, Off64T offset, const HChar *name ) |
2197 | -{ |
2198 | - SysRes sres; |
2199 | - NSegment seg; |
2200 | - Addr advised; |
2201 | - Bool ok; |
2202 | - MapRequest req; |
2203 | - ULong dev, ino; |
2204 | - UInt mode; |
2205 | - HChar buf[VKI_PATH_MAX]; |
2206 | - |
2207 | - /* Not allowable. */ |
2208 | - if (length == 0 |
2209 | - || !VG_IS_PAGE_ALIGNED(start) |
2210 | - || !VG_IS_PAGE_ALIGNED(offset)) |
2211 | - return VG_(mk_SysRes_Error)( VKI_EINVAL ); |
2212 | - |
2213 | - /* Ask for an advisory. If it's negative, fail immediately. */ |
2214 | - req.rkind = MFixed; |
2215 | - req.start = start; |
2216 | - req.len = length; |
2217 | - advised = VG_(am_get_advisory)( &req, True/*client*/, &ok ); |
2218 | - if (!ok || advised != start) |
2219 | - return VG_(mk_SysRes_Error)( VKI_EINVAL ); |
2220 | - |
2221 | - /* We have been advised that the mapping is allowable at the |
2222 | - specified address. So hand it off to the kernel, and propagate |
2223 | - any resulting failure immediately. */ |
2224 | - // DDD: #warning GrP fixme MAP_FIXED can clobber memory! |
2225 | - sres = VG_(am_do_mmap_NO_NOTIFY)( |
2226 | - start, length, prot, |
2227 | - VKI_MAP_FIXED|VKI_MAP_PRIVATE, |
2228 | - fd, offset |
2229 | - ); |
2230 | - if (sr_isError(sres)) |
2231 | - return sres; |
2232 | - |
2233 | - if (sr_Res(sres) != start) { |
2234 | - /* I don't think this can happen. It means the kernel made a |
2235 | - fixed map succeed but not at the requested location. Try to |
2236 | - repair the damage, then return saying the mapping failed. */ |
2237 | - (void)ML_(am_do_munmap_NO_NOTIFY)( sr_Res(sres), length ); |
2238 | - return VG_(mk_SysRes_Error)( VKI_EINVAL ); |
2239 | - } |
2240 | - |
2241 | - /* Ok, the mapping succeeded. Now notify the interval map. */ |
2242 | - init_nsegment( &seg ); |
2243 | - seg.kind = SkFileC; |
2244 | - seg.start = start; |
2245 | - seg.end = seg.start + VG_PGROUNDUP(length) - 1; |
2246 | - seg.offset = offset; |
2247 | - seg.hasR = toBool(prot & VKI_PROT_READ); |
2248 | - seg.hasW = toBool(prot & VKI_PROT_WRITE); |
2249 | - seg.hasX = toBool(prot & VKI_PROT_EXEC); |
2250 | - if (ML_(am_get_fd_d_i_m)(fd, &dev, &ino, &mode)) { |
2251 | - seg.dev = dev; |
2252 | - seg.ino = ino; |
2253 | - seg.mode = mode; |
2254 | - } |
2255 | - if (name) { |
2256 | - seg.fnIdx = allocate_segname( name ); |
2257 | - } else if (ML_(am_resolve_filename)(fd, buf, VKI_PATH_MAX)) { |
2258 | - seg.fnIdx = allocate_segname( buf ); |
2259 | - } |
2260 | - add_segment( &seg ); |
2261 | - |
2262 | - AM_SANITY_CHECK; |
2263 | - return sres; |
2264 | -} |
2265 | - |
2266 | - |
2267 | -/* Map anonymously at a fixed address for the client, and update |
2268 | - the segment array accordingly. */ |
2269 | - |
2270 | -SysRes VG_(am_mmap_anon_fixed_client) ( Addr start, SizeT length, UInt prot ) |
2271 | -{ |
2272 | - SysRes sres; |
2273 | - NSegment seg; |
2274 | - Addr advised; |
2275 | - Bool ok; |
2276 | - MapRequest req; |
2277 | - |
2278 | - /* Not allowable. */ |
2279 | - if (length == 0 || !VG_IS_PAGE_ALIGNED(start)) |
2280 | - return VG_(mk_SysRes_Error)( VKI_EINVAL ); |
2281 | - |
2282 | - /* Ask for an advisory. If it's negative, fail immediately. */ |
2283 | - req.rkind = MFixed; |
2284 | - req.start = start; |
2285 | - req.len = length; |
2286 | - advised = VG_(am_get_advisory)( &req, True/*client*/, &ok ); |
2287 | - if (!ok || advised != start) |
2288 | - return VG_(mk_SysRes_Error)( VKI_EINVAL ); |
2289 | - |
2290 | - /* We have been advised that the mapping is allowable at the |
2291 | - specified address. So hand it off to the kernel, and propagate |
2292 | - any resulting failure immediately. */ |
2293 | - // DDD: #warning GrP fixme MAP_FIXED can clobber memory! |
2294 | - sres = VG_(am_do_mmap_NO_NOTIFY)( |
2295 | - start, length, prot, |
2296 | - VKI_MAP_FIXED|VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS, |
2297 | - 0, 0 |
2298 | - ); |
2299 | - if (sr_isError(sres)) |
2300 | - return sres; |
2301 | - |
2302 | - if (sr_Res(sres) != start) { |
2303 | - /* I don't think this can happen. It means the kernel made a |
2304 | - fixed map succeed but not at the requested location. Try to |
2305 | - repair the damage, then return saying the mapping failed. */ |
2306 | - (void)ML_(am_do_munmap_NO_NOTIFY)( sr_Res(sres), length ); |
2307 | - return VG_(mk_SysRes_Error)( VKI_EINVAL ); |
2308 | - } |
2309 | - |
2310 | - /* Ok, the mapping succeeded. Now notify the interval map. */ |
2311 | - init_nsegment( &seg ); |
2312 | - seg.kind = SkAnonC; |
2313 | - seg.start = start; |
2314 | - seg.end = seg.start + VG_PGROUNDUP(length) - 1; |
2315 | - seg.hasR = toBool(prot & VKI_PROT_READ); |
2316 | - seg.hasW = toBool(prot & VKI_PROT_WRITE); |
2317 | - seg.hasX = toBool(prot & VKI_PROT_EXEC); |
2318 | - add_segment( &seg ); |
2319 | - |
2320 | - AM_SANITY_CHECK; |
2321 | - return sres; |
2322 | -} |
2323 | - |
2324 | - |
2325 | -/* Map anonymously at an unconstrained address for the client, and |
2326 | - update the segment array accordingly. */ |
2327 | - |
2328 | -SysRes VG_(am_mmap_anon_float_client) ( SizeT length, Int prot ) |
2329 | -{ |
2330 | - SysRes sres; |
2331 | - NSegment seg; |
2332 | - Addr advised; |
2333 | - Bool ok; |
2334 | - MapRequest req; |
2335 | - |
2336 | - /* Not allowable. */ |
2337 | - if (length == 0) |
2338 | - return VG_(mk_SysRes_Error)( VKI_EINVAL ); |
2339 | - |
2340 | - /* Ask for an advisory. If it's negative, fail immediately. */ |
2341 | - req.rkind = MAny; |
2342 | - req.start = 0; |
2343 | - req.len = length; |
2344 | - advised = VG_(am_get_advisory)( &req, True/*client*/, &ok ); |
2345 | - if (!ok) |
2346 | - return VG_(mk_SysRes_Error)( VKI_EINVAL ); |
2347 | - |
2348 | - /* We have been advised that the mapping is allowable at the |
2349 | - advised address. So hand it off to the kernel, and propagate |
2350 | - any resulting failure immediately. */ |
2351 | - // DDD: #warning GrP fixme MAP_FIXED can clobber memory! |
2352 | - sres = VG_(am_do_mmap_NO_NOTIFY)( |
2353 | - advised, length, prot, |
2354 | - VKI_MAP_FIXED|VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS, |
2355 | - 0, 0 |
2356 | - ); |
2357 | - if (sr_isError(sres)) |
2358 | - return sres; |
2359 | - |
2360 | - if (sr_Res(sres) != advised) { |
2361 | - /* I don't think this can happen. It means the kernel made a |
2362 | - fixed map succeed but not at the requested location. Try to |
2363 | - repair the damage, then return saying the mapping failed. */ |
2364 | - (void)ML_(am_do_munmap_NO_NOTIFY)( sr_Res(sres), length ); |
2365 | - return VG_(mk_SysRes_Error)( VKI_EINVAL ); |
2366 | - } |
2367 | - |
2368 | - /* Ok, the mapping succeeded. Now notify the interval map. */ |
2369 | - init_nsegment( &seg ); |
2370 | - seg.kind = SkAnonC; |
2371 | - seg.start = advised; |
2372 | - seg.end = seg.start + VG_PGROUNDUP(length) - 1; |
2373 | - seg.hasR = toBool(prot & VKI_PROT_READ); |
2374 | - seg.hasW = toBool(prot & VKI_PROT_WRITE); |
2375 | - seg.hasX = toBool(prot & VKI_PROT_EXEC); |
2376 | - add_segment( &seg ); |
2377 | - |
2378 | - AM_SANITY_CHECK; |
2379 | - return sres; |
2380 | -} |
2381 | - |
2382 | - |
2383 | -/* Similarly, acquire new address space for the client but with |
2384 | - considerable restrictions on what can be done with it: (1) the |
2385 | - actual protections may exceed those stated in 'prot', (2) the |
2386 | - area's protections cannot be later changed using any form of |
2387 | - mprotect, and (3) the area cannot be freed using any form of |
2388 | - munmap. On Linux this behaves the same as |
2389 | - VG_(am_mmap_anon_float_client). On AIX5 this *may* allocate memory |
2390 | - by using sbrk, so as to make use of large pages on AIX. */ |
2391 | - |
2392 | -SysRes VG_(am_sbrk_anon_float_client) ( SizeT length, Int prot ) |
2393 | -{ |
2394 | - return VG_(am_mmap_anon_float_client) ( length, prot ); |
2395 | -} |
2396 | - |
2397 | - |
2398 | -/* Map anonymously at an unconstrained address for V, and update the |
2399 | - segment array accordingly. This is fundamentally how V allocates |
2400 | - itself more address space when needed. */ |
2401 | - |
2402 | -SysRes VG_(am_mmap_anon_float_valgrind)( SizeT length ) |
2403 | -{ |
2404 | - SysRes sres; |
2405 | - NSegment seg; |
2406 | - Addr advised; |
2407 | - Bool ok; |
2408 | - MapRequest req; |
2409 | - |
2410 | - /* Not allowable. */ |
2411 | - if (length == 0) |
2412 | - return VG_(mk_SysRes_Error)( VKI_EINVAL ); |
2413 | - |
2414 | - /* Ask for an advisory. If it's negative, fail immediately. */ |
2415 | - req.rkind = MAny; |
2416 | - req.start = 0; |
2417 | - req.len = length; |
2418 | - advised = VG_(am_get_advisory)( &req, False/*valgrind*/, &ok ); |
2419 | - if (!ok) |
2420 | - return VG_(mk_SysRes_Error)( VKI_EINVAL ); |
2421 | - |
2422 | -// On Darwin, for anonymous maps you can pass in a tag which is used by |
2423 | -// programs like vmmap for statistical purposes. |
2424 | -#ifndef VM_TAG_VALGRIND |
2425 | -# define VM_TAG_VALGRIND 0 |
2426 | -#endif |
2427 | - |
2428 | - /* We have been advised that the mapping is allowable at the |
2429 | - specified address. So hand it off to the kernel, and propagate |
2430 | - any resulting failure immediately. */ |
2431 | - /* GrP fixme darwin: use advisory as a hint only, otherwise syscall in |
2432 | - another thread can pre-empt our spot. [At one point on the DARWIN |
2433 | - branch the VKI_MAP_FIXED was commented out; unclear if this is |
2434 | - necessary or not given the second Darwin-only call that immediately |
2435 | - follows if this one fails. --njn] */ |
2436 | - sres = VG_(am_do_mmap_NO_NOTIFY)( |
2437 | - advised, length, |
2438 | - VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC, |
2439 | - VKI_MAP_FIXED|VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS, |
2440 | - VM_TAG_VALGRIND, 0 |
2441 | - ); |
2442 | -#if defined(VGO_darwin) |
2443 | - if (sr_isError(sres)) { |
2444 | - /* try again, ignoring the advisory */ |
2445 | - sres = VG_(am_do_mmap_NO_NOTIFY)( |
2446 | - 0, length, |
2447 | - VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC, |
2448 | - /*VKI_MAP_FIXED|*/VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS, |
2449 | - VM_TAG_VALGRIND, 0 |
2450 | - ); |
2451 | - } |
2452 | -#endif |
2453 | - if (sr_isError(sres)) |
2454 | - return sres; |
2455 | - |
2456 | -#if defined(VGO_linux) |
2457 | - if (sr_Res(sres) != advised) { |
2458 | - /* I don't think this can happen. It means the kernel made a |
2459 | - fixed map succeed but not at the requested location. Try to |
2460 | - repair the damage, then return saying the mapping failed. */ |
2461 | - (void)ML_(am_do_munmap_NO_NOTIFY)( sr_Res(sres), length ); |
2462 | - return VG_(mk_SysRes_Error)( VKI_EINVAL ); |
2463 | - } |
2464 | -#endif |
2465 | - |
2466 | - /* Ok, the mapping succeeded. Now notify the interval map. */ |
2467 | - init_nsegment( &seg ); |
2468 | - seg.kind = SkAnonV; |
2469 | - seg.start = sr_Res(sres); |
2470 | - seg.end = seg.start + VG_PGROUNDUP(length) - 1; |
2471 | - seg.hasR = True; |
2472 | - seg.hasW = True; |
2473 | - seg.hasX = True; |
2474 | - add_segment( &seg ); |
2475 | - |
2476 | - AM_SANITY_CHECK; |
2477 | - return sres; |
2478 | -} |
2479 | - |
2480 | -/* Really just a wrapper around VG_(am_mmap_anon_float_valgrind). */ |
2481 | - |
2482 | -void* VG_(am_shadow_alloc)(SizeT size) |
2483 | -{ |
2484 | - SysRes sres = VG_(am_mmap_anon_float_valgrind)( size ); |
2485 | - return sr_isError(sres) ? NULL : (void*)sr_Res(sres); |
2486 | -} |
2487 | - |
2488 | -/* Same comments apply as per VG_(am_sbrk_anon_float_client). On |
2489 | - Linux this behaves the same as VG_(am_mmap_anon_float_valgrind). */ |
2490 | - |
2491 | -SysRes VG_(am_sbrk_anon_float_valgrind)( SizeT cszB ) |
2492 | -{ |
2493 | - return VG_(am_mmap_anon_float_valgrind)( cszB ); |
2494 | -} |
2495 | - |
2496 | - |
2497 | -/* Map a file at an unconstrained address for V, and update the |
2498 | - segment array accordingly. Use the provided flags */ |
2499 | - |
2500 | -static SysRes VG_(am_mmap_file_float_valgrind_flags) ( SizeT length, UInt prot, |
2501 | - UInt flags, |
2502 | - Int fd, Off64T offset ) |
2503 | -{ |
2504 | - SysRes sres; |
2505 | - NSegment seg; |
2506 | - Addr advised; |
2507 | - Bool ok; |
2508 | - MapRequest req; |
2509 | - ULong dev, ino; |
2510 | - UInt mode; |
2511 | - HChar buf[VKI_PATH_MAX]; |
2512 | - |
2513 | - /* Not allowable. */ |
2514 | - if (length == 0 || !VG_IS_PAGE_ALIGNED(offset)) |
2515 | - return VG_(mk_SysRes_Error)( VKI_EINVAL ); |
2516 | - |
2517 | - /* Ask for an advisory. If it's negative, fail immediately. */ |
2518 | - req.rkind = MAny; |
2519 | - req.start = 0; |
2520 | - req.len = length; |
2521 | - advised = VG_(am_get_advisory)( &req, True/*client*/, &ok ); |
2522 | - if (!ok) |
2523 | - return VG_(mk_SysRes_Error)( VKI_EINVAL ); |
2524 | - |
2525 | - /* We have been advised that the mapping is allowable at the |
2526 | - specified address. So hand it off to the kernel, and propagate |
2527 | - any resulting failure immediately. */ |
2528 | - sres = VG_(am_do_mmap_NO_NOTIFY)( |
2529 | - advised, length, prot, |
2530 | - flags, |
2531 | - fd, offset |
2532 | - ); |
2533 | - if (sr_isError(sres)) |
2534 | - return sres; |
2535 | - |
2536 | - if (sr_Res(sres) != advised) { |
2537 | - /* I don't think this can happen. It means the kernel made a |
2538 | - fixed map succeed but not at the requested location. Try to |
2539 | - repair the damage, then return saying the mapping failed. */ |
2540 | - (void)ML_(am_do_munmap_NO_NOTIFY)( sr_Res(sres), length ); |
2541 | - return VG_(mk_SysRes_Error)( VKI_EINVAL ); |
2542 | - } |
2543 | - |
2544 | - /* Ok, the mapping succeeded. Now notify the interval map. */ |
2545 | - init_nsegment( &seg ); |
2546 | - seg.kind = SkFileV; |
2547 | - seg.start = sr_Res(sres); |
2548 | - seg.end = seg.start + VG_PGROUNDUP(length) - 1; |
2549 | - seg.offset = offset; |
2550 | - seg.hasR = toBool(prot & VKI_PROT_READ); |
2551 | - seg.hasW = toBool(prot & VKI_PROT_WRITE); |
2552 | - seg.hasX = toBool(prot & VKI_PROT_EXEC); |
2553 | - if (ML_(am_get_fd_d_i_m)(fd, &dev, &ino, &mode)) { |
2554 | - seg.dev = dev; |
2555 | - seg.ino = ino; |
2556 | - seg.mode = mode; |
2557 | - } |
2558 | - if (ML_(am_resolve_filename)(fd, buf, VKI_PATH_MAX)) { |
2559 | - seg.fnIdx = allocate_segname( buf ); |
2560 | - } |
2561 | - add_segment( &seg ); |
2562 | - |
2563 | - AM_SANITY_CHECK; |
2564 | - return sres; |
2565 | -} |
2566 | -/* Map privately a file at an unconstrained address for V, and update the |
2567 | - segment array accordingly. This is used by V for transiently |
2568 | - mapping in object files to read their debug info. */ |
2569 | - |
2570 | -SysRes VG_(am_mmap_file_float_valgrind) ( SizeT length, UInt prot, |
2571 | - Int fd, Off64T offset ) |
2572 | -{ |
2573 | - return VG_(am_mmap_file_float_valgrind_flags) (length, prot, |
2574 | - VKI_MAP_FIXED|VKI_MAP_PRIVATE, |
2575 | - fd, offset ); |
2576 | -} |
2577 | - |
2578 | -extern SysRes VG_(am_shared_mmap_file_float_valgrind) |
2579 | - ( SizeT length, UInt prot, Int fd, Off64T offset ) |
2580 | -{ |
2581 | - return VG_(am_mmap_file_float_valgrind_flags) (length, prot, |
2582 | - VKI_MAP_FIXED|VKI_MAP_SHARED, |
2583 | - fd, offset ); |
2584 | -} |
2585 | - |
2586 | -/* --- --- munmap helper --- --- */ |
2587 | - |
2588 | -static |
2589 | -SysRes am_munmap_both_wrk ( /*OUT*/Bool* need_discard, |
2590 | - Addr start, SizeT len, Bool forClient ) |
2591 | -{ |
2592 | - Bool d; |
2593 | - SysRes sres; |
2594 | - |
2595 | - if (!VG_IS_PAGE_ALIGNED(start)) |
2596 | - goto eINVAL; |
2597 | - |
2598 | - if (len == 0) { |
2599 | - *need_discard = False; |
2600 | - return VG_(mk_SysRes_Success)( 0 ); |
2601 | - } |
2602 | - |
2603 | - if (start + len < len) |
2604 | - goto eINVAL; |
2605 | - |
2606 | - len = VG_PGROUNDUP(len); |
2607 | - aspacem_assert(VG_IS_PAGE_ALIGNED(start)); |
2608 | - aspacem_assert(VG_IS_PAGE_ALIGNED(len)); |
2609 | - |
2610 | - if (forClient) { |
2611 | - if (!VG_(am_is_valid_for_client_or_free_or_resvn) |
2612 | - ( start, len, VKI_PROT_NONE )) |
2613 | - goto eINVAL; |
2614 | - } else { |
2615 | - if (!is_valid_for_valgrind( start, len )) |
2616 | - goto eINVAL; |
2617 | - } |
2618 | - |
2619 | - d = any_Ts_in_range( start, len ); |
2620 | - |
2621 | - sres = ML_(am_do_munmap_NO_NOTIFY)( start, len ); |
2622 | - if (sr_isError(sres)) |
2623 | - return sres; |
2624 | - |
2625 | - VG_(am_notify_munmap)( start, len ); |
2626 | - AM_SANITY_CHECK; |
2627 | - *need_discard = d; |
2628 | - return sres; |
2629 | - |
2630 | - eINVAL: |
2631 | - return VG_(mk_SysRes_Error)( VKI_EINVAL ); |
2632 | -} |
2633 | - |
2634 | -/* Unmap the given address range and update the segment array |
2635 | - accordingly. This fails if the range isn't valid for the client. |
2636 | - If *need_discard is True after a successful return, the caller |
2637 | - should immediately discard translations from the specified address |
2638 | - range. */ |
2639 | - |
2640 | -SysRes VG_(am_munmap_client)( /*OUT*/Bool* need_discard, |
2641 | - Addr start, SizeT len ) |
2642 | -{ |
2643 | - return am_munmap_both_wrk( need_discard, start, len, True/*client*/ ); |
2644 | -} |
2645 | - |
2646 | -/* Unmap the given address range and update the segment array |
2647 | - accordingly. This fails if the range isn't valid for valgrind. */ |
2648 | - |
2649 | -SysRes VG_(am_munmap_valgrind)( Addr start, SizeT len ) |
2650 | -{ |
2651 | - Bool need_discard; |
2652 | - SysRes r = am_munmap_both_wrk( &need_discard, |
2653 | - start, len, False/*valgrind*/ ); |
2654 | - /* If this assertion fails, it means we allowed translations to be |
2655 | - made from a V-owned section. Which shouldn't happen. */ |
2656 | - if (!sr_isError(r)) |
2657 | - aspacem_assert(!need_discard); |
2658 | - return r; |
2659 | -} |
2660 | - |
2661 | -/* Let (start,len) denote an area within a single Valgrind-owned |
2662 | - segment (anon or file). Change the ownership of [start, start+len) |
2663 | - to the client instead. Fails if (start,len) does not denote a |
2664 | - suitable segment. */ |
2665 | - |
2666 | -Bool VG_(am_change_ownership_v_to_c)( Addr start, SizeT len ) |
2667 | -{ |
2668 | - Int i, iLo, iHi; |
2669 | - |
2670 | - if (len == 0) |
2671 | - return True; |
2672 | - if (start + len < start) |
2673 | - return False; |
2674 | - if (!VG_IS_PAGE_ALIGNED(start) || !VG_IS_PAGE_ALIGNED(len)) |
2675 | - return False; |
2676 | - |
2677 | - i = find_nsegment_idx(start); |
2678 | - if (nsegments[i].kind != SkFileV && nsegments[i].kind != SkAnonV) |
2679 | - return False; |
2680 | - if (start+len-1 > nsegments[i].end) |
2681 | - return False; |
2682 | - |
2683 | - aspacem_assert(start >= nsegments[i].start); |
2684 | - aspacem_assert(start+len-1 <= nsegments[i].end); |
2685 | - |
2686 | - /* This scheme is like how mprotect works: split the to-be-changed |
2687 | - range into its own segment(s), then mess with them (it). There |
2688 | - should be only one. */ |
2689 | - split_nsegments_lo_and_hi( start, start+len-1, &iLo, &iHi ); |
2690 | - aspacem_assert(iLo == iHi); |
2691 | - switch (nsegments[iLo].kind) { |
2692 | - case SkFileV: nsegments[iLo].kind = SkFileC; break; |
2693 | - case SkAnonV: nsegments[iLo].kind = SkAnonC; break; |
2694 | - default: aspacem_assert(0); /* can't happen - guarded above */ |
2695 | - } |
2696 | - |
2697 | - preen_nsegments(); |
2698 | - return True; |
2699 | -} |
2700 | - |
2701 | -/* 'seg' must be NULL or have been obtained from |
2702 | - VG_(am_find_nsegment), and still valid. If non-NULL, and if it |
2703 | - denotes a SkAnonC (anonymous client mapping) area, set the .isCH |
2704 | - (is-client-heap) flag for that area. Otherwise do nothing. |
2705 | - (Bizarre interface so that the same code works for both Linux and |
2706 | - AIX and does not impose inefficiencies on the Linux version.) */ |
2707 | -void VG_(am_set_segment_isCH_if_SkAnonC)( NSegment* seg ) |
2708 | -{ |
2709 | - Int i = segAddr_to_index( seg ); |
2710 | - aspacem_assert(i >= 0 && i < nsegments_used); |
2711 | - if (nsegments[i].kind == SkAnonC) { |
2712 | - nsegments[i].isCH = True; |
2713 | - } else { |
2714 | - aspacem_assert(nsegments[i].isCH == False); |
2715 | - } |
2716 | -} |
2717 | - |
2718 | -/* Same idea as VG_(am_set_segment_isCH_if_SkAnonC), except set the |
2719 | - segment's hasT bit (has-cached-code) if this is SkFileC or SkAnonC |
2720 | - segment. */ |
2721 | -void VG_(am_set_segment_hasT_if_SkFileC_or_SkAnonC)( NSegment* seg ) |
2722 | -{ |
2723 | - Int i = segAddr_to_index( seg ); |
2724 | - aspacem_assert(i >= 0 && i < nsegments_used); |
2725 | - if (nsegments[i].kind == SkAnonC || nsegments[i].kind == SkFileC) { |
2726 | - nsegments[i].hasT = True; |
2727 | - } |
2728 | -} |
2729 | - |
2730 | - |
2731 | -/* --- --- --- reservations --- --- --- */ |
2732 | - |
2733 | -/* Create a reservation from START .. START+LENGTH-1, with the given |
2734 | - ShrinkMode. When checking whether the reservation can be created, |
2735 | - also ensure that at least abs(EXTRA) extra free bytes will remain |
2736 | - above (> 0) or below (< 0) the reservation. |
2737 | - |
2738 | - The reservation will only be created if it, plus the extra-zone, |
2739 | - falls entirely within a single free segment. The returned Bool |
2740 | - indicates whether the creation succeeded. */ |
2741 | - |
2742 | -Bool VG_(am_create_reservation) ( Addr start, SizeT length, |
2743 | - ShrinkMode smode, SSizeT extra ) |
2744 | -{ |
2745 | - Int startI, endI; |
2746 | - NSegment seg; |
2747 | - |
2748 | - /* start and end, not taking into account the extra space. */ |
2749 | - Addr start1 = start; |
2750 | - Addr end1 = start + length - 1; |
2751 | - |
2752 | - /* start and end, taking into account the extra space. */ |
2753 | - Addr start2 = start1; |
2754 | - Addr end2 = end1; |
2755 | - |
2756 | - if (extra < 0) start2 += extra; // this moves it down :-) |
2757 | - if (extra > 0) end2 += extra; |
2758 | - |
2759 | - aspacem_assert(VG_IS_PAGE_ALIGNED(start)); |
2760 | - aspacem_assert(VG_IS_PAGE_ALIGNED(start+length)); |
2761 | - aspacem_assert(VG_IS_PAGE_ALIGNED(start2)); |
2762 | - aspacem_assert(VG_IS_PAGE_ALIGNED(end2+1)); |
2763 | - |
2764 | - startI = find_nsegment_idx( start2 ); |
2765 | - endI = find_nsegment_idx( end2 ); |
2766 | - |
2767 | - /* If the start and end points don't fall within the same (free) |
2768 | - segment, we're hosed. This does rely on the assumption that all |
2769 | - mergeable adjacent segments can be merged, but add_segment() |
2770 | - should ensure that. */ |
2771 | - if (startI != endI) |
2772 | - return False; |
2773 | - |
2774 | - if (nsegments[startI].kind != SkFree) |
2775 | - return False; |
2776 | - |
2777 | - /* Looks good - make the reservation. */ |
2778 | - aspacem_assert(nsegments[startI].start <= start2); |
2779 | - aspacem_assert(end2 <= nsegments[startI].end); |
2780 | - |
2781 | - init_nsegment( &seg ); |
2782 | - seg.kind = SkResvn; |
2783 | - seg.start = start1; /* NB: extra space is not included in the |
2784 | - reservation. */ |
2785 | - seg.end = end1; |
2786 | - seg.smode = smode; |
2787 | - add_segment( &seg ); |
2788 | - |
2789 | - AM_SANITY_CHECK; |
2790 | - return True; |
2791 | -} |
2792 | - |
2793 | - |
2794 | -/* Let SEG be an anonymous client mapping. This fn extends the |
2795 | - mapping by DELTA bytes, taking the space from a reservation section |
2796 | - which must be adjacent. If DELTA is positive, the segment is |
2797 | - extended forwards in the address space, and the reservation must be |
2798 | - the next one along. If DELTA is negative, the segment is extended |
2799 | - backwards in the address space and the reservation must be the |
2800 | - previous one. DELTA must be page aligned. abs(DELTA) must not |
2801 | - exceed the size of the reservation segment minus one page, that is, |
2802 | - the reservation segment after the operation must be at least one |
2803 | - page long. */ |
2804 | - |
2805 | -Bool VG_(am_extend_into_adjacent_reservation_client) ( NSegment* seg, |
2806 | - SSizeT delta ) |
2807 | -{ |
2808 | - Int segA, segR; |
2809 | - UInt prot; |
2810 | - SysRes sres; |
2811 | - |
2812 | - /* Find the segment array index for SEG. If the assertion fails it |
2813 | - probably means you passed in a bogus SEG. */ |
2814 | - segA = segAddr_to_index( seg ); |
2815 | - aspacem_assert(segA >= 0 && segA < nsegments_used); |
2816 | - |
2817 | - if (nsegments[segA].kind != SkAnonC) |
2818 | - return False; |
2819 | - |
2820 | - if (delta == 0) |
2821 | - return True; |
2822 | - |
2823 | - prot = (nsegments[segA].hasR ? VKI_PROT_READ : 0) |
2824 | - | (nsegments[segA].hasW ? VKI_PROT_WRITE : 0) |
2825 | - | (nsegments[segA].hasX ? VKI_PROT_EXEC : 0); |
2826 | - |
2827 | - aspacem_assert(VG_IS_PAGE_ALIGNED(delta<0 ? -delta : delta)); |
2828 | - |
2829 | - if (delta > 0) { |
2830 | - |
2831 | - /* Extending the segment forwards. */ |
2832 | - segR = segA+1; |
2833 | - if (segR >= nsegments_used |
2834 | - || nsegments[segR].kind != SkResvn |
2835 | - || nsegments[segR].smode != SmLower |
2836 | - || nsegments[segR].start != nsegments[segA].end + 1 |
2837 | - || delta + VKI_PAGE_SIZE |
2838 | - > (nsegments[segR].end - nsegments[segR].start + 1)) |
2839 | - return False; |
2840 | - |
2841 | - /* Extend the kernel's mapping. */ |
2842 | - // DDD: #warning GrP fixme MAP_FIXED can clobber memory! |
2843 | - sres = VG_(am_do_mmap_NO_NOTIFY)( |
2844 | - nsegments[segR].start, delta, |
2845 | - prot, |
2846 | - VKI_MAP_FIXED|VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS, |
2847 | - 0, 0 |
2848 | - ); |
2849 | - if (sr_isError(sres)) |
2850 | - return False; /* kernel bug if this happens? */ |
2851 | - if (sr_Res(sres) != nsegments[segR].start) { |
2852 | - /* kernel bug if this happens? */ |
2853 | - (void)ML_(am_do_munmap_NO_NOTIFY)( sr_Res(sres), delta ); |
2854 | - return False; |
2855 | - } |
2856 | - |
2857 | - /* Ok, success with the kernel. Update our structures. */ |
2858 | - nsegments[segR].start += delta; |
2859 | - nsegments[segA].end += delta; |
2860 | - aspacem_assert(nsegments[segR].start <= nsegments[segR].end); |
2861 | - |
2862 | - } else { |
2863 | - |
2864 | - /* Extending the segment backwards. */ |
2865 | - delta = -delta; |
2866 | - aspacem_assert(delta > 0); |
2867 | - |
2868 | - segR = segA-1; |
2869 | - if (segR < 0 |
2870 | - || nsegments[segR].kind != SkResvn |
2871 | - || nsegments[segR].smode != SmUpper |
2872 | - || nsegments[segR].end + 1 != nsegments[segA].start |
2873 | - || delta + VKI_PAGE_SIZE |
2874 | - > (nsegments[segR].end - nsegments[segR].start + 1)) |
2875 | - return False; |
2876 | - |
2877 | - /* Extend the kernel's mapping. */ |
2878 | - // DDD: #warning GrP fixme MAP_FIXED can clobber memory! |
2879 | - sres = VG_(am_do_mmap_NO_NOTIFY)( |
2880 | - nsegments[segA].start-delta, delta, |
2881 | - prot, |
2882 | - VKI_MAP_FIXED|VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS, |
2883 | - 0, 0 |
2884 | - ); |
2885 | - if (sr_isError(sres)) |
2886 | - return False; /* kernel bug if this happens? */ |
2887 | - if (sr_Res(sres) != nsegments[segA].start-delta) { |
2888 | - /* kernel bug if this happens? */ |
2889 | - (void)ML_(am_do_munmap_NO_NOTIFY)( sr_Res(sres), delta ); |
2890 | - return False; |
2891 | - } |
2892 | - |
2893 | - /* Ok, success with the kernel. Update our structures. */ |
2894 | - nsegments[segR].end -= delta; |
2895 | - nsegments[segA].start -= delta; |
2896 | - aspacem_assert(nsegments[segR].start <= nsegments[segR].end); |
2897 | - |
2898 | - } |
2899 | - |
2900 | - AM_SANITY_CHECK; |
2901 | - return True; |
2902 | -} |
2903 | - |
2904 | - |
2905 | -/* --- --- --- resizing/move a mapping --- --- --- */ |
2906 | - |
2907 | -#if HAVE_MREMAP |
2908 | - |
2909 | -/* Let SEG be a client mapping (anonymous or file). This fn extends |
2910 | - the mapping forwards only by DELTA bytes, and trashes whatever was |
2911 | - in the new area. Fails if SEG is not a single client mapping or if |
2912 | - the new area is not accessible to the client. Fails if DELTA is |
2913 | - not page aligned. *seg is invalid after a successful return. If |
2914 | - *need_discard is True after a successful return, the caller should |
2915 | - immediately discard translations from the new area. */ |
2916 | - |
2917 | -Bool VG_(am_extend_map_client)( /*OUT*/Bool* need_discard, |
2918 | - NSegment* seg, SizeT delta ) |
2919 | -{ |
2920 | - Addr xStart; |
2921 | - SysRes sres; |
2922 | - NSegment seg_copy = *seg; |
2923 | - SizeT seg_old_len = seg->end + 1 - seg->start; |
2924 | - |
2925 | - if (0) |
2926 | - VG_(am_show_nsegments)(0, "VG_(am_extend_map_client) BEFORE"); |
2927 | - |
2928 | - if (seg->kind != SkFileC && seg->kind != SkAnonC) |
2929 | - return False; |
2930 | - |
2931 | - if (delta == 0 || !VG_IS_PAGE_ALIGNED(delta)) |
2932 | - return False; |
2933 | - |
2934 | - xStart = seg->end+1; |
2935 | - if (xStart + delta < delta) |
2936 | - return False; |
2937 | - |
2938 | - if (!VG_(am_is_valid_for_client_or_free_or_resvn)( xStart, delta, |
2939 | - VKI_PROT_NONE )) |
2940 | - return False; |
2941 | - |
2942 | - AM_SANITY_CHECK; |
2943 | - sres = ML_(am_do_extend_mapping_NO_NOTIFY)( seg->start, |
2944 | - seg_old_len, |
2945 | - seg_old_len + delta ); |
2946 | - if (sr_isError(sres)) { |
2947 | - AM_SANITY_CHECK; |
2948 | - return False; |
2949 | - } else { |
2950 | - /* the area must not have moved */ |
2951 | - aspacem_assert(sr_Res(sres) == seg->start); |
2952 | - } |
2953 | - |
2954 | - *need_discard = any_Ts_in_range( seg_copy.end+1, delta ); |
2955 | - |
2956 | - seg_copy.end += delta; |
2957 | - add_segment( &seg_copy ); |
2958 | - |
2959 | - if (0) |
2960 | - VG_(am_show_nsegments)(0, "VG_(am_extend_map_client) AFTER"); |
2961 | - |
2962 | - AM_SANITY_CHECK; |
2963 | - return True; |
2964 | -} |
2965 | - |
2966 | - |
2967 | -/* Remap the old address range to the new address range. Fails if any |
2968 | - parameter is not page aligned, if the either size is zero, if any |
2969 | - wraparound is implied, if the old address range does not fall |
2970 | - entirely within a single segment, if the new address range overlaps |
2971 | - with the old one, or if the old address range is not a valid client |
2972 | - mapping. If *need_discard is True after a successful return, the |
2973 | - caller should immediately discard translations from both specified |
2974 | - address ranges. */ |
2975 | - |
2976 | -Bool VG_(am_relocate_nooverlap_client)( /*OUT*/Bool* need_discard, |
2977 | - Addr old_addr, SizeT old_len, |
2978 | - Addr new_addr, SizeT new_len ) |
2979 | -{ |
2980 | - Int iLo, iHi; |
2981 | - SysRes sres; |
2982 | - NSegment seg; |
2983 | - |
2984 | - if (old_len == 0 || new_len == 0) |
2985 | - return False; |
2986 | - |
2987 | - if (!VG_IS_PAGE_ALIGNED(old_addr) || !VG_IS_PAGE_ALIGNED(old_len) |
2988 | - || !VG_IS_PAGE_ALIGNED(new_addr) || !VG_IS_PAGE_ALIGNED(new_len)) |
2989 | - return False; |
2990 | - |
2991 | - if (old_addr + old_len < old_addr |
2992 | - || new_addr + new_len < new_addr) |
2993 | - return False; |
2994 | - |
2995 | - if (old_addr + old_len - 1 < new_addr |
2996 | - || new_addr + new_len - 1 < old_addr) { |
2997 | - /* no overlap */ |
2998 | - } else |
2999 | - return False; |
3000 | - |
3001 | - iLo = find_nsegment_idx( old_addr ); |
3002 | - iHi = find_nsegment_idx( old_addr + old_len - 1 ); |
3003 | - if (iLo != iHi) |
3004 | - return False; |
3005 | - |
3006 | - if (nsegments[iLo].kind != SkFileC && nsegments[iLo].kind != SkAnonC) |
3007 | - return False; |
3008 | - |
3009 | - sres = ML_(am_do_relocate_nooverlap_mapping_NO_NOTIFY) |
3010 | - ( old_addr, old_len, new_addr, new_len ); |
3011 | - if (sr_isError(sres)) { |
3012 | - AM_SANITY_CHECK; |
3013 | - return False; |
3014 | - } else { |
3015 | - aspacem_assert(sr_Res(sres) == new_addr); |
3016 | - } |
3017 | - |
3018 | - *need_discard = any_Ts_in_range( old_addr, old_len ) |
3019 | - || any_Ts_in_range( new_addr, new_len ); |
3020 | - |
3021 | - seg = nsegments[iLo]; |
3022 | - |
3023 | - /* Mark the new area based on the old seg. */ |
3024 | - if (seg.kind == SkFileC) { |
3025 | - seg.offset += ((ULong)old_addr) - ((ULong)seg.start); |
3026 | - } else { |
3027 | - aspacem_assert(seg.kind == SkAnonC); |
3028 | - aspacem_assert(seg.offset == 0); |
3029 | - } |
3030 | - seg.start = new_addr; |
3031 | - seg.end = new_addr + new_len - 1; |
3032 | - add_segment( &seg ); |
3033 | - |
3034 | - /* Create a free hole in the old location. */ |
3035 | - init_nsegment( &seg ); |
3036 | - seg.start = old_addr; |
3037 | - seg.end = old_addr + old_len - 1; |
3038 | - /* See comments in VG_(am_notify_munmap) about this SkResvn vs |
3039 | - SkFree thing. */ |
3040 | - if (old_addr > aspacem_maxAddr |
3041 | - && /* check previous comparison is meaningful */ |
3042 | - aspacem_maxAddr < Addr_MAX) |
3043 | - seg.kind = SkResvn; |
3044 | - else |
3045 | - seg.kind = SkFree; |
3046 | - |
3047 | - add_segment( &seg ); |
3048 | - |
3049 | - AM_SANITY_CHECK; |
3050 | - return True; |
3051 | -} |
3052 | - |
3053 | -#endif // HAVE_MREMAP |
3054 | - |
3055 | - |
3056 | -#if defined(VGO_linux) |
3057 | - |
3058 | -/*-----------------------------------------------------------------*/ |
3059 | -/*--- ---*/ |
3060 | -/*--- A simple parser for /proc/self/maps on Linux 2.4.X/2.6.X. ---*/ |
3061 | -/*--- Almost completely independent of the stuff above. The ---*/ |
3062 | -/*--- only function it 'exports' to the code above this comment ---*/ |
3063 | -/*--- is parse_procselfmaps. ---*/ |
3064 | -/*--- ---*/ |
3065 | -/*-----------------------------------------------------------------*/ |
3066 | - |
3067 | -/*------BEGIN-procmaps-parser-for-Linux--------------------------*/ |
3068 | - |
3069 | -/* Size of a smallish table used to read /proc/self/map entries. */ |
3070 | -#define M_PROCMAP_BUF 100000 |
3071 | - |
3072 | -/* static ... to keep it out of the stack frame. */ |
3073 | -static Char procmap_buf[M_PROCMAP_BUF]; |
3074 | - |
3075 | -/* Records length of /proc/self/maps read into procmap_buf. */ |
3076 | -static Int buf_n_tot; |
3077 | - |
3078 | -/* Helper fns. */ |
3079 | - |
3080 | -static Int hexdigit ( Char c ) |
3081 | -{ |
3082 | - if (c >= '0' && c <= '9') return (Int)(c - '0'); |
3083 | - if (c >= 'a' && c <= 'f') return 10 + (Int)(c - 'a'); |
3084 | - if (c >= 'A' && c <= 'F') return 10 + (Int)(c - 'A'); |
3085 | - return -1; |
3086 | -} |
3087 | - |
3088 | -static Int decdigit ( Char c ) |
3089 | -{ |
3090 | - if (c >= '0' && c <= '9') return (Int)(c - '0'); |
3091 | - return -1; |
3092 | -} |
3093 | - |
3094 | -static Int readchar ( const Char* buf, Char* ch ) |
3095 | -{ |
3096 | - if (*buf == 0) return 0; |
3097 | - *ch = *buf; |
3098 | - return 1; |
3099 | -} |
3100 | - |
3101 | -static Int readhex ( const Char* buf, UWord* val ) |
3102 | -{ |
3103 | - /* Read a word-sized hex number. */ |
3104 | - Int n = 0; |
3105 | - *val = 0; |
3106 | - while (hexdigit(*buf) >= 0) { |
3107 | - *val = (*val << 4) + hexdigit(*buf); |
3108 | - n++; buf++; |
3109 | - } |
3110 | - return n; |
3111 | -} |
3112 | - |
3113 | -static Int readhex64 ( const Char* buf, ULong* val ) |
3114 | -{ |
3115 | - /* Read a potentially 64-bit hex number. */ |
3116 | - Int n = 0; |
3117 | - *val = 0; |
3118 | - while (hexdigit(*buf) >= 0) { |
3119 | - *val = (*val << 4) + hexdigit(*buf); |
3120 | - n++; buf++; |
3121 | - } |
3122 | - return n; |
3123 | -} |
3124 | - |
3125 | -static Int readdec64 ( const Char* buf, ULong* val ) |
3126 | -{ |
3127 | - Int n = 0; |
3128 | - *val = 0; |
3129 | - while (hexdigit(*buf) >= 0) { |
3130 | - *val = (*val * 10) + decdigit(*buf); |
3131 | - n++; buf++; |
3132 | - } |
3133 | - return n; |
3134 | -} |
3135 | - |
3136 | - |
3137 | -/* Get the contents of /proc/self/maps into a static buffer. If |
3138 | - there's a syntax error, it won't fit, or other failure, just |
3139 | - abort. */ |
3140 | - |
3141 | -static void read_procselfmaps_into_buf ( void ) |
3142 | -{ |
3143 | - Int n_chunk; |
3144 | - SysRes fd; |
3145 | - |
3146 | - /* Read the initial memory mapping from the /proc filesystem. */ |
3147 | - fd = ML_(am_open)( "/proc/self/maps", VKI_O_RDONLY, 0 ); |
3148 | - if (sr_isError(fd)) |
3149 | - ML_(am_barf)("can't open /proc/self/maps"); |
3150 | - |
3151 | - buf_n_tot = 0; |
3152 | - do { |
3153 | - n_chunk = ML_(am_read)( sr_Res(fd), &procmap_buf[buf_n_tot], |
3154 | - M_PROCMAP_BUF - buf_n_tot ); |
3155 | - if (n_chunk >= 0) |
3156 | - buf_n_tot += n_chunk; |
3157 | - } while ( n_chunk > 0 && buf_n_tot < M_PROCMAP_BUF ); |
3158 | - |
3159 | - ML_(am_close)(sr_Res(fd)); |
3160 | - |
3161 | - if (buf_n_tot >= M_PROCMAP_BUF-5) |
3162 | - ML_(am_barf_toolow)("M_PROCMAP_BUF"); |
3163 | - if (buf_n_tot == 0) |
3164 | - ML_(am_barf)("I/O error on /proc/self/maps"); |
3165 | - |
3166 | - procmap_buf[buf_n_tot] = 0; |
3167 | -} |
3168 | - |
3169 | -/* Parse /proc/self/maps. For each map entry, call |
3170 | - record_mapping, passing it, in this order: |
3171 | - |
3172 | - start address in memory |
3173 | - length |
3174 | - page protections (using the VKI_PROT_* flags) |
3175 | - mapped file device and inode |
3176 | - offset in file, or zero if no file |
3177 | - filename, zero terminated, or NULL if no file |
3178 | - |
3179 | - So the sig of the called fn might be |
3180 | - |
3181 | - void (*record_mapping)( Addr start, SizeT size, UInt prot, |
3182 | - UInt dev, UInt info, |
3183 | - ULong foffset, UChar* filename ) |
3184 | - |
3185 | - Note that the supplied filename is transiently stored; record_mapping |
3186 | - should make a copy if it wants to keep it. |
3187 | - |
3188 | - Nb: it is important that this function does not alter the contents of |
3189 | - procmap_buf! |
3190 | -*/ |
3191 | -static void parse_procselfmaps ( |
3192 | - void (*record_mapping)( Addr addr, SizeT len, UInt prot, |
3193 | - ULong dev, ULong ino, Off64T offset, |
3194 | - const UChar* filename ), |
3195 | - void (*record_gap)( Addr addr, SizeT len ) |
3196 | - ) |
3197 | -{ |
3198 | - Int i, j, i_eol; |
3199 | - Addr start, endPlusOne, gapStart; |
3200 | - UChar* filename; |
3201 | - UChar rr, ww, xx, pp, ch, tmp; |
3202 | - UInt prot; |
3203 | - UWord maj, min; |
3204 | - ULong foffset, dev, ino; |
3205 | - |
3206 | - foffset = ino = 0; /* keep gcc-4.1.0 happy */ |
3207 | - |
3208 | - read_procselfmaps_into_buf(); |
3209 | - |
3210 | - aspacem_assert('\0' != procmap_buf[0] && 0 != buf_n_tot); |
3211 | - |
3212 | - if (0) |
3213 | - VG_(debugLog)(0, "procselfmaps", "raw:\n%s\n", procmap_buf); |
3214 | - |
3215 | - /* Ok, it's safely aboard. Parse the entries. */ |
3216 | - i = 0; |
3217 | - gapStart = Addr_MIN; |
3218 | - while (True) { |
3219 | - if (i >= buf_n_tot) break; |
3220 | - |
3221 | - /* Read (without fscanf :) the pattern %16x-%16x %c%c%c%c %16x %2x:%2x %d */ |
3222 | - j = readhex(&procmap_buf[i], &start); |
3223 | - if (j > 0) i += j; else goto syntaxerror; |
3224 | - j = readchar(&procmap_buf[i], &ch); |
3225 | - if (j == 1 && ch == '-') i += j; else goto syntaxerror; |
3226 | - j = readhex(&procmap_buf[i], &endPlusOne); |
3227 | - if (j > 0) i += j; else goto syntaxerror; |
3228 | - |
3229 | - j = readchar(&procmap_buf[i], &ch); |
3230 | - if (j == 1 && ch == ' ') i += j; else goto syntaxerror; |
3231 | - |
3232 | - j = readchar(&procmap_buf[i], &rr); |
3233 | - if (j == 1 && (rr == 'r' || rr == '-')) i += j; else goto syntaxerror; |
3234 | - j = readchar(&procmap_buf[i], &ww); |
3235 | - if (j == 1 && (ww == 'w' || ww == '-')) i += j; else goto syntaxerror; |
3236 | - j = readchar(&procmap_buf[i], &xx); |
3237 | - if (j == 1 && (xx == 'x' || xx == '-')) i += j; else goto syntaxerror; |
3238 | - /* This field is the shared/private flag */ |
3239 | - j = readchar(&procmap_buf[i], &pp); |
3240 | - if (j == 1 && (pp == 'p' || pp == '-' || pp == 's')) |
3241 | - i += j; else goto syntaxerror; |
3242 | - |
3243 | - j = readchar(&procmap_buf[i], &ch); |
3244 | - if (j == 1 && ch == ' ') i += j; else goto syntaxerror; |
3245 | - |
3246 | - j = readhex64(&procmap_buf[i], &foffset); |
3247 | - if (j > 0) i += j; else goto syntaxerror; |
3248 | - |
3249 | - j = readchar(&procmap_buf[i], &ch); |
3250 | - if (j == 1 && ch == ' ') i += j; else goto syntaxerror; |
3251 | - |
3252 | - j = readhex(&procmap_buf[i], &maj); |
3253 | - if (j > 0) i += j; else goto syntaxerror; |
3254 | - j = readchar(&procmap_buf[i], &ch); |
3255 | - if (j == 1 && ch == ':') i += j; else goto syntaxerror; |
3256 | - j = readhex(&procmap_buf[i], &min); |
3257 | - if (j > 0) i += j; else goto syntaxerror; |
3258 | - |
3259 | - j = readchar(&procmap_buf[i], &ch); |
3260 | - if (j == 1 && ch == ' ') i += j; else goto syntaxerror; |
3261 | - |
3262 | - j = readdec64(&procmap_buf[i], &ino); |
3263 | - if (j > 0) i += j; else goto syntaxerror; |
3264 | - |
3265 | - goto read_line_ok; |
3266 | - |
3267 | - syntaxerror: |
3268 | - VG_(debugLog)(0, "Valgrind:", |
3269 | - "FATAL: syntax error reading /proc/self/maps\n"); |
3270 | - { Int k, m; |
3271 | - HChar buf50[51]; |
3272 | - m = 0; |
3273 | - buf50[m] = 0; |
3274 | - k = i - 50; |
3275 | - if (k < 0) k = 0; |
3276 | - for (; k <= i; k++) { |
3277 | - buf50[m] = procmap_buf[k]; |
3278 | - buf50[m+1] = 0; |
3279 | - if (m < 50-1) m++; |
3280 | - } |
3281 | - VG_(debugLog)(0, "procselfmaps", "Last 50 chars: '%s'\n", buf50); |
3282 | - } |
3283 | - ML_(am_exit)(1); |
3284 | - |
3285 | - read_line_ok: |
3286 | - |
3287 | - /* Try and find the name of the file mapped to this segment, if |
3288 | - it exists. Note that files can contains spaces. */ |
3289 | - |
3290 | - // Move i to the next non-space char, which should be either a '/' or |
3291 | - // a newline. |
3292 | - while (procmap_buf[i] == ' ' && i < buf_n_tot-1) i++; |
3293 | - |
3294 | - // Move i_eol to the end of the line. |
3295 | - i_eol = i; |
3296 | - while (procmap_buf[i_eol] != '\n' && i_eol < buf_n_tot-1) i_eol++; |
3297 | - |
3298 | - // If there's a filename... |
3299 | - if (i < i_eol-1 && procmap_buf[i] == '/') { |
3300 | - /* Minor hack: put a '\0' at the filename end for the call to |
3301 | - 'record_mapping', then restore the old char with 'tmp'. */ |
3302 | - filename = &procmap_buf[i]; |
3303 | - tmp = filename[i_eol - i]; |
3304 | - filename[i_eol - i] = '\0'; |
3305 | - } else { |
3306 | - tmp = 0; |
3307 | - filename = NULL; |
3308 | - foffset = 0; |
3309 | - } |
3310 | - |
3311 | - prot = 0; |
3312 | - if (rr == 'r') prot |= VKI_PROT_READ; |
3313 | - if (ww == 'w') prot |= VKI_PROT_WRITE; |
3314 | - if (xx == 'x') prot |= VKI_PROT_EXEC; |
3315 | - |
3316 | - /* Linux has two ways to encode a device number when it |
3317 | - is exposed to user space (via fstat etc). The old way |
3318 | - is the traditional unix scheme that produces a 16 bit |
3319 | - device number with the top 8 being the major number and |
3320 | - the bottom 8 the minor number. |
3321 | - |
3322 | - The new scheme allows for a 12 bit major number and |
3323 | - a 20 bit minor number by using a 32 bit device number |
3324 | - and putting the top 12 bits of the minor number into |
3325 | - the top 12 bits of the device number thus leaving an |
3326 | - extra 4 bits for the major number. |
3327 | - |
3328 | - If the minor and major number are both single byte |
3329 | - values then both schemes give the same result so we |
3330 | - use the new scheme here in case either number is |
3331 | - outside the 0-255 range and then use fstat64 when |
3332 | - available (or fstat on 64 bit systems) so that we |
3333 | - should always have a new style device number and |
3334 | - everything should match. */ |
3335 | - dev = (min & 0xff) | (maj << 8) | ((min & ~0xff) << 12); |
3336 | - |
3337 | - if (record_gap && gapStart < start) |
3338 | - (*record_gap) ( gapStart, start-gapStart ); |
3339 | - |
3340 | - if (record_mapping && start < endPlusOne) |
3341 | - (*record_mapping) ( start, endPlusOne-start, |
3342 | - prot, dev, ino, |
3343 | - foffset, filename ); |
3344 | - |
3345 | - if ('\0' != tmp) { |
3346 | - filename[i_eol - i] = tmp; |
3347 | - } |
3348 | - |
3349 | - i = i_eol + 1; |
3350 | - gapStart = endPlusOne; |
3351 | - } |
3352 | - |
3353 | -# if defined(VGP_arm_linux) |
3354 | - /* ARM puts code at the end of memory that contains processor |
3355 | - specific stuff (cmpxchg, getting the thread local storage, etc.) |
3356 | - This isn't specified in /proc/self/maps, so do it here. This |
3357 | - kludgery causes the view of memory, as presented to |
3358 | - record_gap/record_mapping, to actually reflect reality. IMO |
3359 | - (JRS, 2010-Jan-03) the fact that /proc/.../maps does not list |
3360 | - the commpage should be regarded as a bug in the kernel. */ |
3361 | - { const Addr commpage_start = ARM_LINUX_FAKE_COMMPAGE_START; |
3362 | - const Addr commpage_end1 = ARM_LINUX_FAKE_COMMPAGE_END1; |
3363 | - if (gapStart < commpage_start) { |
3364 | - if (record_gap) |
3365 | - (*record_gap)( gapStart, commpage_start - gapStart ); |
3366 | - if (record_mapping) |
3367 | - (*record_mapping)( commpage_start, commpage_end1 - commpage_start, |
3368 | - VKI_PROT_READ|VKI_PROT_EXEC, |
3369 | - 0/*dev*/, 0/*ino*/, 0/*foffset*/, |
3370 | - NULL); |
3371 | - gapStart = commpage_end1; |
3372 | - } |
3373 | - } |
3374 | -# endif |
3375 | - |
3376 | - if (record_gap && gapStart < Addr_MAX) |
3377 | - (*record_gap) ( gapStart, Addr_MAX - gapStart + 1 ); |
3378 | -} |
3379 | - |
3380 | -/*------END-procmaps-parser-for-Linux----------------------------*/ |
3381 | - |
3382 | -/*------BEGIN-procmaps-parser-for-Darwin-------------------------*/ |
3383 | - |
3384 | -#elif defined(VGO_darwin) |
3385 | -#include <mach/mach.h> |
3386 | -#include <mach/mach_vm.h> |
3387 | - |
3388 | -static unsigned int mach2vki(unsigned int vm_prot) |
3389 | -{ |
3390 | - return |
3391 | - ((vm_prot & VM_PROT_READ) ? VKI_PROT_READ : 0) | |
3392 | - ((vm_prot & VM_PROT_WRITE) ? VKI_PROT_WRITE : 0) | |
3393 | - ((vm_prot & VM_PROT_EXECUTE) ? VKI_PROT_EXEC : 0) ; |
3394 | -} |
3395 | - |
3396 | -static UInt stats_machcalls = 0; |
3397 | - |
3398 | -static void parse_procselfmaps ( |
3399 | - void (*record_mapping)( Addr addr, SizeT len, UInt prot, |
3400 | - ULong dev, ULong ino, Off64T offset, |
3401 | - const UChar* filename ), |
3402 | - void (*record_gap)( Addr addr, SizeT len ) |
3403 | - ) |
3404 | -{ |
3405 | - vm_address_t iter; |
3406 | - unsigned int depth; |
3407 | - vm_address_t last; |
3408 | - |
3409 | - iter = 0; |
3410 | - depth = 0; |
3411 | - last = 0; |
3412 | - while (1) { |
3413 | - mach_vm_address_t addr = iter; |
3414 | - mach_vm_size_t size; |
3415 | - vm_region_submap_short_info_data_64_t info; |
3416 | - kern_return_t kr; |
3417 | - |
3418 | - while (1) { |
3419 | - mach_msg_type_number_t info_count |
3420 | - = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64; |
3421 | - stats_machcalls++; |
3422 | - kr = mach_vm_region_recurse(mach_task_self(), &addr, &size, &depth, |
3423 | - (vm_region_info_t)&info, &info_count); |
3424 | - if (kr) |
3425 | - return; |
3426 | - if (info.is_submap) { |
3427 | - depth++; |
3428 | - continue; |
3429 | - } |
3430 | - break; |
3431 | - } |
3432 | - iter = addr + size; |
3433 | - |
3434 | - if (addr > last && record_gap) { |
3435 | - (*record_gap)(last, addr - last); |
3436 | - } |
3437 | - if (record_mapping) { |
3438 | - (*record_mapping)(addr, size, mach2vki(info.protection), |
3439 | - 0, 0, info.offset, NULL); |
3440 | - } |
3441 | - last = addr + size; |
3442 | - } |
3443 | - |
3444 | - if ((Addr)-1 > last && record_gap) |
3445 | - (*record_gap)(last, (Addr)-1 - last); |
3446 | -} |
3447 | - |
3448 | -// Urr. So much for thread safety. |
3449 | -static Bool css_overflowed; |
3450 | -static ChangedSeg* css_local; |
3451 | -static Int css_size_local; |
3452 | -static Int css_used_local; |
3453 | - |
3454 | -static void add_mapping_callback(Addr addr, SizeT len, UInt prot, |
3455 | - ULong dev, ULong ino, Off64T offset, |
3456 | - const UChar *filename) |
3457 | -{ |
3458 | - // derived from sync_check_mapping_callback() |
3459 | - |
3460 | - Int iLo, iHi, i; |
3461 | - |
3462 | - if (len == 0) return; |
3463 | - |
3464 | - /* The kernel should not give us wraparounds. */ |
3465 | - aspacem_assert(addr <= addr + len - 1); |
3466 | - |
3467 | - iLo = find_nsegment_idx( addr ); |
3468 | - iHi = find_nsegment_idx( addr + len - 1 ); |
3469 | - |
3470 | - |
3471 | - /* NSegments iLo .. iHi inclusive should agree with the presented |
3472 | - data. */ |
3473 | - for (i = iLo; i <= iHi; i++) { |
3474 | - |
3475 | - UInt seg_prot; |
3476 | - |
3477 | - if (nsegments[i].kind == SkAnonV || nsegments[i].kind == SkFileV) { |
3478 | - /* Ignore V regions */ |
3479 | - continue; |
3480 | - } |
3481 | - else if (nsegments[i].kind == SkFree || nsegments[i].kind == SkResvn) { |
3482 | - /* Add mapping for SkResvn regions */ |
3483 | - ChangedSeg* cs = &css_local[css_used_local]; |
3484 | - if (css_used_local < css_size_local) { |
3485 | - cs->is_added = True; |
3486 | - cs->start = addr; |
3487 | - cs->end = addr + len - 1; |
3488 | - cs->prot = prot; |
3489 | - cs->offset = offset; |
3490 | - css_used_local++; |
3491 | - } else { |
3492 | - css_overflowed = True; |
3493 | - } |
3494 | - return; |
3495 | - |
3496 | - } else if (nsegments[i].kind == SkAnonC || |
3497 | - nsegments[i].kind == SkFileC || |
3498 | - nsegments[i].kind == SkShmC) |
3499 | - { |
3500 | - /* Check permissions on client regions */ |
3501 | - // GrP fixme |
3502 | - seg_prot = 0; |
3503 | - if (nsegments[i].hasR) seg_prot |= VKI_PROT_READ; |
3504 | - if (nsegments[i].hasW) seg_prot |= VKI_PROT_WRITE; |
3505 | -# if defined(VGA_x86) |
3506 | - // GrP fixme sloppyXcheck |
3507 | - // darwin: kernel X ignored and spuriously changes? (vm_copy) |
3508 | - seg_prot |= (prot & VKI_PROT_EXEC); |
3509 | -# else |
3510 | - if (nsegments[i].hasX) seg_prot |= VKI_PROT_EXEC; |
3511 | -# endif |
3512 | - if (seg_prot != prot) { |
3513 | - if (VG_(clo_trace_syscalls)) |
3514 | - VG_(debugLog)(0,"aspacem","region %p..%p permission " |
3515 | - "mismatch (kernel %x, V %x)\n", |
3516 | - (void*)nsegments[i].start, |
3517 | - (void*)(nsegments[i].end+1), prot, seg_prot); |
3518 | - } |
3519 | - |
3520 | - } else { |
3521 | - aspacem_assert(0); |
3522 | - } |
3523 | - } |
3524 | -} |
3525 | - |
3526 | -static void remove_mapping_callback(Addr addr, SizeT len) |
3527 | -{ |
3528 | - // derived from sync_check_gap_callback() |
3529 | - |
3530 | - Int iLo, iHi, i; |
3531 | - |
3532 | - if (len == 0) |
3533 | - return; |
3534 | - |
3535 | - /* The kernel should not give us wraparounds. */ |
3536 | - aspacem_assert(addr <= addr + len - 1); |
3537 | - |
3538 | - iLo = find_nsegment_idx( addr ); |
3539 | - iHi = find_nsegment_idx( addr + len - 1 ); |
3540 | - |
3541 | - /* NSegments iLo .. iHi inclusive should agree with the presented data. */ |
3542 | - for (i = iLo; i <= iHi; i++) { |
3543 | - if (nsegments[i].kind != SkFree && nsegments[i].kind != SkResvn) { |
3544 | - // V has a mapping, kernel doesn't |
3545 | - ChangedSeg* cs = &css_local[css_used_local]; |
3546 | - if (css_used_local < css_size_local) { |
3547 | - cs->is_added = False; |
3548 | - cs->start = nsegments[i].start; |
3549 | - cs->end = nsegments[i].end; |
3550 | - cs->prot = 0; |
3551 | - cs->offset = 0; |
3552 | - css_used_local++; |
3553 | - } else { |
3554 | - css_overflowed = True; |
3555 | - } |
3556 | - return; |
3557 | - } |
3558 | - } |
3559 | -} |
3560 | - |
3561 | - |
3562 | -// Returns False if 'css' wasn't big enough. |
3563 | -Bool VG_(get_changed_segments)( |
3564 | - const HChar* when, const HChar* where, /*OUT*/ChangedSeg* css, |
3565 | - Int css_size, /*OUT*/Int* css_used) |
3566 | -{ |
3567 | - static UInt stats_synccalls = 1; |
3568 | - aspacem_assert(when && where); |
3569 | - |
3570 | - if (0) |
3571 | - VG_(debugLog)(0,"aspacem", |
3572 | - "[%u,%u] VG_(get_changed_segments)(%s, %s)\n", |
3573 | - stats_synccalls++, stats_machcalls, when, where |
3574 | - ); |
3575 | - |
3576 | - css_overflowed = False; |
3577 | - css_local = css; |
3578 | - css_size_local = css_size; |
3579 | - css_used_local = 0; |
3580 | - |
3581 | - // Get the list of segs that need to be added/removed. |
3582 | - parse_procselfmaps(&add_mapping_callback, &remove_mapping_callback); |
3583 | - |
3584 | - *css_used = css_used_local; |
3585 | - |
3586 | - if (css_overflowed) { |
3587 | - aspacem_assert(css_used_local == css_size_local); |
3588 | - } |
3589 | - |
3590 | - return !css_overflowed; |
3591 | -} |
3592 | - |
3593 | -#endif // defined(VGO_darwin) |
3594 | - |
3595 | -/*------END-procmaps-parser-for-Darwin---------------------------*/ |
3596 | - |
3597 | -#endif // defined(VGO_linux) || defined(VGO_darwin) |
3598 | - |
3599 | -/*--------------------------------------------------------------------*/ |
3600 | -/*--- end ---*/ |
3601 | -/*--------------------------------------------------------------------*/ |
3602 | |
3603 | === removed directory '.pc/0002-version.patch' |
3604 | === removed file '.pc/0002-version.patch/configure' |
3605 | --- .pc/0002-version.patch/configure 2012-01-06 19:01:30 +0000 |
3606 | +++ .pc/0002-version.patch/configure 1970-01-01 00:00:00 +0000 |
3607 | @@ -1,10742 +0,0 @@ |
3608 | -#! /bin/sh |
3609 | -# Guess values for system-dependent variables and create Makefiles. |
3610 | -# Generated by GNU Autoconf 2.65 for Valgrind 3.7.0. |
3611 | -# |
3612 | -# Report bugs to <valgrind-users@lists.sourceforge.net>. |
3613 | -# |
3614 | -# |
3615 | -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, |
3616 | -# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, |
3617 | -# Inc. |
3618 | -# |
3619 | -# |
3620 | -# This configure script is free software; the Free Software Foundation |
3621 | -# gives unlimited permission to copy, distribute and modify it. |
3622 | -## -------------------- ## |
3623 | -## M4sh Initialization. ## |
3624 | -## -------------------- ## |
3625 | - |
3626 | -# Be more Bourne compatible |
3627 | -DUALCASE=1; export DUALCASE # for MKS sh |
3628 | -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : |
3629 | - emulate sh |
3630 | - NULLCMD=: |
3631 | - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which |
3632 | - # is contrary to our usage. Disable this feature. |
3633 | - alias -g '${1+"$@"}'='"$@"' |
3634 | - setopt NO_GLOB_SUBST |
3635 | -else |
3636 | - case `(set -o) 2>/dev/null` in #( |
3637 | - *posix*) : |
3638 | - set -o posix ;; #( |
3639 | - *) : |
3640 | - ;; |
3641 | -esac |
3642 | -fi |
3643 | - |
3644 | - |
3645 | -as_nl=' |
3646 | -' |
3647 | -export as_nl |
3648 | -# Printing a long string crashes Solaris 7 /usr/bin/printf. |
3649 | -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' |
3650 | -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo |
3651 | -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo |
3652 | -# Prefer a ksh shell builtin over an external printf program on Solaris, |
3653 | -# but without wasting forks for bash or zsh. |
3654 | -if test -z "$BASH_VERSION$ZSH_VERSION" \ |
3655 | - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then |
3656 | - as_echo='print -r --' |
3657 | - as_echo_n='print -rn --' |
3658 | -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then |
3659 | - as_echo='printf %s\n' |
3660 | - as_echo_n='printf %s' |
3661 | -else |
3662 | - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then |
3663 | - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' |
3664 | - as_echo_n='/usr/ucb/echo -n' |
3665 | - else |
3666 | - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' |
3667 | - as_echo_n_body='eval |
3668 | - arg=$1; |
3669 | - case $arg in #( |
3670 | - *"$as_nl"*) |
3671 | - expr "X$arg" : "X\\(.*\\)$as_nl"; |
3672 | - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; |
3673 | - esac; |
3674 | - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" |
3675 | - ' |
3676 | - export as_echo_n_body |
3677 | - as_echo_n='sh -c $as_echo_n_body as_echo' |
3678 | - fi |
3679 | - export as_echo_body |
3680 | - as_echo='sh -c $as_echo_body as_echo' |
3681 | -fi |
3682 | - |
3683 | -# The user is always right. |
3684 | -if test "${PATH_SEPARATOR+set}" != set; then |
3685 | - PATH_SEPARATOR=: |
3686 | - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { |
3687 | - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || |
3688 | - PATH_SEPARATOR=';' |
3689 | - } |
3690 | -fi |
3691 | - |
3692 | - |
3693 | -# IFS |
3694 | -# We need space, tab and new line, in precisely that order. Quoting is |
3695 | -# there to prevent editors from complaining about space-tab. |
3696 | -# (If _AS_PATH_WALK were called with IFS unset, it would disable word |
3697 | -# splitting by setting IFS to empty value.) |
3698 | -IFS=" "" $as_nl" |
3699 | - |
3700 | -# Find who we are. Look in the path if we contain no directory separator. |
3701 | -case $0 in #(( |
3702 | - *[\\/]* ) as_myself=$0 ;; |
3703 | - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR |
3704 | -for as_dir in $PATH |
3705 | -do |
3706 | - IFS=$as_save_IFS |
3707 | - test -z "$as_dir" && as_dir=. |
3708 | - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break |
3709 | - done |
3710 | -IFS=$as_save_IFS |
3711 | - |
3712 | - ;; |
3713 | -esac |
3714 | -# We did not find ourselves, most probably we were run as `sh COMMAND' |
3715 | -# in which case we are not to be found in the path. |
3716 | -if test "x$as_myself" = x; then |
3717 | - as_myself=$0 |
3718 | -fi |
3719 | -if test ! -f "$as_myself"; then |
3720 | - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 |
3721 | - exit 1 |
3722 | -fi |
3723 | - |
3724 | -# Unset variables that we do not need and which cause bugs (e.g. in |
3725 | -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" |
3726 | -# suppresses any "Segmentation fault" message there. '((' could |
3727 | -# trigger a bug in pdksh 5.2.14. |
3728 | -for as_var in BASH_ENV ENV MAIL MAILPATH |
3729 | -do eval test x\${$as_var+set} = xset \ |
3730 | - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : |
3731 | -done |
3732 | -PS1='$ ' |
3733 | -PS2='> ' |
3734 | -PS4='+ ' |
3735 | - |
3736 | -# NLS nuisances. |
3737 | -LC_ALL=C |
3738 | -export LC_ALL |
3739 | -LANGUAGE=C |
3740 | -export LANGUAGE |
3741 | - |
3742 | -# CDPATH. |
3743 | -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH |
3744 | - |
3745 | -if test "x$CONFIG_SHELL" = x; then |
3746 | - as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : |
3747 | - emulate sh |
3748 | - NULLCMD=: |
3749 | - # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which |
3750 | - # is contrary to our usage. Disable this feature. |
3751 | - alias -g '\${1+\"\$@\"}'='\"\$@\"' |
3752 | - setopt NO_GLOB_SUBST |
3753 | -else |
3754 | - case \`(set -o) 2>/dev/null\` in #( |
3755 | - *posix*) : |
3756 | - set -o posix ;; #( |
3757 | - *) : |
3758 | - ;; |
3759 | -esac |
3760 | -fi |
3761 | -" |
3762 | - as_required="as_fn_return () { (exit \$1); } |
3763 | -as_fn_success () { as_fn_return 0; } |
3764 | -as_fn_failure () { as_fn_return 1; } |
3765 | -as_fn_ret_success () { return 0; } |
3766 | -as_fn_ret_failure () { return 1; } |
3767 | - |
3768 | -exitcode=0 |
3769 | -as_fn_success || { exitcode=1; echo as_fn_success failed.; } |
3770 | -as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } |
3771 | -as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } |
3772 | -as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } |
3773 | -if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : |
3774 | - |
3775 | -else |
3776 | - exitcode=1; echo positional parameters were not saved. |
3777 | -fi |
3778 | -test x\$exitcode = x0 || exit 1" |
3779 | - as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO |
3780 | - as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO |
3781 | - eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && |
3782 | - test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 |
3783 | -test \$(( 1 + 1 )) = 2 || exit 1" |
3784 | - if (eval "$as_required") 2>/dev/null; then : |
3785 | - as_have_required=yes |
3786 | -else |
3787 | - as_have_required=no |
3788 | -fi |
3789 | - if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : |
3790 | - |
3791 | -else |
3792 | - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR |
3793 | -as_found=false |
3794 | -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH |
3795 | -do |
3796 | - IFS=$as_save_IFS |
3797 | - test -z "$as_dir" && as_dir=. |
3798 | - as_found=: |
3799 | - case $as_dir in #( |
3800 | - /*) |
3801 | - for as_base in sh bash ksh sh5; do |
3802 | - # Try only shells that exist, to save several forks. |
3803 | - as_shell=$as_dir/$as_base |
3804 | - if { test -f "$as_shell" || test -f "$as_shell.exe"; } && |
3805 | - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : |
3806 | - CONFIG_SHELL=$as_shell as_have_required=yes |
3807 | - if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : |
3808 | - break 2 |
3809 | -fi |
3810 | -fi |
3811 | - done;; |
3812 | - esac |
3813 | - as_found=false |
3814 | -done |
3815 | -$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && |
3816 | - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : |
3817 | - CONFIG_SHELL=$SHELL as_have_required=yes |
3818 | -fi; } |
3819 | -IFS=$as_save_IFS |
3820 | - |
3821 | - |
3822 | - if test "x$CONFIG_SHELL" != x; then : |
3823 | - # We cannot yet assume a decent shell, so we have to provide a |
3824 | - # neutralization value for shells without unset; and this also |
3825 | - # works around shells that cannot unset nonexistent variables. |
3826 | - BASH_ENV=/dev/null |
3827 | - ENV=/dev/null |
3828 | - (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV |
3829 | - export CONFIG_SHELL |
3830 | - exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} |
3831 | -fi |
3832 | - |
3833 | - if test x$as_have_required = xno; then : |
3834 | - $as_echo "$0: This script requires a shell more modern than all" |
3835 | - $as_echo "$0: the shells that I found on your system." |
3836 | - if test x${ZSH_VERSION+set} = xset ; then |
3837 | - $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" |
3838 | - $as_echo "$0: be upgraded to zsh 4.3.4 or later." |
3839 | - else |
3840 | - $as_echo "$0: Please tell bug-autoconf@gnu.org and |
3841 | -$0: valgrind-users@lists.sourceforge.net about your system, |
3842 | -$0: including any error possibly output before this |
3843 | -$0: message. Then install a modern shell, or manually run |
3844 | -$0: the script under such a shell if you do have one." |
3845 | - fi |
3846 | - exit 1 |
3847 | -fi |
3848 | -fi |
3849 | -fi |
3850 | -SHELL=${CONFIG_SHELL-/bin/sh} |
3851 | -export SHELL |
3852 | -# Unset more variables known to interfere with behavior of common tools. |
3853 | -CLICOLOR_FORCE= GREP_OPTIONS= |
3854 | -unset CLICOLOR_FORCE GREP_OPTIONS |
3855 | - |
3856 | -## --------------------- ## |
3857 | -## M4sh Shell Functions. ## |
3858 | -## --------------------- ## |
3859 | -# as_fn_unset VAR |
3860 | -# --------------- |
3861 | -# Portably unset VAR. |
3862 | -as_fn_unset () |
3863 | -{ |
3864 | - { eval $1=; unset $1;} |
3865 | -} |
3866 | -as_unset=as_fn_unset |
3867 | - |
3868 | -# as_fn_set_status STATUS |
3869 | -# ----------------------- |
3870 | -# Set $? to STATUS, without forking. |
3871 | -as_fn_set_status () |
3872 | -{ |
3873 | - return $1 |
3874 | -} # as_fn_set_status |
3875 | - |
3876 | -# as_fn_exit STATUS |
3877 | -# ----------------- |
3878 | -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. |
3879 | -as_fn_exit () |
3880 | -{ |
3881 | - set +e |
3882 | - as_fn_set_status $1 |
3883 | - exit $1 |
3884 | -} # as_fn_exit |
3885 | - |
3886 | -# as_fn_mkdir_p |
3887 | -# ------------- |
3888 | -# Create "$as_dir" as a directory, including parents if necessary. |
3889 | -as_fn_mkdir_p () |
3890 | -{ |
3891 | - |
3892 | - case $as_dir in #( |
3893 | - -*) as_dir=./$as_dir;; |
3894 | - esac |
3895 | - test -d "$as_dir" || eval $as_mkdir_p || { |
3896 | - as_dirs= |
3897 | - while :; do |
3898 | - case $as_dir in #( |
3899 | - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( |
3900 | - *) as_qdir=$as_dir;; |
3901 | - esac |
3902 | - as_dirs="'$as_qdir' $as_dirs" |
3903 | - as_dir=`$as_dirname -- "$as_dir" || |
3904 | -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ |
3905 | - X"$as_dir" : 'X\(//\)[^/]' \| \ |
3906 | - X"$as_dir" : 'X\(//\)$' \| \ |
3907 | - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || |
3908 | -$as_echo X"$as_dir" | |
3909 | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ |
3910 | - s//\1/ |
3911 | - q |
3912 | - } |
3913 | - /^X\(\/\/\)[^/].*/{ |
3914 | - s//\1/ |
3915 | - q |
3916 | - } |
3917 | - /^X\(\/\/\)$/{ |
3918 | - s//\1/ |
3919 | - q |
3920 | - } |
3921 | - /^X\(\/\).*/{ |
3922 | - s//\1/ |
3923 | - q |
3924 | - } |
3925 | - s/.*/./; q'` |
3926 | - test -d "$as_dir" && break |
3927 | - done |
3928 | - test -z "$as_dirs" || eval "mkdir $as_dirs" |
3929 | - } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir" |
3930 | - |
3931 | - |
3932 | -} # as_fn_mkdir_p |
3933 | -# as_fn_append VAR VALUE |
3934 | -# ---------------------- |
3935 | -# Append the text in VALUE to the end of the definition contained in VAR. Take |
3936 | -# advantage of any shell optimizations that allow amortized linear growth over |
3937 | -# repeated appends, instead of the typical quadratic growth present in naive |
3938 | -# implementations. |
3939 | -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : |
3940 | - eval 'as_fn_append () |
3941 | - { |
3942 | - eval $1+=\$2 |
3943 | - }' |
3944 | -else |
3945 | - as_fn_append () |
3946 | - { |
3947 | - eval $1=\$$1\$2 |
3948 | - } |
3949 | -fi # as_fn_append |
3950 | - |
3951 | -# as_fn_arith ARG... |
3952 | -# ------------------ |
3953 | -# Perform arithmetic evaluation on the ARGs, and store the result in the |
3954 | -# global $as_val. Take advantage of shells that can avoid forks. The arguments |
3955 | -# must be portable across $(()) and expr. |
3956 | -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : |
3957 | - eval 'as_fn_arith () |
3958 | - { |
3959 | - as_val=$(( $* )) |
3960 | - }' |
3961 | -else |
3962 | - as_fn_arith () |
3963 | - { |
3964 | - as_val=`expr "$@" || test $? -eq 1` |
3965 | - } |
3966 | -fi # as_fn_arith |
3967 | - |
3968 | - |
3969 | -# as_fn_error ERROR [LINENO LOG_FD] |
3970 | -# --------------------------------- |
3971 | -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are |
3972 | -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the |
3973 | -# script with status $?, using 1 if that was 0. |
3974 | -as_fn_error () |
3975 | -{ |
3976 | - as_status=$?; test $as_status -eq 0 && as_status=1 |
3977 | - if test "$3"; then |
3978 | - as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack |
3979 | - $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3 |
3980 | - fi |
3981 | - $as_echo "$as_me: error: $1" >&2 |
3982 | - as_fn_exit $as_status |
3983 | -} # as_fn_error |
3984 | - |
3985 | -if expr a : '\(a\)' >/dev/null 2>&1 && |
3986 | - test "X`expr 00001 : '.*\(...\)'`" = X001; then |
3987 | - as_expr=expr |
3988 | -else |
3989 | - as_expr=false |
3990 | -fi |
3991 | - |
3992 | -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then |
3993 | - as_basename=basename |
3994 | -else |
3995 | - as_basename=false |
3996 | -fi |
3997 | - |
3998 | -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then |
3999 | - as_dirname=dirname |
4000 | -else |
4001 | - as_dirname=false |
4002 | -fi |
4003 | - |
4004 | -as_me=`$as_basename -- "$0" || |
4005 | -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ |
4006 | - X"$0" : 'X\(//\)$' \| \ |
4007 | - X"$0" : 'X\(/\)' \| . 2>/dev/null || |
4008 | -$as_echo X/"$0" | |
4009 | - sed '/^.*\/\([^/][^/]*\)\/*$/{ |
4010 | - s//\1/ |
4011 | - q |
4012 | - } |
4013 | - /^X\/\(\/\/\)$/{ |
4014 | - s//\1/ |
4015 | - q |
4016 | - } |
4017 | - /^X\/\(\/\).*/{ |
4018 | - s//\1/ |
4019 | - q |
4020 | - } |
4021 | - s/.*/./; q'` |
4022 | - |
4023 | -# Avoid depending upon Character Ranges. |
4024 | -as_cr_letters='abcdefghijklmnopqrstuvwxyz' |
4025 | -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
4026 | -as_cr_Letters=$as_cr_letters$as_cr_LETTERS |
4027 | -as_cr_digits='0123456789' |
4028 | -as_cr_alnum=$as_cr_Letters$as_cr_digits |
4029 | - |
4030 | - |
4031 | - as_lineno_1=$LINENO as_lineno_1a=$LINENO |
4032 | - as_lineno_2=$LINENO as_lineno_2a=$LINENO |
4033 | - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && |
4034 | - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { |
4035 | - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) |
4036 | - sed -n ' |
4037 | - p |
4038 | - /[$]LINENO/= |
4039 | - ' <$as_myself | |
4040 | - sed ' |
4041 | - s/[$]LINENO.*/&-/ |
4042 | - t lineno |
4043 | - b |
4044 | - :lineno |
4045 | - N |
4046 | - :loop |
4047 | - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ |
4048 | - t loop |
4049 | - s/-\n.*// |
4050 | - ' >$as_me.lineno && |
4051 | - chmod +x "$as_me.lineno" || |
4052 | - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } |
4053 | - |
4054 | - # Don't try to exec as it changes $[0], causing all sort of problems |
4055 | - # (the dirname of $[0] is not the place where we might find the |
4056 | - # original and so on. Autoconf is especially sensitive to this). |
4057 | - . "./$as_me.lineno" |
4058 | - # Exit status is that of the last command. |
4059 | - exit |
4060 | -} |
4061 | - |
4062 | -ECHO_C= ECHO_N= ECHO_T= |
4063 | -case `echo -n x` in #((((( |
4064 | --n*) |
4065 | - case `echo 'xy\c'` in |
4066 | - *c*) ECHO_T=' ';; # ECHO_T is single tab character. |
4067 | - xy) ECHO_C='\c';; |
4068 | - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null |
4069 | - ECHO_T=' ';; |
4070 | - esac;; |
4071 | -*) |
4072 | - ECHO_N='-n';; |
4073 | -esac |
4074 | - |
4075 | -rm -f conf$$ conf$$.exe conf$$.file |
4076 | -if test -d conf$$.dir; then |
4077 | - rm -f conf$$.dir/conf$$.file |
4078 | -else |
4079 | - rm -f conf$$.dir |
4080 | - mkdir conf$$.dir 2>/dev/null |
4081 | -fi |
4082 | -if (echo >conf$$.file) 2>/dev/null; then |
4083 | - if ln -s conf$$.file conf$$ 2>/dev/null; then |
4084 | - as_ln_s='ln -s' |
4085 | - # ... but there are two gotchas: |
4086 | - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. |
4087 | - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. |
4088 | - # In both cases, we have to default to `cp -p'. |
4089 | - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || |
4090 | - as_ln_s='cp -p' |
4091 | - elif ln conf$$.file conf$$ 2>/dev/null; then |
4092 | - as_ln_s=ln |
4093 | - else |
4094 | - as_ln_s='cp -p' |
4095 | - fi |
4096 | -else |
4097 | - as_ln_s='cp -p' |
4098 | -fi |
4099 | -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file |
4100 | -rmdir conf$$.dir 2>/dev/null |
4101 | - |
4102 | -if mkdir -p . 2>/dev/null; then |
4103 | - as_mkdir_p='mkdir -p "$as_dir"' |
4104 | -else |
4105 | - test -d ./-p && rmdir ./-p |
4106 | - as_mkdir_p=false |
4107 | -fi |
4108 | - |
4109 | -if test -x / >/dev/null 2>&1; then |
4110 | - as_test_x='test -x' |
4111 | -else |
4112 | - if ls -dL / >/dev/null 2>&1; then |
4113 | - as_ls_L_option=L |
4114 | - else |
4115 | - as_ls_L_option= |
4116 | - fi |
4117 | - as_test_x=' |
4118 | - eval sh -c '\'' |
4119 | - if test -d "$1"; then |
4120 | - test -d "$1/."; |
4121 | - else |
4122 | - case $1 in #( |
4123 | - -*)set "./$1";; |
4124 | - esac; |
4125 | - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( |
4126 | - ???[sx]*):;;*)false;;esac;fi |
4127 | - '\'' sh |
4128 | - ' |
4129 | -fi |
4130 | -as_executable_p=$as_test_x |
4131 | - |
4132 | -# Sed expression to map a string onto a valid CPP name. |
4133 | -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" |
4134 | - |
4135 | -# Sed expression to map a string onto a valid variable name. |
4136 | -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" |
4137 | - |
4138 | - |
4139 | -test -n "$DJDIR" || exec 7<&0 </dev/null |
4140 | -exec 6>&1 |
4141 | - |
4142 | -# Name of the host. |
4143 | -# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, |
4144 | -# so uname gets run too. |
4145 | -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` |
4146 | - |
4147 | -# |
4148 | -# Initializations. |
4149 | -# |
4150 | -ac_default_prefix=/usr/local |
4151 | -ac_clean_files= |
4152 | -ac_config_libobj_dir=. |
4153 | -LIBOBJS= |
4154 | -cross_compiling=no |
4155 | -subdirs= |
4156 | -MFLAGS= |
4157 | -MAKEFLAGS= |
4158 | - |
4159 | -# Identity of this package. |
4160 | -PACKAGE_NAME='Valgrind' |
4161 | -PACKAGE_TARNAME='valgrind' |
4162 | -PACKAGE_VERSION='3.7.0' |
4163 | -PACKAGE_STRING='Valgrind 3.7.0' |
4164 | -PACKAGE_BUGREPORT='valgrind-users@lists.sourceforge.net' |
4165 | -PACKAGE_URL='' |
4166 | - |
4167 | -ac_unique_file="coregrind/m_main.c" |
4168 | -# Factoring default headers for most tests. |
4169 | -ac_includes_default="\ |
4170 | -#include <stdio.h> |
4171 | -#ifdef HAVE_SYS_TYPES_H |
4172 | -# include <sys/types.h> |
4173 | -#endif |
4174 | -#ifdef HAVE_SYS_STAT_H |
4175 | -# include <sys/stat.h> |
4176 | -#endif |
4177 | -#ifdef STDC_HEADERS |
4178 | -# include <stdlib.h> |
4179 | -# include <stddef.h> |
4180 | -#else |
4181 | -# ifdef HAVE_STDLIB_H |
4182 | -# include <stdlib.h> |
4183 | -# endif |
4184 | -#endif |
4185 | -#ifdef HAVE_STRING_H |
4186 | -# if !defined STDC_HEADERS && defined HAVE_MEMORY_H |
4187 | -# include <memory.h> |
4188 | -# endif |
4189 | -# include <string.h> |
4190 | -#endif |
4191 | -#ifdef HAVE_STRINGS_H |
4192 | -# include <strings.h> |
4193 | -#endif |
4194 | -#ifdef HAVE_INTTYPES_H |
4195 | -# include <inttypes.h> |
4196 | -#endif |
4197 | -#ifdef HAVE_STDINT_H |
4198 | -# include <stdint.h> |
4199 | -#endif |
4200 | -#ifdef HAVE_UNISTD_H |
4201 | -# include <unistd.h> |
4202 | -#endif" |
4203 | - |
4204 | -ac_header_list= |
4205 | -ac_subst_vars='am__EXEEXT_FALSE |
4206 | -am__EXEEXT_TRUE |
4207 | -LTLIBOBJS |
4208 | -HAVE_BUILTIN_ATOMIC_CXX_FALSE |
4209 | -HAVE_BUILTIN_ATOMIC_CXX_TRUE |
4210 | -HAVE_BUILTIN_ATOMIC_FALSE |
4211 | -HAVE_BUILTIN_ATOMIC_TRUE |
4212 | -HAVE_OPENMP_FALSE |
4213 | -HAVE_OPENMP_TRUE |
4214 | -HAVE_BOOST_1_35_FALSE |
4215 | -HAVE_BOOST_1_35_TRUE |
4216 | -BOOST_LIBS |
4217 | -BOOST_CFLAGS |
4218 | -BUILD_MPIWRAP_SEC_FALSE |
4219 | -BUILD_MPIWRAP_SEC_TRUE |
4220 | -BUILD_MPIWRAP_PRI_FALSE |
4221 | -BUILD_MPIWRAP_PRI_TRUE |
4222 | -MPI_CC |
4223 | -HAVE_PTHREAD_SPINLOCK_FALSE |
4224 | -HAVE_PTHREAD_SPINLOCK_TRUE |
4225 | -HAVE_PTHREAD_MUTEX_TIMEDLOCK_FALSE |
4226 | -HAVE_PTHREAD_MUTEX_TIMEDLOCK_TRUE |
4227 | -HAVE_PTHREAD_BARRIER_FALSE |
4228 | -HAVE_PTHREAD_BARRIER_TRUE |
4229 | -LIBOBJS |
4230 | -BUILD_SSE42_TESTS_FALSE |
4231 | -BUILD_SSE42_TESTS_TRUE |
4232 | -BUILD_LZCNT_TESTS_FALSE |
4233 | -BUILD_LZCNT_TESTS_TRUE |
4234 | -BUILD_PCLMULQDQ_TESTS_FALSE |
4235 | -BUILD_PCLMULQDQ_TESTS_TRUE |
4236 | -BUILD_SSSE3_TESTS_FALSE |
4237 | -BUILD_SSSE3_TESTS_TRUE |
4238 | -BUILD_SSE3_TESTS_FALSE |
4239 | -BUILD_SSE3_TESTS_TRUE |
4240 | -FLAG_NO_BUILD_ID |
4241 | -FLAG_UNLIMITED_INLINE_UNIT_GROWTH |
4242 | -FLAG_FNO_STACK_PROTECTOR |
4243 | -FLAG_W_EXTRA |
4244 | -FLAG_W_NO_UNINITIALIZED |
4245 | -FLAG_W_NO_OVERFLOW |
4246 | -FLAG_W_NO_NONNULL |
4247 | -FLAG_W_NO_FORMAT_ZERO_LENGTH |
4248 | -FLAG_W_NO_EMPTY_BODY |
4249 | -PREFERRED_STACK_BOUNDARY |
4250 | -FLAG_MSSE |
4251 | -FLAG_MMMX |
4252 | -FLAG_M64 |
4253 | -FLAG_M32 |
4254 | -HAVE_PTHREAD_CREATE_GLIBC_2_0_FALSE |
4255 | -HAVE_PTHREAD_CREATE_GLIBC_2_0_TRUE |
4256 | -HAS_VSX_FALSE |
4257 | -HAS_VSX_TRUE |
4258 | -HAS_ALTIVEC_FALSE |
4259 | -HAS_ALTIVEC_TRUE |
4260 | -VGCONF_PLATVARIANT_IS_ANDROID_FALSE |
4261 | -VGCONF_PLATVARIANT_IS_ANDROID_TRUE |
4262 | -VGCONF_PLATVARIANT_IS_VANILLA_FALSE |
4263 | -VGCONF_PLATVARIANT_IS_VANILLA_TRUE |
4264 | -VGCONF_PLATVARIANT |
4265 | -GLIBC_VERSION |
4266 | -EGREP |
4267 | -GREP |
4268 | -DEFAULT_SUPP |
4269 | -VALT_LOAD_ADDRESS_SEC |
4270 | -VALT_LOAD_ADDRESS_PRI |
4271 | -VGCONF_HAVE_PLATFORM_SEC_FALSE |
4272 | -VGCONF_HAVE_PLATFORM_SEC_TRUE |
4273 | -VGCONF_OS_IS_DARWIN_FALSE |
4274 | -VGCONF_OS_IS_DARWIN_TRUE |
4275 | -VGCONF_OS_IS_LINUX_FALSE |
4276 | -VGCONF_OS_IS_LINUX_TRUE |
4277 | -VGCONF_PLATFORMS_INCLUDE_AMD64_DARWIN_FALSE |
4278 | -VGCONF_PLATFORMS_INCLUDE_AMD64_DARWIN_TRUE |
4279 | -VGCONF_PLATFORMS_INCLUDE_X86_DARWIN_FALSE |
4280 | -VGCONF_PLATFORMS_INCLUDE_X86_DARWIN_TRUE |
4281 | -VGCONF_PLATFORMS_INCLUDE_S390X_LINUX_FALSE |
4282 | -VGCONF_PLATFORMS_INCLUDE_S390X_LINUX_TRUE |
4283 | -VGCONF_PLATFORMS_INCLUDE_ARM_LINUX_FALSE |
4284 | -VGCONF_PLATFORMS_INCLUDE_ARM_LINUX_TRUE |
4285 | -VGCONF_PLATFORMS_INCLUDE_PPC64_LINUX_FALSE |
4286 | -VGCONF_PLATFORMS_INCLUDE_PPC64_LINUX_TRUE |
4287 | -VGCONF_PLATFORMS_INCLUDE_PPC32_LINUX_FALSE |
4288 | -VGCONF_PLATFORMS_INCLUDE_PPC32_LINUX_TRUE |
4289 | -VGCONF_PLATFORMS_INCLUDE_AMD64_LINUX_FALSE |
4290 | -VGCONF_PLATFORMS_INCLUDE_AMD64_LINUX_TRUE |
4291 | -VGCONF_PLATFORMS_INCLUDE_X86_LINUX_FALSE |
4292 | -VGCONF_PLATFORMS_INCLUDE_X86_LINUX_TRUE |
4293 | -VGCONF_ARCHS_INCLUDE_S390X_FALSE |
4294 | -VGCONF_ARCHS_INCLUDE_S390X_TRUE |
4295 | -VGCONF_ARCHS_INCLUDE_ARM_FALSE |
4296 | -VGCONF_ARCHS_INCLUDE_ARM_TRUE |
4297 | -VGCONF_ARCHS_INCLUDE_PPC64_FALSE |
4298 | -VGCONF_ARCHS_INCLUDE_PPC64_TRUE |
4299 | -VGCONF_ARCHS_INCLUDE_PPC32_FALSE |
4300 | -VGCONF_ARCHS_INCLUDE_PPC32_TRUE |
4301 | -VGCONF_ARCHS_INCLUDE_AMD64_FALSE |
4302 | -VGCONF_ARCHS_INCLUDE_AMD64_TRUE |
4303 | -VGCONF_ARCHS_INCLUDE_X86_FALSE |
4304 | -VGCONF_ARCHS_INCLUDE_X86_TRUE |
4305 | -VGCONF_PLATFORM_SEC_CAPS |
4306 | -VGCONF_PLATFORM_PRI_CAPS |
4307 | -VGCONF_ARCH_SEC |
4308 | -VGCONF_ARCH_PRI |
4309 | -VGCONF_OS |
4310 | -host_os |
4311 | -host_vendor |
4312 | -host_cpu |
4313 | -host |
4314 | -build_os |
4315 | -build_vendor |
4316 | -build_cpu |
4317 | -build |
4318 | -DIFF |
4319 | -am__fastdepCCAS_FALSE |
4320 | -am__fastdepCCAS_TRUE |
4321 | -CCASDEPMODE |
4322 | -CCASFLAGS |
4323 | -CCAS |
4324 | -GDB |
4325 | -PERL |
4326 | -AR |
4327 | -SED |
4328 | -RANLIB |
4329 | -am__fastdepCXX_FALSE |
4330 | -am__fastdepCXX_TRUE |
4331 | -CXXDEPMODE |
4332 | -ac_ct_CXX |
4333 | -CXXFLAGS |
4334 | -CXX |
4335 | -CPP |
4336 | -am__fastdepCC_FALSE |
4337 | -am__fastdepCC_TRUE |
4338 | -CCDEPMODE |
4339 | -AMDEPBACKSLASH |
4340 | -AMDEP_FALSE |
4341 | -AMDEP_TRUE |
4342 | -am__quote |
4343 | -am__include |
4344 | -DEPDIR |
4345 | -OBJEXT |
4346 | -EXEEXT |
4347 | -ac_ct_CC |
4348 | -CPPFLAGS |
4349 | -LDFLAGS |
4350 | -CFLAGS |
4351 | -CC |
4352 | -LN_S |
4353 | -MAINT |
4354 | -MAINTAINER_MODE_FALSE |
4355 | -MAINTAINER_MODE_TRUE |
4356 | -am__untar |
4357 | -am__tar |
4358 | -AMTAR |
4359 | -am__leading_dot |
4360 | -SET_MAKE |
4361 | -AWK |
4362 | -mkdir_p |
4363 | -MKDIR_P |
4364 | -INSTALL_STRIP_PROGRAM |
4365 | -STRIP |
4366 | -install_sh |
4367 | -MAKEINFO |
4368 | -AUTOHEADER |
4369 | -AUTOMAKE |
4370 | -AUTOCONF |
4371 | -ACLOCAL |
4372 | -VERSION |
4373 | -PACKAGE |
4374 | -CYGPATH_W |
4375 | -am__isrc |
4376 | -INSTALL_DATA |
4377 | -INSTALL_SCRIPT |
4378 | -INSTALL_PROGRAM |
4379 | -target_alias |
4380 | -host_alias |
4381 | -build_alias |
4382 | -LIBS |
4383 | -ECHO_T |
4384 | -ECHO_N |
4385 | -ECHO_C |
4386 | -DEFS |
4387 | -mandir |
4388 | -localedir |
4389 | -libdir |
4390 | -psdir |
4391 | -pdfdir |
4392 | -dvidir |
4393 | -htmldir |
4394 | -infodir |
4395 | -docdir |
4396 | -oldincludedir |
4397 | -includedir |
4398 | -localstatedir |
4399 | -sharedstatedir |
4400 | -sysconfdir |
4401 | -datadir |
4402 | -datarootdir |
4403 | -libexecdir |
4404 | -sbindir |
4405 | -bindir |
4406 | -program_transform_name |
4407 | -prefix |
4408 | -exec_prefix |
4409 | -PACKAGE_URL |
4410 | -PACKAGE_BUGREPORT |
4411 | -PACKAGE_STRING |
4412 | -PACKAGE_VERSION |
4413 | -PACKAGE_TARNAME |
4414 | -PACKAGE_NAME |
4415 | -PATH_SEPARATOR |
4416 | -SHELL' |
4417 | -ac_subst_files='' |
4418 | -ac_user_opts=' |
4419 | -enable_option_checking |
4420 | -enable_maintainer_mode |
4421 | -enable_dependency_tracking |
4422 | -enable_only64bit |
4423 | -enable_only32bit |
4424 | -enable_inner |
4425 | -with_tmpdir |
4426 | -enable_tls |
4427 | -with_mpicc |
4428 | -' |
4429 | - ac_precious_vars='build_alias |
4430 | -host_alias |
4431 | -target_alias |
4432 | -CC |
4433 | -CFLAGS |
4434 | -LDFLAGS |
4435 | -LIBS |
4436 | -CPPFLAGS |
4437 | -CPP |
4438 | -CXX |
4439 | -CXXFLAGS |
4440 | -CCC |
4441 | -AR |
4442 | -CCAS |
4443 | -CCASFLAGS' |
4444 | - |
4445 | - |
4446 | -# Initialize some variables set by options. |
4447 | -ac_init_help= |
4448 | -ac_init_version=false |
4449 | -ac_unrecognized_opts= |
4450 | -ac_unrecognized_sep= |
4451 | -# The variables have the same names as the options, with |
4452 | -# dashes changed to underlines. |
4453 | -cache_file=/dev/null |
4454 | -exec_prefix=NONE |
4455 | -no_create= |
4456 | -no_recursion= |
4457 | -prefix=NONE |
4458 | -program_prefix=NONE |
4459 | -program_suffix=NONE |
4460 | -program_transform_name=s,x,x, |
4461 | -silent= |
4462 | -site= |
4463 | -srcdir= |
4464 | -verbose= |
4465 | -x_includes=NONE |
4466 | -x_libraries=NONE |
4467 | - |
4468 | -# Installation directory options. |
4469 | -# These are left unexpanded so users can "make install exec_prefix=/foo" |
4470 | -# and all the variables that are supposed to be based on exec_prefix |
4471 | -# by default will actually change. |
4472 | -# Use braces instead of parens because sh, perl, etc. also accept them. |
4473 | -# (The list follows the same order as the GNU Coding Standards.) |
4474 | -bindir='${exec_prefix}/bin' |
4475 | -sbindir='${exec_prefix}/sbin' |
4476 | -libexecdir='${exec_prefix}/libexec' |
4477 | -datarootdir='${prefix}/share' |
4478 | -datadir='${datarootdir}' |
4479 | -sysconfdir='${prefix}/etc' |
4480 | -sharedstatedir='${prefix}/com' |
4481 | -localstatedir='${prefix}/var' |
4482 | -includedir='${prefix}/include' |
4483 | -oldincludedir='/usr/include' |
4484 | -docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' |
4485 | -infodir='${datarootdir}/info' |
4486 | -htmldir='${docdir}' |
4487 | -dvidir='${docdir}' |
4488 | -pdfdir='${docdir}' |
4489 | -psdir='${docdir}' |
4490 | -libdir='${exec_prefix}/lib' |
4491 | -localedir='${datarootdir}/locale' |
4492 | -mandir='${datarootdir}/man' |
4493 | - |
4494 | -ac_prev= |
4495 | -ac_dashdash= |
4496 | -for ac_option |
4497 | -do |
4498 | - # If the previous option needs an argument, assign it. |
4499 | - if test -n "$ac_prev"; then |
4500 | - eval $ac_prev=\$ac_option |
4501 | - ac_prev= |
4502 | - continue |
4503 | - fi |
4504 | - |
4505 | - case $ac_option in |
4506 | - *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; |
4507 | - *) ac_optarg=yes ;; |
4508 | - esac |
4509 | - |
4510 | - # Accept the important Cygnus configure options, so we can diagnose typos. |
4511 | - |
4512 | - case $ac_dashdash$ac_option in |
4513 | - --) |
4514 | - ac_dashdash=yes ;; |
4515 | - |
4516 | - -bindir | --bindir | --bindi | --bind | --bin | --bi) |
4517 | - ac_prev=bindir ;; |
4518 | - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) |
4519 | - bindir=$ac_optarg ;; |
4520 | - |
4521 | - -build | --build | --buil | --bui | --bu) |
4522 | - ac_prev=build_alias ;; |
4523 | - -build=* | --build=* | --buil=* | --bui=* | --bu=*) |
4524 | - build_alias=$ac_optarg ;; |
4525 | - |
4526 | - -cache-file | --cache-file | --cache-fil | --cache-fi \ |
4527 | - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) |
4528 | - ac_prev=cache_file ;; |
4529 | - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ |
4530 | - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) |
4531 | - cache_file=$ac_optarg ;; |
4532 | - |
4533 | - --config-cache | -C) |
4534 | - cache_file=config.cache ;; |
4535 | - |
4536 | - -datadir | --datadir | --datadi | --datad) |
4537 | - ac_prev=datadir ;; |
4538 | - -datadir=* | --datadir=* | --datadi=* | --datad=*) |
4539 | - datadir=$ac_optarg ;; |
4540 | - |
4541 | - -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ |
4542 | - | --dataroo | --dataro | --datar) |
4543 | - ac_prev=datarootdir ;; |
4544 | - -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ |
4545 | - | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) |
4546 | - datarootdir=$ac_optarg ;; |
4547 | - |
4548 | - -disable-* | --disable-*) |
4549 | - ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` |
4550 | - # Reject names that are not valid shell variable names. |
4551 | - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && |
4552 | - as_fn_error "invalid feature name: $ac_useropt" |
4553 | - ac_useropt_orig=$ac_useropt |
4554 | - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` |
4555 | - case $ac_user_opts in |
4556 | - *" |
4557 | -"enable_$ac_useropt" |
4558 | -"*) ;; |
4559 | - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" |
4560 | - ac_unrecognized_sep=', ';; |
4561 | - esac |
4562 | - eval enable_$ac_useropt=no ;; |
4563 | - |
4564 | - -docdir | --docdir | --docdi | --doc | --do) |
4565 | - ac_prev=docdir ;; |
4566 | - -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) |
4567 | - docdir=$ac_optarg ;; |
4568 | - |
4569 | - -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) |
4570 | - ac_prev=dvidir ;; |
4571 | - -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) |
4572 | - dvidir=$ac_optarg ;; |
4573 | - |
4574 | - -enable-* | --enable-*) |
4575 | - ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` |
4576 | - # Reject names that are not valid shell variable names. |
4577 | - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && |
4578 | - as_fn_error "invalid feature name: $ac_useropt" |
4579 | - ac_useropt_orig=$ac_useropt |
4580 | - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` |
4581 | - case $ac_user_opts in |
4582 | - *" |
4583 | -"enable_$ac_useropt" |
4584 | -"*) ;; |
4585 | - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" |
4586 | - ac_unrecognized_sep=', ';; |
4587 | - esac |
4588 | - eval enable_$ac_useropt=\$ac_optarg ;; |
4589 | - |
4590 | - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ |
4591 | - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ |
4592 | - | --exec | --exe | --ex) |
4593 | - ac_prev=exec_prefix ;; |
4594 | - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ |
4595 | - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ |
4596 | - | --exec=* | --exe=* | --ex=*) |
4597 | - exec_prefix=$ac_optarg ;; |
4598 | - |
4599 | - -gas | --gas | --ga | --g) |
4600 | - # Obsolete; use --with-gas. |
4601 | - with_gas=yes ;; |
4602 | - |
4603 | - -help | --help | --hel | --he | -h) |
4604 | - ac_init_help=long ;; |
4605 | - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) |
4606 | - ac_init_help=recursive ;; |
4607 | - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) |
4608 | - ac_init_help=short ;; |
4609 | - |
4610 | - -host | --host | --hos | --ho) |
4611 | - ac_prev=host_alias ;; |
4612 | - -host=* | --host=* | --hos=* | --ho=*) |
4613 | - host_alias=$ac_optarg ;; |
4614 | - |
4615 | - -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) |
4616 | - ac_prev=htmldir ;; |
4617 | - -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ |
4618 | - | --ht=*) |
4619 | - htmldir=$ac_optarg ;; |
4620 | - |
4621 | - -includedir | --includedir | --includedi | --included | --include \ |
4622 | - | --includ | --inclu | --incl | --inc) |
4623 | - ac_prev=includedir ;; |
4624 | - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ |
4625 | - | --includ=* | --inclu=* | --incl=* | --inc=*) |
4626 | - includedir=$ac_optarg ;; |
4627 | - |
4628 | - -infodir | --infodir | --infodi | --infod | --info | --inf) |
4629 | - ac_prev=infodir ;; |
4630 | - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) |
4631 | - infodir=$ac_optarg ;; |
4632 | - |
4633 | - -libdir | --libdir | --libdi | --libd) |
4634 | - ac_prev=libdir ;; |
4635 | - -libdir=* | --libdir=* | --libdi=* | --libd=*) |
4636 | - libdir=$ac_optarg ;; |
4637 | - |
4638 | - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ |
4639 | - | --libexe | --libex | --libe) |
4640 | - ac_prev=libexecdir ;; |
4641 | - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ |
4642 | - | --libexe=* | --libex=* | --libe=*) |
4643 | - libexecdir=$ac_optarg ;; |
4644 | - |
4645 | - -localedir | --localedir | --localedi | --localed | --locale) |
4646 | - ac_prev=localedir ;; |
4647 | - -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) |
4648 | - localedir=$ac_optarg ;; |
4649 | - |
4650 | - -localstatedir | --localstatedir | --localstatedi | --localstated \ |
4651 | - | --localstate | --localstat | --localsta | --localst | --locals) |
4652 | - ac_prev=localstatedir ;; |
4653 | - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ |
4654 | - | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) |
4655 | - localstatedir=$ac_optarg ;; |
4656 | - |
4657 | - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) |
4658 | - ac_prev=mandir ;; |
4659 | - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) |
4660 | - mandir=$ac_optarg ;; |
4661 | - |
4662 | - -nfp | --nfp | --nf) |
4663 | - # Obsolete; use --without-fp. |
4664 | - with_fp=no ;; |
4665 | - |
4666 | - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ |
4667 | - | --no-cr | --no-c | -n) |
4668 | - no_create=yes ;; |
4669 | - |
4670 | - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ |
4671 | - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) |
4672 | - no_recursion=yes ;; |
4673 | - |
4674 | - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ |
4675 | - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ |
4676 | - | --oldin | --oldi | --old | --ol | --o) |
4677 | - ac_prev=oldincludedir ;; |
4678 | - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ |
4679 | - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ |
4680 | - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) |
4681 | - oldincludedir=$ac_optarg ;; |
4682 | - |
4683 | - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) |
4684 | - ac_prev=prefix ;; |
4685 | - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) |
4686 | - prefix=$ac_optarg ;; |
4687 | - |
4688 | - -program-prefix | --program-prefix | --program-prefi | --program-pref \ |
4689 | - | --program-pre | --program-pr | --program-p) |
4690 | - ac_prev=program_prefix ;; |
4691 | - -program-prefix=* | --program-prefix=* | --program-prefi=* \ |
4692 | - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) |
4693 | - program_prefix=$ac_optarg ;; |
4694 | - |
4695 | - -program-suffix | --program-suffix | --program-suffi | --program-suff \ |
4696 | - | --program-suf | --program-su | --program-s) |
4697 | - ac_prev=program_suffix ;; |
4698 | - -program-suffix=* | --program-suffix=* | --program-suffi=* \ |
4699 | - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) |
4700 | - program_suffix=$ac_optarg ;; |
4701 | - |
4702 | - -program-transform-name | --program-transform-name \ |
4703 | - | --program-transform-nam | --program-transform-na \ |
4704 | - | --program-transform-n | --program-transform- \ |
4705 | - | --program-transform | --program-transfor \ |
4706 | - | --program-transfo | --program-transf \ |
4707 | - | --program-trans | --program-tran \ |
4708 | - | --progr-tra | --program-tr | --program-t) |
4709 | - ac_prev=program_transform_name ;; |
4710 | - -program-transform-name=* | --program-transform-name=* \ |
4711 | - | --program-transform-nam=* | --program-transform-na=* \ |
4712 | - | --program-transform-n=* | --program-transform-=* \ |
4713 | - | --program-transform=* | --program-transfor=* \ |
4714 | - | --program-transfo=* | --program-transf=* \ |
4715 | - | --program-trans=* | --program-tran=* \ |
4716 | - | --progr-tra=* | --program-tr=* | --program-t=*) |
4717 | - program_transform_name=$ac_optarg ;; |
4718 | - |
4719 | - -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) |
4720 | - ac_prev=pdfdir ;; |
4721 | - -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) |
4722 | - pdfdir=$ac_optarg ;; |
4723 | - |
4724 | - -psdir | --psdir | --psdi | --psd | --ps) |
4725 | - ac_prev=psdir ;; |
4726 | - -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) |
4727 | - psdir=$ac_optarg ;; |
4728 | - |
4729 | - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ |
4730 | - | -silent | --silent | --silen | --sile | --sil) |
4731 | - silent=yes ;; |
4732 | - |
4733 | - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) |
4734 | - ac_prev=sbindir ;; |
4735 | - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ |
4736 | - | --sbi=* | --sb=*) |
4737 | - sbindir=$ac_optarg ;; |
4738 | - |
4739 | - -sharedstatedir | --sharedstatedir | --sharedstatedi \ |
4740 | - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ |
4741 | - | --sharedst | --shareds | --shared | --share | --shar \ |
4742 | - | --sha | --sh) |
4743 | - ac_prev=sharedstatedir ;; |
4744 | - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ |
4745 | - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ |
4746 | - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ |
4747 | - | --sha=* | --sh=*) |
4748 | - sharedstatedir=$ac_optarg ;; |
4749 | - |
4750 | - -site | --site | --sit) |
4751 | - ac_prev=site ;; |
4752 | - -site=* | --site=* | --sit=*) |
4753 | - site=$ac_optarg ;; |
4754 | - |
4755 | - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) |
4756 | - ac_prev=srcdir ;; |
4757 | - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) |
4758 | - srcdir=$ac_optarg ;; |
4759 | - |
4760 | - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ |
4761 | - | --syscon | --sysco | --sysc | --sys | --sy) |
4762 | - ac_prev=sysconfdir ;; |
4763 | - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ |
4764 | - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) |
4765 | - sysconfdir=$ac_optarg ;; |
4766 | - |
4767 | - -target | --target | --targe | --targ | --tar | --ta | --t) |
4768 | - ac_prev=target_alias ;; |
4769 | - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) |
4770 | - target_alias=$ac_optarg ;; |
4771 | - |
4772 | - -v | -verbose | --verbose | --verbos | --verbo | --verb) |
4773 | - verbose=yes ;; |
4774 | - |
4775 | - -version | --version | --versio | --versi | --vers | -V) |
4776 | - ac_init_version=: ;; |
4777 | - |
4778 | - -with-* | --with-*) |
4779 | - ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` |
4780 | - # Reject names that are not valid shell variable names. |
4781 | - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && |
4782 | - as_fn_error "invalid package name: $ac_useropt" |
4783 | - ac_useropt_orig=$ac_useropt |
4784 | - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` |
4785 | - case $ac_user_opts in |
4786 | - *" |
4787 | -"with_$ac_useropt" |
4788 | -"*) ;; |
4789 | - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" |
4790 | - ac_unrecognized_sep=', ';; |
4791 | - esac |
4792 | - eval with_$ac_useropt=\$ac_optarg ;; |
4793 | - |
4794 | - -without-* | --without-*) |
4795 | - ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` |
4796 | - # Reject names that are not valid shell variable names. |
4797 | - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && |
4798 | - as_fn_error "invalid package name: $ac_useropt" |
4799 | - ac_useropt_orig=$ac_useropt |
4800 | - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` |
4801 | - case $ac_user_opts in |
4802 | - *" |
4803 | -"with_$ac_useropt" |
4804 | -"*) ;; |
4805 | - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" |
4806 | - ac_unrecognized_sep=', ';; |
4807 | - esac |
4808 | - eval with_$ac_useropt=no ;; |
4809 | - |
4810 | - --x) |
4811 | - # Obsolete; use --with-x. |
4812 | - with_x=yes ;; |
4813 | - |
4814 | - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ |
4815 | - | --x-incl | --x-inc | --x-in | --x-i) |
4816 | - ac_prev=x_includes ;; |
4817 | - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ |
4818 | - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) |
4819 | - x_includes=$ac_optarg ;; |
4820 | - |
4821 | - -x-libraries | --x-libraries | --x-librarie | --x-librari \ |
4822 | - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) |
4823 | - ac_prev=x_libraries ;; |
4824 | - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ |
4825 | - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) |
4826 | - x_libraries=$ac_optarg ;; |
4827 | - |
4828 | - -*) as_fn_error "unrecognized option: \`$ac_option' |
4829 | -Try \`$0 --help' for more information." |
4830 | - ;; |
4831 | - |
4832 | - *=*) |
4833 | - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` |
4834 | - # Reject names that are not valid shell variable names. |
4835 | - case $ac_envvar in #( |
4836 | - '' | [0-9]* | *[!_$as_cr_alnum]* ) |
4837 | - as_fn_error "invalid variable name: \`$ac_envvar'" ;; |
4838 | - esac |
4839 | - eval $ac_envvar=\$ac_optarg |
4840 | - export $ac_envvar ;; |
4841 | - |
4842 | - *) |
4843 | - # FIXME: should be removed in autoconf 3.0. |
4844 | - $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 |
4845 | - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && |
4846 | - $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 |
4847 | - : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} |
4848 | - ;; |
4849 | - |
4850 | - esac |
4851 | -done |
4852 | - |
4853 | -if test -n "$ac_prev"; then |
4854 | - ac_option=--`echo $ac_prev | sed 's/_/-/g'` |
4855 | - as_fn_error "missing argument to $ac_option" |
4856 | -fi |
4857 | - |
4858 | -if test -n "$ac_unrecognized_opts"; then |
4859 | - case $enable_option_checking in |
4860 | - no) ;; |
4861 | - fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;; |
4862 | - *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; |
4863 | - esac |
4864 | -fi |
4865 | - |
4866 | -# Check all directory arguments for consistency. |
4867 | -for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ |
4868 | - datadir sysconfdir sharedstatedir localstatedir includedir \ |
4869 | - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ |
4870 | - libdir localedir mandir |
4871 | -do |
4872 | - eval ac_val=\$$ac_var |
4873 | - # Remove trailing slashes. |
4874 | - case $ac_val in |
4875 | - */ ) |
4876 | - ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` |
4877 | - eval $ac_var=\$ac_val;; |
4878 | - esac |
4879 | - # Be sure to have absolute directory names. |
4880 | - case $ac_val in |
4881 | - [\\/$]* | ?:[\\/]* ) continue;; |
4882 | - NONE | '' ) case $ac_var in *prefix ) continue;; esac;; |
4883 | - esac |
4884 | - as_fn_error "expected an absolute directory name for --$ac_var: $ac_val" |
4885 | -done |
4886 | - |
4887 | -# There might be people who depend on the old broken behavior: `$host' |
4888 | -# used to hold the argument of --host etc. |
4889 | -# FIXME: To remove some day. |
4890 | -build=$build_alias |
4891 | -host=$host_alias |
4892 | -target=$target_alias |
4893 | - |
4894 | -# FIXME: To remove some day. |
4895 | -if test "x$host_alias" != x; then |
4896 | - if test "x$build_alias" = x; then |
4897 | - cross_compiling=maybe |
4898 | - $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. |
4899 | - If a cross compiler is detected then cross compile mode will be used." >&2 |
4900 | - elif test "x$build_alias" != "x$host_alias"; then |
4901 | - cross_compiling=yes |
4902 | - fi |
4903 | -fi |
4904 | - |
4905 | -ac_tool_prefix= |
4906 | -test -n "$host_alias" && ac_tool_prefix=$host_alias- |
4907 | - |
4908 | -test "$silent" = yes && exec 6>/dev/null |
4909 | - |
4910 | - |
4911 | -ac_pwd=`pwd` && test -n "$ac_pwd" && |
4912 | -ac_ls_di=`ls -di .` && |
4913 | -ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || |
4914 | - as_fn_error "working directory cannot be determined" |
4915 | -test "X$ac_ls_di" = "X$ac_pwd_ls_di" || |
4916 | - as_fn_error "pwd does not report name of working directory" |
4917 | - |
4918 | - |
4919 | -# Find the source files, if location was not specified. |
4920 | -if test -z "$srcdir"; then |
4921 | - ac_srcdir_defaulted=yes |
4922 | - # Try the directory containing this script, then the parent directory. |
4923 | - ac_confdir=`$as_dirname -- "$as_myself" || |
4924 | -$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ |
4925 | - X"$as_myself" : 'X\(//\)[^/]' \| \ |
4926 | - X"$as_myself" : 'X\(//\)$' \| \ |
4927 | - X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || |
4928 | -$as_echo X"$as_myself" | |
4929 | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ |
4930 | - s//\1/ |
4931 | - q |
4932 | - } |
4933 | - /^X\(\/\/\)[^/].*/{ |
4934 | - s//\1/ |
4935 | - q |
4936 | - } |
4937 | - /^X\(\/\/\)$/{ |
4938 | - s//\1/ |
4939 | - q |
4940 | - } |
4941 | - /^X\(\/\).*/{ |
4942 | - s//\1/ |
4943 | - q |
4944 | - } |
4945 | - s/.*/./; q'` |
4946 | - srcdir=$ac_confdir |
4947 | - if test ! -r "$srcdir/$ac_unique_file"; then |
4948 | - srcdir=.. |
4949 | - fi |
4950 | -else |
4951 | - ac_srcdir_defaulted=no |
4952 | -fi |
4953 | -if test ! -r "$srcdir/$ac_unique_file"; then |
4954 | - test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." |
4955 | - as_fn_error "cannot find sources ($ac_unique_file) in $srcdir" |
4956 | -fi |
4957 | -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" |
4958 | -ac_abs_confdir=`( |
4959 | - cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg" |
4960 | - pwd)` |
4961 | -# When building in place, set srcdir=. |
4962 | -if test "$ac_abs_confdir" = "$ac_pwd"; then |
4963 | - srcdir=. |
4964 | -fi |
4965 | -# Remove unnecessary trailing slashes from srcdir. |
4966 | -# Double slashes in file names in object file debugging info |
4967 | -# mess up M-x gdb in Emacs. |
4968 | -case $srcdir in |
4969 | -*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; |
4970 | -esac |
4971 | -for ac_var in $ac_precious_vars; do |
4972 | - eval ac_env_${ac_var}_set=\${${ac_var}+set} |
4973 | - eval ac_env_${ac_var}_value=\$${ac_var} |
4974 | - eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} |
4975 | - eval ac_cv_env_${ac_var}_value=\$${ac_var} |
4976 | -done |
4977 | - |
4978 | -# |
4979 | -# Report the --help message. |
4980 | -# |
4981 | -if test "$ac_init_help" = "long"; then |
4982 | - # Omit some internal or obsolete options to make the list less imposing. |
4983 | - # This message is too long to be a string in the A/UX 3.1 sh. |
4984 | - cat <<_ACEOF |
4985 | -\`configure' configures Valgrind 3.7.0 to adapt to many kinds of systems. |
4986 | - |
4987 | -Usage: $0 [OPTION]... [VAR=VALUE]... |
4988 | - |
4989 | -To assign environment variables (e.g., CC, CFLAGS...), specify them as |
4990 | -VAR=VALUE. See below for descriptions of some of the useful variables. |
4991 | - |
4992 | -Defaults for the options are specified in brackets. |
4993 | - |
4994 | -Configuration: |
4995 | - -h, --help display this help and exit |
4996 | - --help=short display options specific to this package |
4997 | - --help=recursive display the short help of all the included packages |
4998 | - -V, --version display version information and exit |
4999 | - -q, --quiet, --silent do not print \`checking...' messages |
5000 | - --cache-file=FILE cache test results in FILE [disabled] |
The diff has been truncated for viewing.
Two immediate issues I see:
* The version number should be 1:3.8.1-1ubuntu1, not 1:3.8.1-0ubuntu2, as this is a merge from Debian.
* The latest changelog entry should describe the Ubuntu changes that remain as a delta from Debian so that the Debian maintainer can consider integrating them.
I haven't looked deeper yet, but those issues definitely need to be fixed first.