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-2015 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 (highest addressable byte) for the client's stack. */ 62 extern Addr VG_(am_startup) ( Addr sp_at_startup ); 63 64 /* 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. */ 66 extern Bool VG_(am_is_valid_for_aspacem_minAddr)( Addr addr, 67 const HChar **errmsg ); 68 69 //-------------------------------------------------------------- 70 // Querying current status 71 72 73 /* Finds an anonymous segment containing 'a'. Returned pointer is read only. */ 74 extern NSegment const *VG_(am_find_anon_segment) ( Addr a ); 75 76 /* Find the next segment along from 'here', if it is a file/anon/resvn 77 segment. */ 78 extern NSegment const* VG_(am_next_nsegment) ( const NSegment* here, 79 Bool fwds ); 80 81 /* 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 84 VKI_PROT_NONE as 'prot'. Will return False if any part of the 85 area does not belong to valgrind or does not have at least 86 the stated permissions. */ 87 extern Bool VG_(am_is_valid_for_valgrind) 88 ( Addr start, SizeT len, UInt prot ); 89 90 /* 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. */ 94 extern Bool VG_(am_is_valid_for_client_or_free_or_resvn) 95 ( Addr start, SizeT len, UInt prot ); 96 97 /* Checks if a piece of memory consists of either free or reservation 98 segments. */ 99 extern Bool VG_(am_is_free_or_resvn)( Addr start, SizeT len ); 100 101 /* Check whether ADDR looks like an address or address-to-be located in an 102 extensible client stack segment. */ 103 extern Bool VG_(am_addr_is_in_extensible_client_stack)( Addr addr ); 104 105 /* 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. */ 108 extern ULong VG_(am_get_anonsize_total)( void ); 109 110 /* Show the segment array on the debug log, at given loglevel. */ 111 extern void VG_(am_show_nsegments) ( Int logLevel, const HChar* who ); 112 113 /* 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 121 extern Bool VG_(am_do_sync_check) ( const HChar* fn, 122 const HChar* file, Int line ); 123 124 //-------------------------------------------------------------- 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). */ 130 typedef 131 struct { 132 /* Note: if rkind == MAlign then start specifies alignment. This is 133 Solaris specific. */ 134 enum { MFixed, MHint, MAny, MAlign } rkind; 135 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. */ 147 extern Addr VG_(am_get_advisory) 148 ( const MapRequest* req, Bool forClient, /*OUT*/Bool* ok ); 149 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. */ 154 extern Addr VG_(am_get_advisory_client_simple) 155 ( Addr start, SizeT len, /*OUT*/Bool* ok ); 156 157 /* 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. */ 165 extern Bool VG_(am_covered_by_single_free_segment) 166 ( Addr start, SizeT len); 167 168 /* 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. */ 172 extern Bool VG_(am_notify_client_mmap) 173 ( Addr a, SizeT len, UInt prot, UInt flags, Int fd, Off64T offset ); 174 175 /* 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. */ 179 extern Bool VG_(am_notify_client_shmat)( Addr a, SizeT len, UInt prot ); 180 181 /* 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. */ 190 extern 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 194 VG_(am_notify_mprotect), we merely record the given info, and don't 195 check it for sensibleness. If the returned Bool is True, the 196 caller should immediately discard translations from the specified 197 address range. */ 198 extern Bool VG_(am_notify_munmap)( Addr start, SizeT len ); 199 200 /* 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. */ 205 extern SysRes VG_(am_do_mmap_NO_NOTIFY) 206 ( Addr start, SizeT length, UInt prot, UInt flags, Int fd, Off64T offset); 207 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. */ 219 extern SysRes VG_(am_mmap_file_fixed_client) 220 ( Addr start, SizeT length, UInt prot, Int fd, Off64T offset ); 221 extern SysRes VG_(am_mmap_file_fixed_client_flags) 222 ( Addr start, SizeT length, UInt prot, UInt flags, Int fd, Off64T offset ); 223 extern SysRes VG_(am_mmap_named_file_fixed_client) 224 ( Addr start, SizeT length, UInt prot, Int fd, 225 Off64T offset, const HChar *name ); 226 extern 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 ); 229 230 /* Map anonymously at a fixed address for the client, and update 231 the segment array accordingly. */ 232 extern SysRes VG_(am_mmap_anon_fixed_client) 233 ( Addr start, SizeT length, UInt prot ); 234 235 236 /* Map anonymously at an unconstrained address for the client, and 237 update the segment array accordingly. */ 238 extern 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. */ 243 extern SysRes VG_(am_mmap_anon_float_valgrind)( SizeT cszB ); 244 245 /* Map privately a file at an unconstrained address for V, and update the 246 segment array accordingly. This is used by V for transiently 247 mapping in object files to read their debug info. */ 248 extern SysRes VG_(am_mmap_file_float_valgrind) 249 ( SizeT length, UInt prot, Int fd, Off64T offset ); 250 251 /* 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. */ 254 extern SysRes VG_(am_shared_mmap_file_float_valgrind) 255 ( SizeT length, UInt prot, Int fd, Off64T offset ); 256 257 /* Convenience wrapper around VG_(am_mmap_anon_float_client) which also 258 marks the segment as containing the client heap. */ 259 extern SysRes VG_(am_mmap_client_heap) ( SizeT length, Int prot ); 260 261 /* 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. */ 266 extern SysRes VG_(am_munmap_client)( /*OUT*/Bool* need_discard, 267 Addr start, SizeT length ); 268 269 /* 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. */ 273 extern Bool VG_(am_change_ownership_v_to_c)( Addr start, SizeT len ); 274 275 /* 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. */ 278 extern void VG_(am_set_segment_hasT)( Addr addr ); 279 280 /* --- --- --- 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. */ 290 extern Bool VG_(am_create_reservation) 291 ( Addr start, SizeT length, ShrinkMode smode, SSizeT extra ); 292 293 /* 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 295 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 299 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 302 page long. The function returns a pointer to the resized segment. */ 303 extern const NSegment *VG_(am_extend_into_adjacent_reservation_client) 304 ( Addr addr, SSizeT delta, /*OUT*/Bool *overflow ); 305 306 /* --- --- --- resizing/move a mapping --- --- --- */ 307 308 /* 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. */ 312 extern const NSegment *VG_(am_extend_map_client)( Addr addr, SizeT delta ); 313 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. */ 322 extern 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 331 // 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. 337 #if defined(VGP_ppc32_linux) \ 338 || defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) \ 339 || defined(VGP_mips32_linux) || defined(VGP_mips64_linux) \ 340 || defined(VGP_arm64_linux) || defined(VGP_tilegx_linux) 341 # define VG_STACK_GUARD_SZB 65536 // 1 or 16 pages 342 #else 343 # define VG_STACK_GUARD_SZB 8192 // 2 pages 344 #endif 345 # define VG_DEFAULT_STACK_ACTIVE_SZB 1048576 // (4096 * 256) = 1Mb 346 347 typedef struct _VgStack VgStack; 348 349 350 /* Allocate and initialise a VgStack (anonymous valgrind space). 351 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 356 extern VgStack* VG_(am_alloc_VgStack)( /*OUT*/Addr* initial_sp ); 357 358 /* 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'. */ 361 extern SizeT VG_(am_get_VgStack_unused_szB)( const VgStack* stack, 362 SizeT limit ); 363 364 // DDD: this is ugly 365 #if defined(VGO_darwin) 366 typedef 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 376 extern Bool VG_(get_changed_segments)( 377 const HChar* when, const HChar* where, /*OUT*/ChangedSeg* css, 378 Int css_size, /*OUT*/Int* css_used); 379 #endif 380 381 #endif // __PUB_CORE_ASPACEMGR_H 382 383 /*--------------------------------------------------------------------*/ 384 /*--- end ---*/ 385 /*--------------------------------------------------------------------*/ 386