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 (at) 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. */ 62 extern 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. */ 76 extern 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'. */ 92 extern 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. */ 99 extern 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. */ 105 extern ULong VG_(am_get_anonsize_total)( void ); 106 107 /* Show the segment array on the debug log, at given loglevel. */ 108 extern 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 127 extern 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). */ 136 typedef 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. */ 151 extern 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. */ 158 extern 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. */ 169 extern 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. */ 176 extern 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. */ 183 extern 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. */ 194 extern 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. */ 202 extern 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. */ 209 extern 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. */ 223 extern SysRes VG_(am_mmap_file_fixed_client) 224 ( Addr start, SizeT length, UInt prot, Int fd, Off64T offset ); 225 extern 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. */ 230 extern 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. */ 236 extern 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. */ 241 extern 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. */ 246 extern 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. */ 252 extern 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. */ 260 extern 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. */ 267 extern 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.) */ 275 extern 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. */ 280 extern 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. */ 292 extern 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. */ 305 extern 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. */ 317 extern 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. */ 328 extern 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 347 typedef 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 362 extern 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'. */ 367 extern SizeT VG_(am_get_VgStack_unused_szB)( VgStack* stack, SizeT limit ); 368 369 // DDD: this is ugly 370 #if defined(VGO_darwin) 371 typedef 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 381 extern 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