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