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-2013 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) ( const NSegment* here,
77                                               Bool fwds );
78
79/* Is the area [start .. start+len-1] validly accessible by the
80   client with at least the permissions 'prot' ?  To find out
81   simply if said area merely belongs to the client, pass
82   VKI_PROT_NONE as 'prot'.  Will return False if any part of the
83   area does not belong to the client or does not have at least
84   the stated permissions. */
85// Is in tool-visible header file.
86// extern Bool VG_(am_is_valid_for_client)
87//   ( Addr start, SizeT len, UInt prot );
88
89/* Same as VG_(am_is_valid_for_client) but for valgrind :
90   test if memory is addressable by valgrind with at least
91   the protection 'prot'. */
92extern Bool VG_(am_is_valid_for_valgrind)
93   ( Addr start, SizeT len, UInt prot );
94
95/* Variant of VG_(am_is_valid_for_client) which allows free areas to
96   be consider part of the client's addressable space.  It also
97   considers reservations to be allowable, since from the client's
98   point of view they don't exist. */
99extern Bool VG_(am_is_valid_for_client_or_free_or_resvn)
100   ( Addr start, SizeT len, UInt prot );
101
102/* Trivial fn: return the total amount of space in anonymous mappings,
103   both for V and the client.  Is used for printing stats in
104   out-of-memory messages. */
105extern ULong VG_(am_get_anonsize_total)( void );
106
107/* Show the segment array on the debug log, at given loglevel. */
108extern void VG_(am_show_nsegments) ( Int logLevel, const HChar* who );
109
110/* Get the filename corresponding to this segment, if known and if it
111   has one.  The returned name's storage cannot be assumed to be
112   persistent, so the caller should immediately copy the name
113   elsewhere.  This may return NULL if the file name is not known or
114   for arbitrary other implementation-dependent reasons, so callers
115   need to be able to handle a NULL return value. */
116// Is in tool-visible header file.
117// extern HChar* VG_(am_get_filename)( NSegment* );
118
119/* VG_(am_get_segment_starts) is also part of this section, but its
120   prototype is tool-visible, hence not in this header file. */
121
122/* Sanity check: check that Valgrind and the kernel agree on the
123   address space layout.  Prints offending segments and call point if
124   a discrepancy is detected, but does not abort the system.  Returned
125   Bool is False if a discrepancy was found. */
126
127extern Bool VG_(am_do_sync_check) ( const HChar* fn,
128                                    const HChar* file, Int line );
129
130//--------------------------------------------------------------
131// Functions pertaining to the central query-notify mechanism
132// used to handle mmap/munmap/mprotect resulting from client
133// syscalls.
134
135/* Describes a request for VG_(am_get_advisory). */
136typedef
137   struct {
138      enum { MFixed, MHint, MAny } rkind;
139      Addr start;
140      Addr len;
141   }
142   MapRequest;
143
144/* Query aspacem to ask where a mapping should go.  On success, the
145   advised placement is returned, and *ok is set to True.  On failure,
146   zero is returned and *ok is set to False.  Note that *ok must be
147   consulted by the caller to establish success or failure; that
148   cannot be established reliably from the returned value.  If *ok is
149   set to False, it means aspacem has vetoed the mapping, and so the
150   caller should not proceed with it. */
151extern Addr VG_(am_get_advisory)
152   ( MapRequest* req, Bool forClient, /*OUT*/Bool* ok );
153
154/* Convenience wrapper for VG_(am_get_advisory) for client floating or
155   fixed requests.  If start is zero, a floating request is issued; if
156   nonzero, a fixed request at that address is issued.  Same comments
157   about return values apply. */
158extern Addr VG_(am_get_advisory_client_simple)
159   ( Addr start, SizeT len, /*OUT*/Bool* ok );
160
161/* Returns True if [start, start + len - 1] is covered by a single
162   free segment, otherwise returns False.
163   This allows to check the following case:
164   VG_(am_get_advisory_client_simple) (first arg == 0, meaning
165   this-or-nothing) is too lenient, and may allow us to trash
166   the next segment along.  So make very sure that the proposed
167   new area really is free.  This is perhaps overly
168   conservative, but it fixes #129866. */
169extern Bool VG_(am_covered_by_single_free_segment)
170   ( Addr start, SizeT len);
171
172/* Notifies aspacem that the client completed an mmap successfully.
173   The segment array is updated accordingly.  If the returned Bool is
174   True, the caller should immediately discard translations from the
175   specified address range. */
176extern Bool VG_(am_notify_client_mmap)
177   ( Addr a, SizeT len, UInt prot, UInt flags, Int fd, Off64T offset );
178
179/* Notifies aspacem that the client completed a shmat successfully.
180   The segment array is updated accordingly.  If the returned Bool is
181   True, the caller should immediately discard translations from the
182   specified address range. */
183extern Bool VG_(am_notify_client_shmat)( Addr a, SizeT len, UInt prot );
184
185/* Notifies aspacem that an mprotect was completed successfully.  The
186   segment array is updated accordingly.  Note, as with
187   VG_(am_notify_munmap), it is not the job of this function to reject
188   stupid mprotects, for example the client doing mprotect of
189   non-client areas.  Such requests should be intercepted earlier, by
190   the syscall wrapper for mprotect.  This function merely records
191   whatever it is told.  If the returned Bool is True, the caller
192   should immediately discard translations from the specified address
193   range. */
194extern Bool VG_(am_notify_mprotect)( Addr start, SizeT len, UInt prot );
195
196/* Notifies aspacem that an munmap completed successfully.  The
197   segment array is updated accordingly.  As with
198   VG_(am_notify_munmap), we merely record the given info, and don't
199   check it for sensibleness.  If the returned Bool is True, the
200   caller should immediately discard translations from the specified
201   address range. */
202extern Bool VG_(am_notify_munmap)( Addr start, SizeT len );
203
204/* Hand a raw mmap to the kernel, without aspacem updating the segment
205   array.  THIS FUNCTION IS DANGEROUS -- it will cause aspacem's view
206   of the address space to diverge from that of the kernel.  DO NOT
207   USE IT UNLESS YOU UNDERSTAND the request-notify model used by
208   aspacem.  In short, DO NOT USE THIS FUNCTION. */
209extern SysRes VG_(am_do_mmap_NO_NOTIFY)
210   ( Addr start, SizeT length, UInt prot, UInt flags, Int fd, Off64T offset);
211
212
213//--------------------------------------------------------------
214// Dealing with mappings which do not arise directly from the
215// simulation of the client.  These are typically used for
216// loading the client and building its stack/data segment, before
217// execution begins.  Also for V's own administrative use.
218
219/* --- --- --- map, unmap, protect  --- --- --- */
220
221/* Map a file at a fixed address for the client, and update the
222   segment array accordingly. */
223extern SysRes VG_(am_mmap_file_fixed_client)
224   ( Addr start, SizeT length, UInt prot, Int fd, Off64T offset );
225extern SysRes VG_(am_mmap_named_file_fixed_client)
226   ( Addr start, SizeT length, UInt prot, Int fd, Off64T offset, const HChar *name );
227
228/* Map anonymously at a fixed address for the client, and update
229   the segment array accordingly. */
230extern SysRes VG_(am_mmap_anon_fixed_client)
231   ( Addr start, SizeT length, UInt prot );
232
233
234/* Map anonymously at an unconstrained address for the client, and
235   update the segment array accordingly.  */
236extern SysRes VG_(am_mmap_anon_float_client) ( SizeT length, Int prot );
237
238/* Map anonymously at an unconstrained address for V, and update the
239   segment array accordingly.  This is fundamentally how V allocates
240   itself more address space when needed. */
241extern SysRes VG_(am_mmap_anon_float_valgrind)( SizeT cszB );
242
243/* Map privately a file at an unconstrained address for V, and update the
244   segment array accordingly.  This is used by V for transiently
245   mapping in object files to read their debug info.  */
246extern SysRes VG_(am_mmap_file_float_valgrind)
247   ( SizeT length, UInt prot, Int fd, Off64T offset );
248
249/* Map shared a file at an unconstrained address for V, and update the
250   segment array accordingly.  This is used by V for communicating
251   with vgdb.  */
252extern SysRes VG_(am_shared_mmap_file_float_valgrind)
253   ( SizeT length, UInt prot, Int fd, Off64T offset );
254
255/* Unmap the given address range and update the segment array
256   accordingly.  This fails if the range isn't valid for the client.
257   If *need_discard is True after a successful return, the caller
258   should immediately discard translations from the specified address
259   range. */
260extern SysRes VG_(am_munmap_client)( /*OUT*/Bool* need_discard,
261                                     Addr start, SizeT length );
262
263/* Let (start,len) denote an area within a single Valgrind-owned
264  segment (anon or file).  Change the ownership of [start, start+len)
265  to the client instead.  Fails if (start,len) does not denote a
266  suitable segment. */
267extern Bool VG_(am_change_ownership_v_to_c)( Addr start, SizeT len );
268
269/* 'seg' must be NULL or have been obtained from
270   VG_(am_find_nsegment), and still valid.  If non-NULL, and if it
271   denotes a SkAnonC (anonymous client mapping) area, set the .isCH
272   (is-client-heap) flag for that area.  Otherwise do nothing.
273   (Bizarre interface so that the same code works for both Linux and
274   AIX and does not impose inefficiencies on the Linux version.) */
275extern void VG_(am_set_segment_isCH_if_SkAnonC)( const NSegment* seg );
276
277/* Same idea as VG_(am_set_segment_isCH_if_SkAnonC), except set the
278   segment's hasT bit (has-cached-code) if this is SkFileC or SkAnonC
279   segment. */
280extern void VG_(am_set_segment_hasT_if_SkFileC_or_SkAnonC)( const NSegment* );
281
282/* --- --- --- reservations --- --- --- */
283
284/* Create a reservation from START .. START+LENGTH-1, with the given
285   ShrinkMode.  When checking whether the reservation can be created,
286   also ensure that at least abs(EXTRA) extra free bytes will remain
287   above (> 0) or below (< 0) the reservation.
288
289   The reservation will only be created if it, plus the extra-zone,
290   falls entirely within a single free segment.  The returned Bool
291   indicates whether the creation succeeded. */
292extern Bool VG_(am_create_reservation)
293   ( Addr start, SizeT length, ShrinkMode smode, SSizeT extra );
294
295/* Let SEG be an anonymous client mapping.  This fn extends the
296   mapping by DELTA bytes, taking the space from a reservation section
297   which must be adjacent.  If DELTA is positive, the segment is
298   extended forwards in the address space, and the reservation must be
299   the next one along.  If DELTA is negative, the segment is extended
300   backwards in the address space and the reservation must be the
301   previous one.  DELTA must be page aligned.  abs(DELTA) must not
302   exceed the size of the reservation segment minus one page, that is,
303   the reservation segment after the operation must be at least one
304   page long. */
305extern Bool VG_(am_extend_into_adjacent_reservation_client)
306   ( const NSegment* seg, SSizeT delta );
307
308/* --- --- --- resizing/move a mapping --- --- --- */
309
310/* Let SEG be a client mapping (anonymous or file).  This fn extends
311   the mapping forwards only by DELTA bytes, and trashes whatever was
312   in the new area.  Fails if SEG is not a single client mapping or if
313   the new area is not accessible to the client.  Fails if DELTA is
314   not page aligned.  *seg is invalid after a successful return.  If
315   *need_discard is True after a successful return, the caller should
316   immediately discard translations from the new area. */
317extern Bool VG_(am_extend_map_client)( /*OUT*/Bool* need_discard,
318                                       const NSegment* seg, SizeT delta );
319
320/* Remap the old address range to the new address range.  Fails if any
321   parameter is not page aligned, if the either size is zero, if any
322   wraparound is implied, if the old address range does not fall
323   entirely within a single segment, if the new address range overlaps
324   with the old one, or if the old address range is not a valid client
325   mapping.  If *need_discard is True after a successful return, the
326   caller should immediately discard translations from both specified
327   address ranges.  */
328extern Bool VG_(am_relocate_nooverlap_client)( /*OUT*/Bool* need_discard,
329                                               Addr old_addr, SizeT old_len,
330                                               Addr new_addr, SizeT new_len );
331
332//--------------------------------------------------------------
333// Valgrind (non-client) thread stacks.  V itself runs on such
334// stacks.  The address space manager provides and suitably
335// protects such stacks.
336
337#if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) \
338    || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
339    || defined(VGP_arm64_linux)
340# define VG_STACK_GUARD_SZB  65536  // 1 or 16 pages
341# define VG_STACK_ACTIVE_SZB (4096 * 256) // 1Mb
342#else
343# define VG_STACK_GUARD_SZB  8192   // 2 pages
344# define VG_STACK_ACTIVE_SZB (4096 * 256) // 1Mb
345#endif
346
347typedef
348   struct {
349      HChar bytes[VG_STACK_GUARD_SZB
350                  + VG_STACK_ACTIVE_SZB
351                  + VG_STACK_GUARD_SZB];
352   }
353   VgStack;
354
355
356/* Allocate and initialise a VgStack (anonymous valgrind space).
357   Protect the stack active area and the guard areas appropriately.
358   Returns NULL on failure, else the address of the bottom of the
359   stack.  On success, also sets *initial_sp to what the stack pointer
360   should be set to. */
361
362extern VgStack* VG_(am_alloc_VgStack)( /*OUT*/Addr* initial_sp );
363
364/* Figure out how many bytes of the stack's active area have not been
365   used.  Used for estimating if we are close to overflowing it.  If
366   the free area is larger than 'limit', just return 'limit'. */
367extern SizeT VG_(am_get_VgStack_unused_szB)( VgStack* stack, SizeT limit );
368
369// DDD: this is ugly
370#if defined(VGO_darwin)
371typedef
372   struct {
373      Bool   is_added;  // Added or removed seg?
374      Addr   start;
375      SizeT  end;
376      UInt   prot;      // Not used for removed segs.
377      Off64T offset;    // Not used for removed segs.
378   }
379   ChangedSeg;
380
381extern Bool VG_(get_changed_segments)(
382      const HChar* when, const HChar* where, /*OUT*/ChangedSeg* css,
383      Int css_size, /*OUT*/Int* css_used);
384#endif
385
386#endif   // __PUB_CORE_ASPACEMGR_H
387
388/*--------------------------------------------------------------------*/
389/*--- end                                                          ---*/
390/*--------------------------------------------------------------------*/
391