Home | History | Annotate | Download | only in coregrind
      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-2010 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) ( 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. */
     92 extern 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. */
     98 extern ULong VG_(am_get_anonsize_total)( void );
     99 
    100 /* Show the segment array on the debug log, at given loglevel. */
    101 extern 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 
    120 extern 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). */
    129 typedef
    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. */
    144 extern 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. */
    151 extern 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. */
    158 extern Bool VG_(am_notify_client_mmap)
    159    ( Addr a, SizeT len, UInt prot, UInt flags, Int fd, Off64T offset );
    160 
    161 /* Notifies aspacem that the client completed a shmat successfully.
    162    The segment array is updated accordingly.  If the returned Bool is
    163    True, the caller should immediately discard translations from the
    164    specified address range. */
    165 extern Bool VG_(am_notify_client_shmat)( Addr a, SizeT len, UInt prot );
    166 
    167 /* Notifies aspacem that an mprotect was completed successfully.  The
    168    segment array is updated accordingly.  Note, as with
    169    VG_(am_notify_munmap), it is not the job of this function to reject
    170    stupid mprotects, for example the client doing mprotect of
    171    non-client areas.  Such requests should be intercepted earlier, by
    172    the syscall wrapper for mprotect.  This function merely records
    173    whatever it is told.  If the returned Bool is True, the caller
    174    should immediately discard translations from the specified address
    175    range. */
    176 extern Bool VG_(am_notify_mprotect)( Addr start, SizeT len, UInt prot );
    177 
    178 /* Notifies aspacem that an munmap completed successfully.  The
    179    segment array is updated accordingly.  As with
    180    VG_(am_notify_munmap), we merely record the given info, and don't
    181    check it for sensibleness.  If the returned Bool is True, the
    182    caller should immediately discard translations from the specified
    183    address range. */
    184 extern Bool VG_(am_notify_munmap)( Addr start, SizeT len );
    185 
    186 /* Hand a raw mmap to the kernel, without aspacem updating the segment
    187    array.  THIS FUNCTION IS DANGEROUS -- it will cause aspacem's view
    188    of the address space to diverge from that of the kernel.  DO NOT
    189    USE IT UNLESS YOU UNDERSTAND the request-notify model used by
    190    aspacem.  In short, DO NOT USE THIS FUNCTION. */
    191 extern SysRes VG_(am_do_mmap_NO_NOTIFY)
    192    ( Addr start, SizeT length, UInt prot, UInt flags, Int fd, Off64T offset);
    193 
    194 
    195 //--------------------------------------------------------------
    196 // Functions pertaining to AIX5-specific notifications.
    197 
    198 /* Describes followup actions that need to be done following a call to
    199    VG_(am_aix5_reread_procmap).  When acquire==True, the specified
    200    code and data segments have been mapped into the process, and so
    201    m_debuginfo needs to read info for it; also m_redir needs to know,
    202    and the tool needs to be told.  When acquire==False, the specified
    203    segments have been unloaded and m_debuginfo, m_redir and the tool
    204    (and m_transtab?) need to notified appropriately. */
    205 typedef
    206    struct {
    207       Addr   code_start;
    208       Word   code_len;
    209       Addr   data_start;
    210       Word   data_len;
    211       UChar* file_name;
    212       UChar* mem_name;
    213       Bool   is_mainexe;
    214       Bool   acquire;
    215    }
    216    AixCodeSegChange;
    217 
    218 /* Tell aspacem that /proc/<pid>/map may have changed (eg following
    219    __loadx) and so it should be re-read, and the code/data segment
    220    list updated accordingly.  The resulting array of AixCodeChangeSeg
    221    directives are written to 'directives', and the number of entries
    222    to *ndirectives. */
    223 extern void VG_(am_aix5_reread_procmap)
    224    ( /*OUT*/AixCodeSegChange* directives, /*OUT*/Int* ndirectives );
    225 
    226 /* Find out the size of the AixCodeSegChange that must be
    227    presented to VG_(am_aix5_reread_procmap). */
    228 extern Int VG_(am_aix5_reread_procmap_howmany_directives)(void);
    229 
    230 /* Tell aspacem where the initial client stack is, so that it
    231    can later produce a faked-up NSegment in response to
    232    VG_(am_find_nsegment) for athat address, if asked. */
    233 extern void VG_(am_aix5_set_initial_client_sp)( Addr );
    234 
    235 /* The AIX5 aspacem implementation needs to be told when it is and
    236    isn't allowed to use sbrk to allocate memory.  Hence: */
    237 extern Bool VG_(am_aix5_sbrk_allowed);
    238 
    239 
    240 //--------------------------------------------------------------
    241 // Dealing with mappings which do not arise directly from the
    242 // simulation of the client.  These are typically used for
    243 // loading the client and building its stack/data segment, before
    244 // execution begins.  Also for V's own administrative use.
    245 
    246 /* --- --- --- map, unmap, protect  --- --- --- */
    247 
    248 /* Map a file at a fixed address for the client, and update the
    249    segment array accordingly. */
    250 extern SysRes VG_(am_mmap_file_fixed_client)
    251    ( Addr start, SizeT length, UInt prot, Int fd, Off64T offset );
    252 extern SysRes VG_(am_mmap_named_file_fixed_client)
    253    ( Addr start, SizeT length, UInt prot, Int fd, Off64T offset, const HChar *name );
    254 
    255 /* Map anonymously at a fixed address for the client, and update
    256    the segment array accordingly. */
    257 extern SysRes VG_(am_mmap_anon_fixed_client)
    258    ( Addr start, SizeT length, UInt prot );
    259 
    260 
    261 /* Map anonymously at an unconstrained address for the client, and
    262    update the segment array accordingly.  */
    263 extern SysRes VG_(am_mmap_anon_float_client) ( SizeT length, Int prot );
    264 
    265 /* Similarly, acquire new address space for the client but with
    266    considerable restrictions on what can be done with it: (1) the
    267    actual protections may exceed those stated in 'prot', (2) the
    268    area's protections cannot be later changed using any form of
    269    mprotect, and (3) the area cannot be freed using any form of
    270    munmap.  On Linux this behaves the same as
    271    VG_(am_mmap_anon_float_client).  On AIX5 this *may* allocate memory
    272    by using sbrk, so as to make use of large pages on AIX. */
    273 extern SysRes VG_(am_sbrk_anon_float_client) ( SizeT length, Int prot );
    274 
    275 
    276 /* Map anonymously at an unconstrained address for V, and update the
    277    segment array accordingly.  This is fundamentally how V allocates
    278    itself more address space when needed. */
    279 extern SysRes VG_(am_mmap_anon_float_valgrind)( SizeT cszB );
    280 
    281 /* Same comments apply as per VG_(am_sbrk_anon_float_client).  On
    282    Linux this behaves the same as VG_(am_mmap_anon_float_valgrind). */
    283 extern SysRes VG_(am_sbrk_anon_float_valgrind)( SizeT cszB );
    284 
    285 
    286 /* Map a file at an unconstrained address for V, and update the
    287    segment array accordingly.  This is used by V for transiently
    288    mapping in object files to read their debug info.  */
    289 extern SysRes VG_(am_mmap_file_float_valgrind)
    290    ( SizeT length, UInt prot, Int fd, Off64T offset );
    291 extern SysRes VG_(am_mmap_file_float_valgrind_with_flags)
    292    ( SizeT length, UInt prot, UInt flags, Int fd, Off64T offset );
    293 
    294 /* Unmap the given address range and update the segment array
    295    accordingly.  This fails if the range isn't valid for the client.
    296    If *need_discard is True after a successful return, the caller
    297    should immediately discard translations from the specified address
    298    range. */
    299 extern SysRes VG_(am_munmap_client)( /*OUT*/Bool* need_discard,
    300                                      Addr start, SizeT length );
    301 
    302 /* Let (start,len) denote an area within a single Valgrind-owned
    303   segment (anon or file).  Change the ownership of [start, start+len)
    304   to the client instead.  Fails if (start,len) does not denote a
    305   suitable segment. */
    306 extern Bool VG_(am_change_ownership_v_to_c)( Addr start, SizeT len );
    307 
    308 /* 'seg' must be NULL or have been obtained from
    309    VG_(am_find_nsegment), and still valid.  If non-NULL, and if it
    310    denotes a SkAnonC (anonymous client mapping) area, set the .isCH
    311    (is-client-heap) flag for that area.  Otherwise do nothing.
    312    (Bizarre interface so that the same code works for both Linux and
    313    AIX and does not impose inefficiencies on the Linux version.) */
    314 extern void VG_(am_set_segment_isCH_if_SkAnonC)( NSegment* seg );
    315 
    316 /* Same idea as VG_(am_set_segment_isCH_if_SkAnonC), except set the
    317    segment's hasT bit (has-cached-code) if this is SkFileC or SkAnonC
    318    segment. */
    319 extern void VG_(am_set_segment_hasT_if_SkFileC_or_SkAnonC)( NSegment* );
    320 
    321 /* --- --- --- reservations --- --- --- */
    322 
    323 /* Create a reservation from START .. START+LENGTH-1, with the given
    324    ShrinkMode.  When checking whether the reservation can be created,
    325    also ensure that at least abs(EXTRA) extra free bytes will remain
    326    above (> 0) or below (< 0) the reservation.
    327 
    328    The reservation will only be created if it, plus the extra-zone,
    329    falls entirely within a single free segment.  The returned Bool
    330    indicates whether the creation succeeded. */
    331 extern Bool VG_(am_create_reservation)
    332    ( Addr start, SizeT length, ShrinkMode smode, SSizeT extra );
    333 
    334 /* Let SEG be an anonymous client mapping.  This fn extends the
    335    mapping by DELTA bytes, taking the space from a reservation section
    336    which must be adjacent.  If DELTA is positive, the segment is
    337    extended forwards in the address space, and the reservation must be
    338    the next one along.  If DELTA is negative, the segment is extended
    339    backwards in the address space and the reservation must be the
    340    previous one.  DELTA must be page aligned.  abs(DELTA) must not
    341    exceed the size of the reservation segment minus one page, that is,
    342    the reservation segment after the operation must be at least one
    343    page long. */
    344 extern Bool VG_(am_extend_into_adjacent_reservation_client)
    345    ( NSegment* seg, SSizeT delta );
    346 
    347 /* --- --- --- resizing/move a mapping --- --- --- */
    348 
    349 /* Let SEG be a client mapping (anonymous or file).  This fn extends
    350    the mapping forwards only by DELTA bytes, and trashes whatever was
    351    in the new area.  Fails if SEG is not a single client mapping or if
    352    the new area is not accessible to the client.  Fails if DELTA is
    353    not page aligned.  *seg is invalid after a successful return.  If
    354    *need_discard is True after a successful return, the caller should
    355    immediately discard translations from the new area. */
    356 extern Bool VG_(am_extend_map_client)( /*OUT*/Bool* need_discard,
    357                                        NSegment* seg, SizeT delta );
    358 
    359 /* Remap the old address range to the new address range.  Fails if any
    360    parameter is not page aligned, if the either size is zero, if any
    361    wraparound is implied, if the old address range does not fall
    362    entirely within a single segment, if the new address range overlaps
    363    with the old one, or if the old address range is not a valid client
    364    mapping.  If *need_discard is True after a successful return, the
    365    caller should immediately discard translations from both specified
    366    address ranges.  */
    367 extern Bool VG_(am_relocate_nooverlap_client)( /*OUT*/Bool* need_discard,
    368                                                Addr old_addr, SizeT old_len,
    369                                                Addr new_addr, SizeT new_len );
    370 
    371 //--------------------------------------------------------------
    372 // Valgrind (non-client) thread stacks.  V itself runs on such
    373 // stacks.  The address space manager provides and suitably
    374 // protects such stacks.
    375 
    376 #if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
    377 # define VG_STACK_GUARD_SZB  65536  // 1 or 16 pages
    378 # define VG_STACK_ACTIVE_SZB (4096 * 256) // 1Mb
    379 #else
    380 # define VG_STACK_GUARD_SZB  8192   // 2 pages
    381 # define VG_STACK_ACTIVE_SZB (4096 * 256) // 1Mb
    382 #endif
    383 
    384 typedef
    385    struct {
    386       HChar bytes[VG_STACK_GUARD_SZB
    387                   + VG_STACK_ACTIVE_SZB
    388                   + VG_STACK_GUARD_SZB];
    389    }
    390    VgStack;
    391 
    392 
    393 /* Allocate and initialise a VgStack (anonymous client space).
    394    Protect the stack active area and the guard areas appropriately.
    395    Returns NULL on failure, else the address of the bottom of the
    396    stack.  On success, also sets *initial_sp to what the stack pointer
    397    should be set to. */
    398 
    399 extern VgStack* VG_(am_alloc_VgStack)( /*OUT*/Addr* initial_sp );
    400 
    401 /* Figure out how many bytes of the stack's active area have not been
    402    used.  Used for estimating if we are close to overflowing it.  If
    403    the free area is larger than 'limit', just return 'limit'. */
    404 extern SizeT VG_(am_get_VgStack_unused_szB)( VgStack* stack, SizeT limit );
    405 
    406 // DDD: this is ugly
    407 #if defined(VGO_darwin)
    408 typedef
    409    struct {
    410       Bool   is_added;  // Added or removed seg?
    411       Addr   start;
    412       SizeT  end;
    413       UInt   prot;      // Not used for removed segs.
    414       Off64T offset;    // Not used for removed segs.
    415    }
    416    ChangedSeg;
    417 
    418 extern Bool VG_(get_changed_segments)(
    419       const HChar* when, const HChar* where, /*OUT*/ChangedSeg* css,
    420       Int css_size, /*OUT*/Int* css_used);
    421 #endif
    422 
    423 #endif   // __PUB_CORE_ASPACEMGR_H
    424 
    425 /*--------------------------------------------------------------------*/
    426 /*--- end                                                          ---*/
    427 /*--------------------------------------------------------------------*/
    428