2 /*--------------------------------------------------------------------*/
3 /*--- The address space manager. pub_core_aspacemgr.h ---*/
4 /*--------------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2000-2010 Julian Seward
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 The GNU General Public License is contained in the file COPYING.
31 #ifndef __PUB_CORE_ASPACEMGR_H
32 #define __PUB_CORE_ASPACEMGR_H
34 //--------------------------------------------------------------------
35 // PURPOSE: This module deals with management of the entire process
36 // address space. Almost everything depends upon it, including dynamic
37 // memory management. Hence this module is almost completely
38 // standalone; the only module it uses is m_debuglog. DO NOT CHANGE
40 //--------------------------------------------------------------------
42 #include "pub_tool_aspacemgr.h"
44 //--------------------------------------------------------------
45 // Definition of address-space segments
47 /* types SegKind, ShrinkMode and NSegment are described in
48 the tool-visible header file, not here. */
51 //--------------------------------------------------------------
54 /* Initialise the address space manager, setting up the initial
55 segment list, and reading /proc/self/maps into it. This must
56 be called before any other function.
58 Takes a pointer to the SP at the time V gained control. This is
59 taken to be the highest usable address (more or less). Based on
60 that (and general consultation of tea leaves, etc) return a
61 suggested end address for the client's stack. */
62 extern Addr VG_(am_startup) ( Addr sp_at_startup );
65 //--------------------------------------------------------------
66 // Querying current status
68 /* Finds the segment containing 'a'. Only returns file/anon/resvn
69 segments. This returns a 'NSegment const *' - a pointer to
71 // Is in tool-visible header file.
72 // extern NSegment const * VG_(am_find_nsegment) ( Addr a );
74 /* Find the next segment along from 'here', if it is a file/anon/resvn
76 extern NSegment const* VG_(am_next_nsegment) ( NSegment* here, Bool fwds );
78 /* Is the area [start .. start+len-1] validly accessible by the
79 client with at least the permissions 'prot' ? To find out
80 simply if said area merely belongs to the client, pass
81 VKI_PROT_NONE as 'prot'. Will return False if any part of the
82 area does not belong to the client or does not have at least
83 the stated permissions. */
84 // Is in tool-visible header file.
85 // extern Bool VG_(am_is_valid_for_client)
86 // ( Addr start, SizeT len, UInt prot );
88 /* Variant of VG_(am_is_valid_for_client) which allows free areas to
89 be consider part of the client's addressable space. It also
90 considers reservations to be allowable, since from the client's
91 point of view they don't exist. */
92 extern Bool VG_(am_is_valid_for_client_or_free_or_resvn)
93 ( Addr start, SizeT len, UInt prot );
95 /* Trivial fn: return the total amount of space in anonymous mappings,
96 both for V and the client. Is used for printing stats in
97 out-of-memory messages. */
98 extern ULong VG_(am_get_anonsize_total)( void );
100 /* Show the segment array on the debug log, at given loglevel. */
101 extern void VG_(am_show_nsegments) ( Int logLevel, HChar* who );
103 /* Get the filename corresponding to this segment, if known and if it
104 has one. The returned name's storage cannot be assumed to be
105 persistent, so the caller should immediately copy the name
106 elsewhere. This may return NULL if the file name is not known or
107 for arbitrary other implementation-dependent reasons, so callers
108 need to be able to handle a NULL return value. */
109 // Is in tool-visible header file.
110 // extern HChar* VG_(am_get_filename)( NSegment* );
112 /* VG_(am_get_segment_starts) is also part of this section, but its
113 prototype is tool-visible, hence not in this header file. */
115 /* Sanity check: check that Valgrind and the kernel agree on the
116 address space layout. Prints offending segments and call point if
117 a discrepancy is detected, but does not abort the system. Returned
118 Bool is False if a discrepancy was found. */
120 extern Bool VG_(am_do_sync_check) ( const HChar* fn,
121 const HChar* file, Int line );
123 //--------------------------------------------------------------
124 // Functions pertaining to the central query-notify mechanism
125 // used to handle mmap/munmap/mprotect resulting from client
128 /* Describes a request for VG_(am_get_advisory). */
131 enum { MFixed, MHint, MAny } rkind;
137 /* Query aspacem to ask where a mapping should go. On success, the
138 advised placement is returned, and *ok is set to True. On failure,
139 zero is returned and *ok is set to False. Note that *ok must be
140 consulted by the caller to establish success or failure; that
141 cannot be established reliably from the returned value. If *ok is
142 set to False, it means aspacem has vetoed the mapping, and so the
143 caller should not proceed with it. */
144 extern Addr VG_(am_get_advisory)
145 ( MapRequest* req, Bool forClient, /*OUT*/Bool* ok );
147 /* Convenience wrapper for VG_(am_get_advisory) for client floating or
148 fixed requests. If start is zero, a floating request is issued; if
149 nonzero, a fixed request at that address is issued. Same comments
150 about return values apply. */
151 extern Addr VG_(am_get_advisory_client_simple)
152 ( Addr start, SizeT len, /*OUT*/Bool* ok );
154 #if defined(VGO_l4re)
155 /* Convenience wrapper for VG_(am_get_advisory) for Valgrind floating or
156 fixed requests. If start is zero, a floating request is issued; if
157 nonzero, a fixed request at that address is issued. Same comments
158 about return values apply. */
159 extern Addr VG_(am_get_advisory_valgrind_simple)
160 ( Addr start, SizeT len, /*OUT*/Bool* ok );
164 /* Notifies aspacem that the client completed an mmap successfully.
165 The segment array is updated accordingly. If the returned Bool is
166 True, the caller should immediately discard translations from the
167 specified address range. */
168 extern Bool VG_(am_notify_client_mmap)
169 ( Addr a, SizeT len, UInt prot, UInt flags, Int fd, Off64T offset );
170 extern Bool VG_(am_notify_valgrind_mmap)
171 ( Addr a, SizeT len, UInt prot, UInt flags, Int fd, Off64T offset );
173 /* Notifies aspacem that the client completed a shmat successfully.
174 The segment array is updated accordingly. If the returned Bool is
175 True, the caller should immediately discard translations from the
176 specified address range. */
177 extern Bool VG_(am_notify_client_shmat)( Addr a, SizeT len, UInt prot );
179 /* Notifies aspacem that an mprotect was completed successfully. The
180 segment array is updated accordingly. Note, as with
181 VG_(am_notify_munmap), it is not the job of this function to reject
182 stupid mprotects, for example the client doing mprotect of
183 non-client areas. Such requests should be intercepted earlier, by
184 the syscall wrapper for mprotect. This function merely records
185 whatever it is told. If the returned Bool is True, the caller
186 should immediately discard translations from the specified address
188 extern Bool VG_(am_notify_mprotect)( Addr start, SizeT len, UInt prot );
190 /* Notifies aspacem that an munmap completed successfully. The
191 segment array is updated accordingly. As with
192 VG_(am_notify_munmap), we merely record the given info, and don't
193 check it for sensibleness. If the returned Bool is True, the
194 caller should immediately discard translations from the specified
196 extern Bool VG_(am_notify_munmap)( Addr start, SizeT len );
198 /* Hand a raw mmap to the kernel, without aspacem updating the segment
199 array. THIS FUNCTION IS DANGEROUS -- it will cause aspacem's view
200 of the address space to diverge from that of the kernel. DO NOT
201 USE IT UNLESS YOU UNDERSTAND the request-notify model used by
202 aspacem. In short, DO NOT USE THIS FUNCTION. */
203 extern SysRes VG_(am_do_mmap_NO_NOTIFY)
204 ( Addr start, SizeT length, UInt prot, UInt flags, Int fd, Off64T offset);
207 //--------------------------------------------------------------
208 // Functions pertaining to AIX5-specific notifications.
210 /* Describes followup actions that need to be done following a call to
211 VG_(am_aix5_reread_procmap). When acquire==True, the specified
212 code and data segments have been mapped into the process, and so
213 m_debuginfo needs to read info for it; also m_redir needs to know,
214 and the tool needs to be told. When acquire==False, the specified
215 segments have been unloaded and m_debuginfo, m_redir and the tool
216 (and m_transtab?) need to notified appropriately. */
230 /* Tell aspacem that /proc/<pid>/map may have changed (eg following
231 __loadx) and so it should be re-read, and the code/data segment
232 list updated accordingly. The resulting array of AixCodeChangeSeg
233 directives are written to 'directives', and the number of entries
235 extern void VG_(am_aix5_reread_procmap)
236 ( /*OUT*/AixCodeSegChange* directives, /*OUT*/Int* ndirectives );
238 /* Find out the size of the AixCodeSegChange that must be
239 presented to VG_(am_aix5_reread_procmap). */
240 extern Int VG_(am_aix5_reread_procmap_howmany_directives)(void);
242 /* Tell aspacem where the initial client stack is, so that it
243 can later produce a faked-up NSegment in response to
244 VG_(am_find_nsegment) for athat address, if asked. */
245 extern void VG_(am_aix5_set_initial_client_sp)( Addr );
247 /* The AIX5 aspacem implementation needs to be told when it is and
248 isn't allowed to use sbrk to allocate memory. Hence: */
249 extern Bool VG_(am_aix5_sbrk_allowed);
252 //--------------------------------------------------------------
253 // Dealing with mappings which do not arise directly from the
254 // simulation of the client. These are typically used for
255 // loading the client and building its stack/data segment, before
256 // execution begins. Also for V's own administrative use.
258 /* --- --- --- map, unmap, protect --- --- --- */
260 /* Map a file at a fixed address for the client, and update the
261 segment array accordingly. */
262 extern SysRes VG_(am_mmap_file_fixed_client)
263 ( Addr start, SizeT length, UInt prot, Int fd, Off64T offset );
264 extern SysRes VG_(am_mmap_named_file_fixed_client)
265 ( Addr start, SizeT length, UInt prot, Int fd, Off64T offset, const HChar *name );
267 /* Map anonymously at a fixed address for the client, and update
268 the segment array accordingly. */
269 extern SysRes VG_(am_mmap_anon_fixed_client)
270 ( Addr start, SizeT length, UInt prot );
273 /* Map anonymously at an unconstrained address for the client, and
274 update the segment array accordingly. */
275 extern SysRes VG_(am_mmap_anon_float_client) ( SizeT length, Int prot );
277 /* Similarly, acquire new address space for the client but with
278 considerable restrictions on what can be done with it: (1) the
279 actual protections may exceed those stated in 'prot', (2) the
280 area's protections cannot be later changed using any form of
281 mprotect, and (3) the area cannot be freed using any form of
282 munmap. On Linux this behaves the same as
283 VG_(am_mmap_anon_float_client). On AIX5 this *may* allocate memory
284 by using sbrk, so as to make use of large pages on AIX. */
285 extern SysRes VG_(am_sbrk_anon_float_client) ( SizeT length, Int prot );
288 /* Map anonymously at an unconstrained address for V, and update the
289 segment array accordingly. This is fundamentally how V allocates
290 itself more address space when needed. */
291 extern SysRes VG_(am_mmap_anon_float_valgrind)( SizeT cszB );
293 /* Same comments apply as per VG_(am_sbrk_anon_float_client). On
294 Linux this behaves the same as VG_(am_mmap_anon_float_valgrind). */
295 extern SysRes VG_(am_sbrk_anon_float_valgrind)( SizeT cszB );
298 /* Map privately a file at an unconstrained address for V, and update the
299 segment array accordingly. This is used by V for transiently
300 mapping in object files to read their debug info. */
301 extern SysRes VG_(am_mmap_file_float_valgrind)
302 ( SizeT length, UInt prot, Int fd, Off64T offset );
304 /* Map shared a file at an unconstrained address for V, and update the
305 segment array accordingly. This is used by V for communicating
307 extern SysRes VG_(am_shared_mmap_file_float_valgrind)
308 ( SizeT length, UInt prot, Int fd, Off64T offset );
310 /* Unmap the given address range and update the segment array
311 accordingly. This fails if the range isn't valid for the client.
312 If *need_discard is True after a successful return, the caller
313 should immediately discard translations from the specified address
315 extern SysRes VG_(am_munmap_client)( /*OUT*/Bool* need_discard,
316 Addr start, SizeT length );
318 /* Let (start,len) denote an area within a single Valgrind-owned
319 segment (anon or file). Change the ownership of [start, start+len)
320 to the client instead. Fails if (start,len) does not denote a
322 extern Bool VG_(am_change_ownership_v_to_c)( Addr start, SizeT len );
324 /* 'seg' must be NULL or have been obtained from
325 VG_(am_find_nsegment), and still valid. If non-NULL, and if it
326 denotes a SkAnonC (anonymous client mapping) area, set the .isCH
327 (is-client-heap) flag for that area. Otherwise do nothing.
328 (Bizarre interface so that the same code works for both Linux and
329 AIX and does not impose inefficiencies on the Linux version.) */
330 extern void VG_(am_set_segment_isCH_if_SkAnonC)( NSegment* seg );
332 /* Same idea as VG_(am_set_segment_isCH_if_SkAnonC), except set the
333 segment's hasT bit (has-cached-code) if this is SkFileC or SkAnonC
335 extern void VG_(am_set_segment_hasT_if_SkFileC_or_SkAnonC)( NSegment* );
337 /* --- --- --- reservations --- --- --- */
339 /* Create a reservation from START .. START+LENGTH-1, with the given
340 ShrinkMode. When checking whether the reservation can be created,
341 also ensure that at least abs(EXTRA) extra free bytes will remain
342 above (> 0) or below (< 0) the reservation.
344 The reservation will only be created if it, plus the extra-zone,
345 falls entirely within a single free segment. The returned Bool
346 indicates whether the creation succeeded. */
347 extern Bool VG_(am_create_reservation)
348 ( Addr start, SizeT length, ShrinkMode smode, SSizeT extra );
350 /* Let SEG be an anonymous client mapping. This fn extends the
351 mapping by DELTA bytes, taking the space from a reservation section
352 which must be adjacent. If DELTA is positive, the segment is
353 extended forwards in the address space, and the reservation must be
354 the next one along. If DELTA is negative, the segment is extended
355 backwards in the address space and the reservation must be the
356 previous one. DELTA must be page aligned. abs(DELTA) must not
357 exceed the size of the reservation segment minus one page, that is,
358 the reservation segment after the operation must be at least one
360 extern Bool VG_(am_extend_into_adjacent_reservation_client)
361 ( NSegment* seg, SSizeT delta );
363 /* --- --- --- resizing/move a mapping --- --- --- */
365 /* Let SEG be a client mapping (anonymous or file). This fn extends
366 the mapping forwards only by DELTA bytes, and trashes whatever was
367 in the new area. Fails if SEG is not a single client mapping or if
368 the new area is not accessible to the client. Fails if DELTA is
369 not page aligned. *seg is invalid after a successful return. If
370 *need_discard is True after a successful return, the caller should
371 immediately discard translations from the new area. */
372 extern Bool VG_(am_extend_map_client)( /*OUT*/Bool* need_discard,
373 NSegment* seg, SizeT delta );
375 /* Remap the old address range to the new address range. Fails if any
376 parameter is not page aligned, if the either size is zero, if any
377 wraparound is implied, if the old address range does not fall
378 entirely within a single segment, if the new address range overlaps
379 with the old one, or if the old address range is not a valid client
380 mapping. If *need_discard is True after a successful return, the
381 caller should immediately discard translations from both specified
383 extern Bool VG_(am_relocate_nooverlap_client)( /*OUT*/Bool* need_discard,
384 Addr old_addr, SizeT old_len,
385 Addr new_addr, SizeT new_len );
387 //--------------------------------------------------------------
388 // Valgrind (non-client) thread stacks. V itself runs on such
389 // stacks. The address space manager provides and suitably
390 // protects such stacks.
392 #if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
393 # define VG_STACK_GUARD_SZB 65536 // 1 or 16 pages
394 # define VG_STACK_ACTIVE_SZB (4096 * 256) // 1Mb
396 # define VG_STACK_GUARD_SZB 8192 // 2 pages
397 # define VG_STACK_ACTIVE_SZB (4096 * 256) // 1Mb
402 HChar bytes[VG_STACK_GUARD_SZB
403 + VG_STACK_ACTIVE_SZB
404 + VG_STACK_GUARD_SZB];
409 /* Allocate and initialise a VgStack (anonymous client space).
410 Protect the stack active area and the guard areas appropriately.
411 Returns NULL on failure, else the address of the bottom of the
412 stack. On success, also sets *initial_sp to what the stack pointer
415 extern VgStack* VG_(am_alloc_VgStack)( /*OUT*/Addr* initial_sp );
417 /* Figure out how many bytes of the stack's active area have not been
418 used. Used for estimating if we are close to overflowing it. If
419 the free area is larger than 'limit', just return 'limit'. */
420 extern SizeT VG_(am_get_VgStack_unused_szB)( VgStack* stack, SizeT limit );
423 #if defined(VGO_darwin)
426 Bool is_added; // Added or removed seg?
429 UInt prot; // Not used for removed segs.
430 Off64T offset; // Not used for removed segs.
434 extern Bool VG_(get_changed_segments)(
435 const HChar* when, const HChar* where, /*OUT*/ChangedSeg* css,
436 Int css_size, /*OUT*/Int* css_used);
439 #endif // __PUB_CORE_ASPACEMGR_H
441 /*--------------------------------------------------------------------*/
443 /*--------------------------------------------------------------------*/