1
2/*--------------------------------------------------------------------*/
3/*--- The address space manager.              pub_core_aspacemgr.h ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7   This file is part of Valgrind, a dynamic binary instrumentation
8   framework.
9
10   Copyright (C) 2000-2011 Julian Seward
11      jseward@acm.org
12
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.
17
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.
22
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
26   02111-1307, USA.
27
28   The GNU General Public License is contained in the file COPYING.
29*/
30
31#ifndef __PUB_CORE_ASPACEMGR_H
32#define __PUB_CORE_ASPACEMGR_H
33
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
39// THIS.
40//--------------------------------------------------------------------
41
42#include "pub_tool_aspacemgr.h"
43
44//--------------------------------------------------------------
45// Definition of address-space segments
46
47/* types SegKind, ShrinkMode and NSegment are described in
48   the tool-visible header file, not here. */
49
50
51//--------------------------------------------------------------
52// Initialisation
53
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.
57
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. */
62extern Addr VG_(am_startup) ( Addr sp_at_startup );
63
64
65//--------------------------------------------------------------
66// Querying current status
67
68/* Finds the segment containing 'a'.  Only returns file/anon/resvn
69   segments.  This returns a 'NSegment const *' - a pointer to
70   readonly data. */
71// Is in tool-visible header file.
72// extern NSegment const * VG_(am_find_nsegment) ( Addr a );
73
74/* Find the next segment along from 'here', if it is a file/anon/resvn
75   segment. */
76extern NSegment const* VG_(am_next_nsegment) ( NSegment* here, Bool fwds );
77
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 );
87
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. */
92extern Bool VG_(am_is_valid_for_client_or_free_or_resvn)
93   ( Addr start, SizeT len, UInt prot );
94
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. */
98extern ULong VG_(am_get_anonsize_total)( void );
99
100/* Show the segment array on the debug log, at given loglevel. */
101extern void VG_(am_show_nsegments) ( Int logLevel, HChar* who );
102
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* );
111
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. */
114
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. */
119
120extern Bool VG_(am_do_sync_check) ( const HChar* fn,
121                                    const HChar* file, Int line );
122
123//--------------------------------------------------------------
124// Functions pertaining to the central query-notify mechanism
125// used to handle mmap/munmap/mprotect resulting from client
126// syscalls.
127
128/* Describes a request for VG_(am_get_advisory). */
129typedef
130   struct {
131      enum { MFixed, MHint, MAny } rkind;
132      Addr start;
133      Addr len;
134   }
135   MapRequest;
136
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. */
144extern Addr VG_(am_get_advisory)
145   ( MapRequest* req, Bool forClient, /*OUT*/Bool* ok );
146
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. */
151extern Addr VG_(am_get_advisory_client_simple)
152   ( Addr start, SizeT len, /*OUT*/Bool* ok );
153
154/* Notifies aspacem that the client completed an mmap successfully.
155   The segment array is updated accordingly.  If the returned Bool is
156   True, the caller should immediately discard translations from the
157   specified address range. */
158extern Bool VG_(am_notify_client_mmap)
159   ( Addr a, SizeT len, UInt prot, UInt flags, Int fd, Off64T offset );
160
161extern Bool VG_(am_notify_fake_client_mmap)
162   ( Addr a, SizeT len, UInt prot, UInt flags, HChar* fileName, Off64T offset );
163
164/* Notifies aspacem that the client completed a shmat 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. */
168extern Bool VG_(am_notify_client_shmat)( Addr a, SizeT len, UInt prot );
169
170/* Notifies aspacem that an mprotect was completed successfully.  The
171   segment array is updated accordingly.  Note, as with
172   VG_(am_notify_munmap), it is not the job of this function to reject
173   stupid mprotects, for example the client doing mprotect of
174   non-client areas.  Such requests should be intercepted earlier, by
175   the syscall wrapper for mprotect.  This function merely records
176   whatever it is told.  If the returned Bool is True, the caller
177   should immediately discard translations from the specified address
178   range. */
179extern Bool VG_(am_notify_mprotect)( Addr start, SizeT len, UInt prot );
180
181/* Notifies aspacem that an munmap completed successfully.  The
182   segment array is updated accordingly.  As with
183   VG_(am_notify_munmap), we merely record the given info, and don't
184   check it for sensibleness.  If the returned Bool is True, the
185   caller should immediately discard translations from the specified
186   address range. */
187extern Bool VG_(am_notify_munmap)( Addr start, SizeT len );
188
189/* Hand a raw mmap to the kernel, without aspacem updating the segment
190   array.  THIS FUNCTION IS DANGEROUS -- it will cause aspacem's view
191   of the address space to diverge from that of the kernel.  DO NOT
192   USE IT UNLESS YOU UNDERSTAND the request-notify model used by
193   aspacem.  In short, DO NOT USE THIS FUNCTION. */
194extern SysRes VG_(am_do_mmap_NO_NOTIFY)
195   ( Addr start, SizeT length, UInt prot, UInt flags, Int fd, Off64T offset);
196
197
198//--------------------------------------------------------------
199// Dealing with mappings which do not arise directly from the
200// simulation of the client.  These are typically used for
201// loading the client and building its stack/data segment, before
202// execution begins.  Also for V's own administrative use.
203
204/* --- --- --- map, unmap, protect  --- --- --- */
205
206/* Map a file at a fixed address for the client, and update the
207   segment array accordingly. */
208extern SysRes VG_(am_mmap_file_fixed_client)
209   ( Addr start, SizeT length, UInt prot, Int fd, Off64T offset );
210extern SysRes VG_(am_mmap_named_file_fixed_client)
211   ( Addr start, SizeT length, UInt prot, Int fd, Off64T offset, const HChar *name );
212
213/* Map anonymously at a fixed address for the client, and update
214   the segment array accordingly. */
215extern SysRes VG_(am_mmap_anon_fixed_client)
216   ( Addr start, SizeT length, UInt prot );
217
218
219/* Map anonymously at an unconstrained address for the client, and
220   update the segment array accordingly.  */
221extern SysRes VG_(am_mmap_anon_float_client) ( SizeT length, Int prot );
222
223/* Similarly, acquire new address space for the client but with
224   considerable restrictions on what can be done with it: (1) the
225   actual protections may exceed those stated in 'prot', (2) the
226   area's protections cannot be later changed using any form of
227   mprotect, and (3) the area cannot be freed using any form of
228   munmap.  On Linux this behaves the same as
229   VG_(am_mmap_anon_float_client).  On AIX5 this *may* allocate memory
230   by using sbrk, so as to make use of large pages on AIX. */
231extern SysRes VG_(am_sbrk_anon_float_client) ( SizeT length, Int prot );
232
233
234/* Map anonymously at an unconstrained address for V, and update the
235   segment array accordingly.  This is fundamentally how V allocates
236   itself more address space when needed. */
237extern SysRes VG_(am_mmap_anon_float_valgrind)( SizeT cszB );
238
239/* Same comments apply as per VG_(am_sbrk_anon_float_client).  On
240   Linux this behaves the same as VG_(am_mmap_anon_float_valgrind). */
241extern SysRes VG_(am_sbrk_anon_float_valgrind)( SizeT cszB );
242
243
244/* Map privately a file at an unconstrained address for V, and update the
245   segment array accordingly.  This is used by V for transiently
246   mapping in object files to read their debug info.  */
247extern SysRes VG_(am_mmap_file_float_valgrind)
248   ( SizeT length, UInt prot, Int fd, Off64T offset );
249extern SysRes VG_(am_mmap_file_float_valgrind_flags)
250   ( SizeT length, UInt prot, UInt flags, Int fd, Off64T offset );
251
252/* Map shared a file at an unconstrained address for V, and update the
253   segment array accordingly.  This is used by V for communicating
254   with vgdb.  */
255extern SysRes VG_(am_shared_mmap_file_float_valgrind)
256   ( SizeT length, UInt prot, Int fd, Off64T offset );
257
258/* Unmap the given address range and update the segment array
259   accordingly.  This fails if the range isn't valid for the client.
260   If *need_discard is True after a successful return, the caller
261   should immediately discard translations from the specified address
262   range. */
263extern SysRes VG_(am_munmap_client)( /*OUT*/Bool* need_discard,
264                                     Addr start, SizeT length );
265
266/* Let (start,len) denote an area within a single Valgrind-owned
267  segment (anon or file).  Change the ownership of [start, start+len)
268  to the client instead.  Fails if (start,len) does not denote a
269  suitable segment. */
270extern Bool VG_(am_change_ownership_v_to_c)( Addr start, SizeT len );
271
272/* 'seg' must be NULL or have been obtained from
273   VG_(am_find_nsegment), and still valid.  If non-NULL, and if it
274   denotes a SkAnonC (anonymous client mapping) area, set the .isCH
275   (is-client-heap) flag for that area.  Otherwise do nothing.
276   (Bizarre interface so that the same code works for both Linux and
277   AIX and does not impose inefficiencies on the Linux version.) */
278extern void VG_(am_set_segment_isCH_if_SkAnonC)( NSegment* seg );
279
280/* Same idea as VG_(am_set_segment_isCH_if_SkAnonC), except set the
281   segment's hasT bit (has-cached-code) if this is SkFileC or SkAnonC
282   segment. */
283extern void VG_(am_set_segment_hasT_if_SkFileC_or_SkAnonC)( NSegment* );
284
285/* --- --- --- reservations --- --- --- */
286
287/* Create a reservation from START .. START+LENGTH-1, with the given
288   ShrinkMode.  When checking whether the reservation can be created,
289   also ensure that at least abs(EXTRA) extra free bytes will remain
290   above (> 0) or below (< 0) the reservation.
291
292   The reservation will only be created if it, plus the extra-zone,
293   falls entirely within a single free segment.  The returned Bool
294   indicates whether the creation succeeded. */
295extern Bool VG_(am_create_reservation)
296   ( Addr start, SizeT length, ShrinkMode smode, SSizeT extra );
297
298/* Let SEG be an anonymous client mapping.  This fn extends the
299   mapping by DELTA bytes, taking the space from a reservation section
300   which must be adjacent.  If DELTA is positive, the segment is
301   extended forwards in the address space, and the reservation must be
302   the next one along.  If DELTA is negative, the segment is extended
303   backwards in the address space and the reservation must be the
304   previous one.  DELTA must be page aligned.  abs(DELTA) must not
305   exceed the size of the reservation segment minus one page, that is,
306   the reservation segment after the operation must be at least one
307   page long. */
308extern Bool VG_(am_extend_into_adjacent_reservation_client)
309   ( NSegment* seg, SSizeT delta );
310
311/* --- --- --- resizing/move a mapping --- --- --- */
312
313/* Let SEG be a client mapping (anonymous or file).  This fn extends
314   the mapping forwards only by DELTA bytes, and trashes whatever was
315   in the new area.  Fails if SEG is not a single client mapping or if
316   the new area is not accessible to the client.  Fails if DELTA is
317   not page aligned.  *seg is invalid after a successful return.  If
318   *need_discard is True after a successful return, the caller should
319   immediately discard translations from the new area. */
320extern Bool VG_(am_extend_map_client)( /*OUT*/Bool* need_discard,
321                                       NSegment* seg, SizeT delta );
322
323/* Remap the old address range to the new address range.  Fails if any
324   parameter is not page aligned, if the either size is zero, if any
325   wraparound is implied, if the old address range does not fall
326   entirely within a single segment, if the new address range overlaps
327   with the old one, or if the old address range is not a valid client
328   mapping.  If *need_discard is True after a successful return, the
329   caller should immediately discard translations from both specified
330   address ranges.  */
331extern Bool VG_(am_relocate_nooverlap_client)( /*OUT*/Bool* need_discard,
332                                               Addr old_addr, SizeT old_len,
333                                               Addr new_addr, SizeT new_len );
334
335//--------------------------------------------------------------
336// Valgrind (non-client) thread stacks.  V itself runs on such
337// stacks.  The address space manager provides and suitably
338// protects such stacks.
339
340#if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
341# define VG_STACK_GUARD_SZB  65536  // 1 or 16 pages
342# define VG_STACK_ACTIVE_SZB (4096 * 256) // 1Mb
343#else
344# define VG_STACK_GUARD_SZB  8192   // 2 pages
345# define VG_STACK_ACTIVE_SZB (4096 * 256) // 1Mb
346#endif
347
348typedef
349   struct {
350      HChar bytes[VG_STACK_GUARD_SZB
351                  + VG_STACK_ACTIVE_SZB
352                  + VG_STACK_GUARD_SZB];
353   }
354   VgStack;
355
356
357/* Allocate and initialise a VgStack (anonymous client space).
358   Protect the stack active area and the guard areas appropriately.
359   Returns NULL on failure, else the address of the bottom of the
360   stack.  On success, also sets *initial_sp to what the stack pointer
361   should be set to. */
362
363extern VgStack* VG_(am_alloc_VgStack)( /*OUT*/Addr* initial_sp );
364
365/* Figure out how many bytes of the stack's active area have not been
366   used.  Used for estimating if we are close to overflowing it.  If
367   the free area is larger than 'limit', just return 'limit'. */
368extern SizeT VG_(am_get_VgStack_unused_szB)( VgStack* stack, SizeT limit );
369
370// DDD: this is ugly
371#if defined(VGO_darwin)
372typedef
373   struct {
374      Bool   is_added;  // Added or removed seg?
375      Addr   start;
376      SizeT  end;
377      UInt   prot;      // Not used for removed segs.
378      Off64T offset;    // Not used for removed segs.
379   }
380   ChangedSeg;
381
382extern Bool VG_(get_changed_segments)(
383      const HChar* when, const HChar* where, /*OUT*/ChangedSeg* css,
384      Int css_size, /*OUT*/Int* css_used);
385#endif
386
387#endif   // __PUB_CORE_ASPACEMGR_H
388
389/*--------------------------------------------------------------------*/
390/*--- end                                                          ---*/
391/*--------------------------------------------------------------------*/
392