blob: 67ec52825eb55dce9c6b5f441d04c91b63fdca66 [file] [log] [blame]
sewardj55f9d1a2005-04-25 11:11:44 +00001
2/*--------------------------------------------------------------------*/
njn43b9a8a2005-05-10 04:37:01 +00003/*--- The address space manager. pub_core_aspacemgr.h ---*/
sewardj55f9d1a2005-04-25 11:11:44 +00004/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
Elliott Hughesed398002017-06-21 14:41:24 -070010 Copyright (C) 2000-2017 Julian Seward
sewardj55f9d1a2005-04-25 11:11:44 +000011 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
njn4802b382005-06-11 04:58:29 +000042#include "pub_tool_aspacemgr.h"
sewardj55f9d1a2005-04-25 11:11:44 +000043
sewardj45f4e7c2005-09-27 19:20:21 +000044//--------------------------------------------------------------
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
philippe38a74d22014-08-29 22:53:19 +000061 suggested end address (highest addressable byte) for the client's stack. */
sewardj45f4e7c2005-09-27 19:20:21 +000062extern Addr VG_(am_startup) ( Addr sp_at_startup );
63
florian82e7a542015-03-26 21:55:00 +000064/* Check whether ADDR is OK to be used as aspacem_minAddr. If not, *ERRMSG
65 will be set to identify what's wrong. ERRMSG may be NULL. */
66extern Bool VG_(am_is_valid_for_aspacem_minAddr)( Addr addr,
67 const HChar **errmsg );
sewardj45f4e7c2005-09-27 19:20:21 +000068
69//--------------------------------------------------------------
70// Querying current status
71
sewardj45f4e7c2005-09-27 19:20:21 +000072
sewardj8eb8bab2015-07-21 14:44:28 +000073/* Finds an anonymous segment containing 'a'. Returned pointer is read only. */
74extern NSegment const *VG_(am_find_anon_segment) ( Addr a );
75
sewardj45f4e7c2005-09-27 19:20:21 +000076/* Find the next segment along from 'here', if it is a file/anon/resvn
77 segment. */
florian3e798632012-11-24 19:41:54 +000078extern NSegment const* VG_(am_next_nsegment) ( const NSegment* here,
79 Bool fwds );
sewardj45f4e7c2005-09-27 19:20:21 +000080
florian67d46032015-01-23 19:55:31 +000081/* Is the area [start .. start+len-1] validly accessible by
82 valgrind with at least the permissions 'prot' ? To find out
83 simply if said area merely belongs to valgrind, pass
sewardj45f4e7c2005-09-27 19:20:21 +000084 VKI_PROT_NONE as 'prot'. Will return False if any part of the
florian67d46032015-01-23 19:55:31 +000085 area does not belong to valgrind or does not have at least
sewardj45f4e7c2005-09-27 19:20:21 +000086 the stated permissions. */
philippeadfff762014-04-20 22:10:24 +000087extern Bool VG_(am_is_valid_for_valgrind)
88 ( Addr start, SizeT len, UInt prot );
89
sewardj45f4e7c2005-09-27 19:20:21 +000090/* Variant of VG_(am_is_valid_for_client) which allows free areas to
91 be consider part of the client's addressable space. It also
92 considers reservations to be allowable, since from the client's
93 point of view they don't exist. */
94extern Bool VG_(am_is_valid_for_client_or_free_or_resvn)
95 ( Addr start, SizeT len, UInt prot );
96
iraisre8b9ee32015-08-31 21:31:09 +000097/* Checks if a piece of memory consists of either free or reservation
98 segments. */
99extern Bool VG_(am_is_free_or_resvn)( Addr start, SizeT len );
100
florian8f3cd172015-04-22 14:16:11 +0000101/* Check whether ADDR looks like an address or address-to-be located in an
102 extensible client stack segment. */
103extern Bool VG_(am_addr_is_in_extensible_client_stack)( Addr addr );
florian017d8f52015-03-23 17:13:04 +0000104
sewardj45f4e7c2005-09-27 19:20:21 +0000105/* Trivial fn: return the total amount of space in anonymous mappings,
106 both for V and the client. Is used for printing stats in
107 out-of-memory messages. */
108extern ULong VG_(am_get_anonsize_total)( void );
109
110/* Show the segment array on the debug log, at given loglevel. */
floriandbb35842012-10-27 18:39:11 +0000111extern void VG_(am_show_nsegments) ( Int logLevel, const HChar* who );
sewardj45f4e7c2005-09-27 19:20:21 +0000112
sewardj45f4e7c2005-09-27 19:20:21 +0000113/* VG_(am_get_segment_starts) is also part of this section, but its
114 prototype is tool-visible, hence not in this header file. */
115
116/* Sanity check: check that Valgrind and the kernel agree on the
117 address space layout. Prints offending segments and call point if
118 a discrepancy is detected, but does not abort the system. Returned
119 Bool is False if a discrepancy was found. */
120
121extern Bool VG_(am_do_sync_check) ( const HChar* fn,
122 const HChar* file, Int line );
123
sewardj45f4e7c2005-09-27 19:20:21 +0000124//--------------------------------------------------------------
125// Functions pertaining to the central query-notify mechanism
126// used to handle mmap/munmap/mprotect resulting from client
127// syscalls.
128
129/* Describes a request for VG_(am_get_advisory). */
130typedef
131 struct {
sewardj8eb8bab2015-07-21 14:44:28 +0000132 /* Note: if rkind == MAlign then start specifies alignment. This is
133 Solaris specific. */
134 enum { MFixed, MHint, MAny, MAlign } rkind;
sewardj45f4e7c2005-09-27 19:20:21 +0000135 Addr start;
136 Addr len;
137 }
138 MapRequest;
139
140/* Query aspacem to ask where a mapping should go. On success, the
141 advised placement is returned, and *ok is set to True. On failure,
142 zero is returned and *ok is set to False. Note that *ok must be
143 consulted by the caller to establish success or failure; that
144 cannot be established reliably from the returned value. If *ok is
145 set to False, it means aspacem has vetoed the mapping, and so the
146 caller should not proceed with it. */
147extern Addr VG_(am_get_advisory)
florian32971242014-10-23 17:47:15 +0000148 ( const MapRequest* req, Bool forClient, /*OUT*/Bool* ok );
sewardj45f4e7c2005-09-27 19:20:21 +0000149
150/* Convenience wrapper for VG_(am_get_advisory) for client floating or
151 fixed requests. If start is zero, a floating request is issued; if
152 nonzero, a fixed request at that address is issued. Same comments
153 about return values apply. */
154extern Addr VG_(am_get_advisory_client_simple)
155 ( Addr start, SizeT len, /*OUT*/Bool* ok );
156
philippe15e301e2011-12-22 13:25:58 +0000157/* Returns True if [start, start + len - 1] is covered by a single
158 free segment, otherwise returns False.
159 This allows to check the following case:
160 VG_(am_get_advisory_client_simple) (first arg == 0, meaning
161 this-or-nothing) is too lenient, and may allow us to trash
162 the next segment along. So make very sure that the proposed
163 new area really is free. This is perhaps overly
164 conservative, but it fixes #129866. */
165extern Bool VG_(am_covered_by_single_free_segment)
166 ( Addr start, SizeT len);
167
sewardj45f4e7c2005-09-27 19:20:21 +0000168/* Notifies aspacem that the client completed an mmap successfully.
169 The segment array is updated accordingly. If the returned Bool is
170 True, the caller should immediately discard translations from the
171 specified address range. */
172extern Bool VG_(am_notify_client_mmap)
sewardj274461d2005-10-02 17:01:41 +0000173 ( Addr a, SizeT len, UInt prot, UInt flags, Int fd, Off64T offset );
sewardj45f4e7c2005-09-27 19:20:21 +0000174
tom1340c352005-10-04 15:59:54 +0000175/* Notifies aspacem that the client completed a shmat successfully.
176 The segment array is updated accordingly. If the returned Bool is
177 True, the caller should immediately discard translations from the
178 specified address range. */
179extern Bool VG_(am_notify_client_shmat)( Addr a, SizeT len, UInt prot );
180
sewardj45f4e7c2005-09-27 19:20:21 +0000181/* Notifies aspacem that an mprotect was completed successfully. The
182 segment array is updated accordingly. Note, as with
183 VG_(am_notify_munmap), it is not the job of this function to reject
184 stupid mprotects, for example the client doing mprotect of
185 non-client areas. Such requests should be intercepted earlier, by
186 the syscall wrapper for mprotect. This function merely records
187 whatever it is told. If the returned Bool is True, the caller
188 should immediately discard translations from the specified address
189 range. */
190extern Bool VG_(am_notify_mprotect)( Addr start, SizeT len, UInt prot );
191
192/* Notifies aspacem that an munmap completed successfully. The
193 segment array is updated accordingly. As with
florian9e0419c2015-05-22 09:34:30 +0000194 VG_(am_notify_mprotect), we merely record the given info, and don't
sewardj45f4e7c2005-09-27 19:20:21 +0000195 check it for sensibleness. If the returned Bool is True, the
196 caller should immediately discard translations from the specified
197 address range. */
198extern Bool VG_(am_notify_munmap)( Addr start, SizeT len );
199
sewardj45f4e7c2005-09-27 19:20:21 +0000200/* Hand a raw mmap to the kernel, without aspacem updating the segment
201 array. THIS FUNCTION IS DANGEROUS -- it will cause aspacem's view
202 of the address space to diverge from that of the kernel. DO NOT
203 USE IT UNLESS YOU UNDERSTAND the request-notify model used by
204 aspacem. In short, DO NOT USE THIS FUNCTION. */
205extern SysRes VG_(am_do_mmap_NO_NOTIFY)
njn9506f0d2009-05-20 03:20:05 +0000206 ( Addr start, SizeT length, UInt prot, UInt flags, Int fd, Off64T offset);
sewardj45f4e7c2005-09-27 19:20:21 +0000207
208
209//--------------------------------------------------------------
210// Dealing with mappings which do not arise directly from the
211// simulation of the client. These are typically used for
212// loading the client and building its stack/data segment, before
213// execution begins. Also for V's own administrative use.
214
215/* --- --- --- map, unmap, protect --- --- --- */
216
217/* Map a file at a fixed address for the client, and update the
218 segment array accordingly. */
219extern SysRes VG_(am_mmap_file_fixed_client)
sewardj274461d2005-10-02 17:01:41 +0000220 ( Addr start, SizeT length, UInt prot, Int fd, Off64T offset );
sewardj8eb8bab2015-07-21 14:44:28 +0000221extern SysRes VG_(am_mmap_file_fixed_client_flags)
222 ( Addr start, SizeT length, UInt prot, UInt flags, Int fd, Off64T offset );
njnf76d27a2009-05-28 01:53:07 +0000223extern SysRes VG_(am_mmap_named_file_fixed_client)
sewardj8eb8bab2015-07-21 14:44:28 +0000224 ( Addr start, SizeT length, UInt prot, Int fd,
225 Off64T offset, const HChar *name );
226extern SysRes VG_(am_mmap_named_file_fixed_client_flags)
227 ( Addr start, SizeT length, UInt prot, UInt flags, Int fd,
228 Off64T offset, const HChar *name );
sewardj45f4e7c2005-09-27 19:20:21 +0000229
230/* Map anonymously at a fixed address for the client, and update
231 the segment array accordingly. */
232extern SysRes VG_(am_mmap_anon_fixed_client)
233 ( Addr start, SizeT length, UInt prot );
234
sewardjfa2a2462006-10-17 01:30:07 +0000235
sewardj45f4e7c2005-09-27 19:20:21 +0000236/* Map anonymously at an unconstrained address for the client, and
237 update the segment array accordingly. */
238extern SysRes VG_(am_mmap_anon_float_client) ( SizeT length, Int prot );
239
240/* Map anonymously at an unconstrained address for V, and update the
241 segment array accordingly. This is fundamentally how V allocates
242 itself more address space when needed. */
243extern SysRes VG_(am_mmap_anon_float_valgrind)( SizeT cszB );
244
sewardj3b290482011-05-06 21:02:55 +0000245/* Map privately a file at an unconstrained address for V, and update the
sewardj45f4e7c2005-09-27 19:20:21 +0000246 segment array accordingly. This is used by V for transiently
247 mapping in object files to read their debug info. */
248extern SysRes VG_(am_mmap_file_float_valgrind)
sewardj274461d2005-10-02 17:01:41 +0000249 ( SizeT length, UInt prot, Int fd, Off64T offset );
sewardj45f4e7c2005-09-27 19:20:21 +0000250
sewardj3b290482011-05-06 21:02:55 +0000251/* Map shared a file at an unconstrained address for V, and update the
252 segment array accordingly. This is used by V for communicating
253 with vgdb. */
254extern SysRes VG_(am_shared_mmap_file_float_valgrind)
255 ( SizeT length, UInt prot, Int fd, Off64T offset );
256
Elliott Hughesa0664b92017-04-18 17:46:52 -0700257/* Similar to VG_(am_mmap_anon_float_client) but also
florian2fa66ce2015-03-07 23:01:14 +0000258 marks the segment as containing the client heap. */
259extern SysRes VG_(am_mmap_client_heap) ( SizeT length, Int prot );
260
sewardj45f4e7c2005-09-27 19:20:21 +0000261/* Unmap the given address range and update the segment array
262 accordingly. This fails if the range isn't valid for the client.
263 If *need_discard is True after a successful return, the caller
264 should immediately discard translations from the specified address
265 range. */
266extern SysRes VG_(am_munmap_client)( /*OUT*/Bool* need_discard,
267 Addr start, SizeT length );
268
sewardj45f4e7c2005-09-27 19:20:21 +0000269/* Let (start,len) denote an area within a single Valgrind-owned
270 segment (anon or file). Change the ownership of [start, start+len)
271 to the client instead. Fails if (start,len) does not denote a
272 suitable segment. */
273extern Bool VG_(am_change_ownership_v_to_c)( Addr start, SizeT len );
274
florian2fa66ce2015-03-07 23:01:14 +0000275/* Set the 'hasT' bit on the segment containing ADDR indicating that
276 translations have or may have been taken from this segment. ADDR is
277 expected to belong to a client segment. */
278extern void VG_(am_set_segment_hasT)( Addr addr );
sewardjfa2a2462006-10-17 01:30:07 +0000279
sewardj45f4e7c2005-09-27 19:20:21 +0000280/* --- --- --- reservations --- --- --- */
281
282/* Create a reservation from START .. START+LENGTH-1, with the given
283 ShrinkMode. When checking whether the reservation can be created,
284 also ensure that at least abs(EXTRA) extra free bytes will remain
285 above (> 0) or below (< 0) the reservation.
286
287 The reservation will only be created if it, plus the extra-zone,
288 falls entirely within a single free segment. The returned Bool
289 indicates whether the creation succeeded. */
290extern Bool VG_(am_create_reservation)
291 ( Addr start, SizeT length, ShrinkMode smode, SSizeT extra );
292
florian888b8152015-02-26 16:07:12 +0000293/* ADDR is the start address of an anonymous client mapping. This fn extends
294 the mapping by DELTA bytes, taking the space from a reservation section
sewardj45f4e7c2005-09-27 19:20:21 +0000295 which must be adjacent. If DELTA is positive, the segment is
296 extended forwards in the address space, and the reservation must be
297 the next one along. If DELTA is negative, the segment is extended
298 backwards in the address space and the reservation must be the
sewardj6684d2a2005-09-28 01:46:31 +0000299 previous one. DELTA must be page aligned. abs(DELTA) must not
300 exceed the size of the reservation segment minus one page, that is,
301 the reservation segment after the operation must be at least one
florian888b8152015-02-26 16:07:12 +0000302 page long. The function returns a pointer to the resized segment. */
303extern const NSegment *VG_(am_extend_into_adjacent_reservation_client)
florian15fa8a22015-03-03 14:56:17 +0000304 ( Addr addr, SSizeT delta, /*OUT*/Bool *overflow );
sewardj45f4e7c2005-09-27 19:20:21 +0000305
306/* --- --- --- resizing/move a mapping --- --- --- */
307
floriandd7318b2015-02-25 10:06:06 +0000308/* This function grows a client mapping in place into an adjacent free segment.
309 ADDR is the client mapping's start address and DELTA, which must be page
310 aligned, is the growth amount. The function returns a pointer to the
311 resized segment. The function is used in support of mremap. */
312extern const NSegment *VG_(am_extend_map_client)( Addr addr, SizeT delta );
sewardj45f4e7c2005-09-27 19:20:21 +0000313
314/* Remap the old address range to the new address range. Fails if any
315 parameter is not page aligned, if the either size is zero, if any
316 wraparound is implied, if the old address range does not fall
317 entirely within a single segment, if the new address range overlaps
318 with the old one, or if the old address range is not a valid client
319 mapping. If *need_discard is True after a successful return, the
320 caller should immediately discard translations from both specified
321 address ranges. */
322extern Bool VG_(am_relocate_nooverlap_client)( /*OUT*/Bool* need_discard,
323 Addr old_addr, SizeT old_len,
324 Addr new_addr, SizeT new_len );
325
326//--------------------------------------------------------------
327// Valgrind (non-client) thread stacks. V itself runs on such
328// stacks. The address space manager provides and suitably
329// protects such stacks.
330
philipped0720e42015-03-12 20:43:46 +0000331// VG_DEFAULT_STACK_ACTIVE_SZB is the default size of a Valgrind stack.
332// The effectively used size is controlled by the command line options
333// --valgrind-stack-size=xxxx (which must be page aligned).
334// Note that m_main.c needs an interim stack (just to startup), before
335// any command line option can be processed. This interim stack
336// (declared in m_main.c) will use the size VG_DEFAULT_STACK_ACTIVE_SZB.
carllcae0cc22014-08-07 23:17:29 +0000337#if defined(VGP_ppc32_linux) \
338 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \
sewardjf0c12502014-01-12 12:54:00 +0000339 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \
Elliott Hughesed398002017-06-21 14:41:24 -0700340 || defined(VGP_arm64_linux)
sewardje66f2e02006-12-30 17:45:08 +0000341# define VG_STACK_GUARD_SZB 65536 // 1 or 16 pages
sewardje66f2e02006-12-30 17:45:08 +0000342#else
343# define VG_STACK_GUARD_SZB 8192 // 2 pages
sewardje66f2e02006-12-30 17:45:08 +0000344#endif
philipped0720e42015-03-12 20:43:46 +0000345# define VG_DEFAULT_STACK_ACTIVE_SZB 1048576 // (4096 * 256) = 1Mb
sewardj45f4e7c2005-09-27 19:20:21 +0000346
philipped0720e42015-03-12 20:43:46 +0000347typedef struct _VgStack VgStack;
sewardj45f4e7c2005-09-27 19:20:21 +0000348
349
philippe17e76ec2014-04-20 19:50:13 +0000350/* Allocate and initialise a VgStack (anonymous valgrind space).
sewardj45f4e7c2005-09-27 19:20:21 +0000351 Protect the stack active area and the guard areas appropriately.
352 Returns NULL on failure, else the address of the bottom of the
353 stack. On success, also sets *initial_sp to what the stack pointer
354 should be set to. */
355
356extern VgStack* VG_(am_alloc_VgStack)( /*OUT*/Addr* initial_sp );
357
sewardj46dbd3f2010-09-08 08:30:31 +0000358/* Figure out how many bytes of the stack's active area have not been
359 used. Used for estimating if we are close to overflowing it. If
360 the free area is larger than 'limit', just return 'limit'. */
florian32971242014-10-23 17:47:15 +0000361extern SizeT VG_(am_get_VgStack_unused_szB)( const VgStack* stack,
362 SizeT limit );
sewardj45f4e7c2005-09-27 19:20:21 +0000363
njnf76d27a2009-05-28 01:53:07 +0000364// DDD: this is ugly
365#if defined(VGO_darwin)
366typedef
367 struct {
368 Bool is_added; // Added or removed seg?
369 Addr start;
370 SizeT end;
371 UInt prot; // Not used for removed segs.
372 Off64T offset; // Not used for removed segs.
373 }
374 ChangedSeg;
375
njnfd1b4612009-06-24 08:32:42 +0000376extern Bool VG_(get_changed_segments)(
njnf76d27a2009-05-28 01:53:07 +0000377 const HChar* when, const HChar* where, /*OUT*/ChangedSeg* css,
378 Int css_size, /*OUT*/Int* css_used);
379#endif
njne3f06352005-06-01 03:48:33 +0000380
Elliott Hughesa0664b92017-04-18 17:46:52 -0700381#if defined(VGO_solaris)
382extern Bool VG_(am_search_for_new_segment)(Addr *start, SizeT *size,
383 UInt *prot);
384#endif
385
sewardj55f9d1a2005-04-25 11:11:44 +0000386#endif // __PUB_CORE_ASPACEMGR_H
387
388/*--------------------------------------------------------------------*/
njnaf839f52005-06-23 03:27:57 +0000389/*--- end ---*/
sewardj55f9d1a2005-04-25 11:11:44 +0000390/*--------------------------------------------------------------------*/