Home | History | Annotate | Download | only in memcheck
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- A header file for all parts of the MemCheck tool.            ---*/
      4 /*---                                                 mc_include.h ---*/
      5 /*--------------------------------------------------------------------*/
      6 
      7 /*
      8    This file is part of MemCheck, a heavyweight Valgrind tool for
      9    detecting memory errors.
     10 
     11    Copyright (C) 2000-2012 Julian Seward
     12       jseward (at) acm.org
     13 
     14    This program is free software; you can redistribute it and/or
     15    modify it under the terms of the GNU General Public License as
     16    published by the Free Software Foundation; either version 2 of the
     17    License, or (at your option) any later version.
     18 
     19    This program is distributed in the hope that it will be useful, but
     20    WITHOUT ANY WARRANTY; without even the implied warranty of
     21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     22    General Public License for more details.
     23 
     24    You should have received a copy of the GNU General Public License
     25    along with this program; if not, write to the Free Software
     26    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     27    02111-1307, USA.
     28 
     29    The GNU General Public License is contained in the file COPYING.
     30 */
     31 
     32 #ifndef __MC_INCLUDE_H
     33 #define __MC_INCLUDE_H
     34 
     35 #define MC_(str)    VGAPPEND(vgMemCheck_,str)
     36 
     37 
     38 /* This is a private header file for use only within the
     39    memcheck/ directory. */
     40 
     41 /*------------------------------------------------------------*/
     42 /*--- Tracking the heap                                    ---*/
     43 /*------------------------------------------------------------*/
     44 
     45 /* By default, we want at least a 16B redzone on client heap blocks
     46    for Memcheck.
     47    The default can be modified by --redzone-size. */
     48 #define MC_MALLOC_DEFAULT_REDZONE_SZB    16
     49 // effective redzone, as (possibly) modified by --redzone-size:
     50 extern SizeT MC_(Malloc_Redzone_SzB);
     51 
     52 /* For malloc()/new/new[] vs. free()/delete/delete[] mismatch checking. */
     53 typedef
     54    enum {
     55       MC_AllocMalloc = 0,
     56       MC_AllocNew    = 1,
     57       MC_AllocNewVec = 2,
     58       MC_AllocCustom = 3
     59    }
     60    MC_AllocKind;
     61 
     62 /* This describes a heap block. Nb: first two fields must match core's
     63  * VgHashNode. */
     64 typedef
     65    struct _MC_Chunk {
     66       struct _MC_Chunk* next;
     67       Addr         data;            // Address of the actual block.
     68       SizeT        szB : (sizeof(SizeT)*8)-2; // Size requested; 30 or 62 bits.
     69       MC_AllocKind allockind : 2;   // Which operation did the allocation.
     70       ExeContext*  where;           // Where it was allocated.
     71    }
     72    MC_Chunk;
     73 
     74 /* Memory pool.  Nb: first two fields must match core's VgHashNode. */
     75 typedef
     76    struct _MC_Mempool {
     77       struct _MC_Mempool* next;
     78       Addr          pool;           // pool identifier
     79       SizeT         rzB;            // pool red-zone size
     80       Bool          is_zeroed;      // allocations from this pool are zeroed
     81       VgHashTable   chunks;         // chunks associated with this pool
     82    }
     83    MC_Mempool;
     84 
     85 
     86 void* MC_(new_block)  ( ThreadId tid,
     87                         Addr p, SizeT size, SizeT align,
     88                         Bool is_zeroed, MC_AllocKind kind,
     89                         VgHashTable table);
     90 void MC_(handle_free) ( ThreadId tid,
     91                         Addr p, UInt rzB, MC_AllocKind kind );
     92 
     93 void MC_(create_mempool)  ( Addr pool, UInt rzB, Bool is_zeroed );
     94 void MC_(destroy_mempool) ( Addr pool );
     95 void MC_(mempool_alloc)   ( ThreadId tid, Addr pool,
     96                             Addr addr, SizeT size );
     97 void MC_(mempool_free)    ( Addr pool, Addr addr );
     98 void MC_(mempool_trim)    ( Addr pool, Addr addr, SizeT size );
     99 void MC_(move_mempool)    ( Addr poolA, Addr poolB );
    100 void MC_(mempool_change)  ( Addr pool, Addr addrA, Addr addrB, SizeT size );
    101 Bool MC_(mempool_exists)  ( Addr pool );
    102 
    103 /* Searches for a recently freed block which might bracket Addr a.
    104    Return the MC_Chunk* for this block or NULL if no bracketting block
    105    is found. */
    106 MC_Chunk* MC_(get_freed_block_bracketting)( Addr a );
    107 
    108 /* For efficient pooled alloc/free of the MC_Chunk. */
    109 extern PoolAlloc* MC_(chunk_poolalloc);
    110 
    111 /* For tracking malloc'd blocks.  Nb: it's quite important that it's a
    112    VgHashTable, because VgHashTable allows duplicate keys without complaint.
    113    This can occur if a user marks a malloc() block as also a custom block with
    114    MALLOCLIKE_BLOCK. */
    115 extern VgHashTable MC_(malloc_list);
    116 
    117 /* For tracking memory pools. */
    118 extern VgHashTable MC_(mempool_list);
    119 
    120 /* Shadow memory functions */
    121 Bool MC_(check_mem_is_noaccess)( Addr a, SizeT len, Addr* bad_addr );
    122 void MC_(make_mem_noaccess)        ( Addr a, SizeT len );
    123 void MC_(make_mem_undefined_w_otag)( Addr a, SizeT len, UInt otag );
    124 void MC_(make_mem_defined)         ( Addr a, SizeT len );
    125 void MC_(copy_address_range_state) ( Addr src, Addr dst, SizeT len );
    126 
    127 void MC_(print_malloc_stats) ( void );
    128 /* nr of free operations done */
    129 SizeT MC_(get_cmalloc_n_frees) ( void );
    130 
    131 void* MC_(malloc)               ( ThreadId tid, SizeT n );
    132 void* MC_(__builtin_new)        ( ThreadId tid, SizeT n );
    133 void* MC_(__builtin_vec_new)    ( ThreadId tid, SizeT n );
    134 void* MC_(memalign)             ( ThreadId tid, SizeT align, SizeT n );
    135 void* MC_(calloc)               ( ThreadId tid, SizeT nmemb, SizeT size1 );
    136 void  MC_(free)                 ( ThreadId tid, void* p );
    137 void  MC_(__builtin_delete)     ( ThreadId tid, void* p );
    138 void  MC_(__builtin_vec_delete) ( ThreadId tid, void* p );
    139 void* MC_(realloc)              ( ThreadId tid, void* p, SizeT new_size );
    140 SizeT MC_(malloc_usable_size)   ( ThreadId tid, void* p );
    141 
    142 void MC_(handle_resizeInPlace)(ThreadId tid, Addr p,
    143                                SizeT oldSizeB, SizeT newSizeB, SizeT rzB);
    144 
    145 
    146 /*------------------------------------------------------------*/
    147 /*--- Origin tracking translate-time support               ---*/
    148 /*------------------------------------------------------------*/
    149 
    150 /* See detailed comments in mc_machine.c. */
    151 Int MC_(get_otrack_shadow_offset) ( Int offset, Int szB );
    152 IRType MC_(get_otrack_reg_array_equiv_int_type) ( IRRegArray* arr );
    153 
    154 /* Constants which are used as the lowest 2 bits in origin tags.
    155 
    156    An origin tag comprises an upper 30-bit ECU field and a lower 2-bit
    157    'kind' field.  The ECU field is a number given out by m_execontext
    158    and has a 1-1 mapping with ExeContext*s.  An ECU can be used
    159    directly as an origin tag (otag), but in fact we want to put
    160    additional information 'kind' field to indicate roughly where the
    161    tag came from.  This helps print more understandable error messages
    162    for the user -- it has no other purpose.
    163 
    164    Hence the following 2-bit constants are needed for 'kind' field.
    165 
    166    To summarise:
    167 
    168    * Both ECUs and origin tags are represented as 32-bit words
    169 
    170    * m_execontext and the core-tool interface deal purely in ECUs.
    171      They have no knowledge of origin tags - that is a purely
    172      Memcheck-internal matter.
    173 
    174    * all valid ECUs have the lowest 2 bits zero and at least
    175      one of the upper 30 bits nonzero (see VG_(is_plausible_ECU))
    176 
    177    * to convert from an ECU to an otag, OR in one of the MC_OKIND_
    178      constants below
    179 
    180    * to convert an otag back to an ECU, AND it with ~3
    181 */
    182 
    183 #define MC_OKIND_UNKNOWN  0  /* unknown origin */
    184 #define MC_OKIND_HEAP     1  /* this is a heap origin */
    185 #define MC_OKIND_STACK    2  /* this is a stack origin */
    186 #define MC_OKIND_USER     3  /* arises from user-supplied client req */
    187 
    188 
    189 /*------------------------------------------------------------*/
    190 /*--- Profiling of memory events                           ---*/
    191 /*------------------------------------------------------------*/
    192 
    193 /* Define to collect detailed performance info. */
    194 /* #define MC_PROFILE_MEMORY */
    195 
    196 #ifdef MC_PROFILE_MEMORY
    197 #  define N_PROF_EVENTS 500
    198 
    199 UInt   MC_(event_ctr)[N_PROF_EVENTS];
    200 HChar* MC_(event_ctr_name)[N_PROF_EVENTS];
    201 
    202 #  define PROF_EVENT(ev, name)                                \
    203    do { tl_assert((ev) >= 0 && (ev) < N_PROF_EVENTS);         \
    204         /* crude and inaccurate check to ensure the same */   \
    205         /* event isn't being used with > 1 name */            \
    206         if (MC_(event_ctr_name)[ev])                         \
    207            tl_assert(name == MC_(event_ctr_name)[ev]);       \
    208         MC_(event_ctr)[ev]++;                                \
    209         MC_(event_ctr_name)[ev] = (name);                    \
    210    } while (False);
    211 
    212 #else
    213 
    214 #  define PROF_EVENT(ev, name) /* */
    215 
    216 #endif   /* MC_PROFILE_MEMORY */
    217 
    218 
    219 /*------------------------------------------------------------*/
    220 /*--- V and A bits (Victoria & Albert ?)                   ---*/
    221 /*------------------------------------------------------------*/
    222 
    223 /* The number of entries in the primary map can be altered.  However
    224    we hardwire the assumption that each secondary map covers precisely
    225    64k of address space. */
    226 #define SM_SIZE 65536            /* DO NOT CHANGE */
    227 #define SM_MASK (SM_SIZE-1)      /* DO NOT CHANGE */
    228 
    229 #define V_BIT_DEFINED         0
    230 #define V_BIT_UNDEFINED       1
    231 
    232 #define V_BITS8_DEFINED       0
    233 #define V_BITS8_UNDEFINED     0xFF
    234 
    235 #define V_BITS16_DEFINED      0
    236 #define V_BITS16_UNDEFINED    0xFFFF
    237 
    238 #define V_BITS32_DEFINED      0
    239 #define V_BITS32_UNDEFINED    0xFFFFFFFF
    240 
    241 #define V_BITS64_DEFINED      0ULL
    242 #define V_BITS64_UNDEFINED    0xFFFFFFFFFFFFFFFFULL
    243 
    244 
    245 /*------------------------------------------------------------*/
    246 /*--- Leak checking                                        ---*/
    247 /*------------------------------------------------------------*/
    248 
    249 typedef
    250    enum {
    251       // Nb: the order is important -- it dictates the order of loss records
    252       // of equal sizes.
    253       Reachable    =0,  // Definitely reachable from root-set.
    254       Possible     =1,  // Possibly reachable from root-set;  involves at
    255                         //   least one interior-pointer along the way.
    256       IndirectLeak =2,  // Leaked, but reachable from another leaked block
    257                         //   (be it Unreached or IndirectLeak).
    258       Unreached    =3,  // Not reached, ie. leaked.
    259                         //   (At best, only reachable from itself via a cycle.)
    260   }
    261   Reachedness;
    262 
    263 
    264 /* For VALGRIND_COUNT_LEAKS client request */
    265 extern SizeT MC_(bytes_leaked);
    266 extern SizeT MC_(bytes_indirect);
    267 extern SizeT MC_(bytes_dubious);
    268 extern SizeT MC_(bytes_reachable);
    269 extern SizeT MC_(bytes_suppressed);
    270 
    271 /* For VALGRIND_COUNT_LEAK_BLOCKS client request */
    272 extern SizeT MC_(blocks_leaked);
    273 extern SizeT MC_(blocks_indirect);
    274 extern SizeT MC_(blocks_dubious);
    275 extern SizeT MC_(blocks_reachable);
    276 extern SizeT MC_(blocks_suppressed);
    277 
    278 typedef
    279    enum {
    280       LC_Off,
    281       LC_Summary,
    282       LC_Full,
    283    }
    284    LeakCheckMode;
    285 
    286 typedef
    287    enum {
    288       LCD_Any,       // output all loss records, whatever the delta
    289       LCD_Increased, // output loss records with an increase in size or blocks
    290       LCD_Changed,   // output loss records with an increase or
    291                      //decrease in size or blocks
    292    }
    293    LeakCheckDeltaMode;
    294 
    295 /* When a LossRecord is put into an OSet, these elements represent the key. */
    296 typedef
    297    struct _LossRecordKey {
    298       Reachedness  state;        // LC_Extra.state value shared by all blocks.
    299       ExeContext*  allocated_at; // Where they were allocated.
    300    }
    301    LossRecordKey;
    302 
    303 /* A loss record, used for generating err msgs.  Multiple leaked blocks can be
    304  * merged into a single loss record if they have the same state and similar
    305  * enough allocation points (controlled by --leak-resolution). */
    306 typedef
    307    struct _LossRecord {
    308       LossRecordKey key;  // Key, when used in an OSet.
    309       SizeT szB;          // Sum of all MC_Chunk.szB values.
    310       SizeT indirect_szB; // Sum of all LC_Extra.indirect_szB values.
    311       UInt  num_blocks;   // Number of blocks represented by the record.
    312       SizeT old_szB;          // old_* values are the values found during the
    313       SizeT old_indirect_szB; // previous leak search. old_* values are used to
    314       UInt  old_num_blocks;   // output only the changed/new loss records
    315    }
    316    LossRecord;
    317 
    318 typedef
    319    struct _LeakCheckParams {
    320       LeakCheckMode mode;
    321       Bool show_reachable;
    322       Bool show_possibly_lost;
    323       LeakCheckDeltaMode deltamode;
    324       UInt max_loss_records_output;       // limit on the nr of loss records output.
    325       Bool requested_by_monitor_command; // True when requested by gdb/vgdb.
    326    }
    327    LeakCheckParams;
    328 
    329 void MC_(detect_memory_leaks) ( ThreadId tid, LeakCheckParams * lcp);
    330 
    331 // maintains the lcp.deltamode given in the last call to detect_memory_leaks
    332 extern LeakCheckDeltaMode MC_(detect_memory_leaks_last_delta_mode);
    333 
    334 // prints the list of blocks corresponding to the given loss_record_nr.
    335 // Returns True if loss_record_nr identifies a correct loss record from last leak search.
    336 // Returns False otherwise.
    337 Bool MC_(print_block_list) ( UInt loss_record_nr);
    338 
    339 // Prints the addresses/registers/... at which a pointer to
    340 // the given range [address, address+szB[ is found.
    341 void MC_(who_points_at) ( Addr address, SizeT szB);
    342 
    343 // if delta_mode == LCD_Any, prints in buf an empty string
    344 // otherwise prints a delta in the layout  " (+%'lu)" or " (-%'lu)"
    345 extern char * MC_(snprintf_delta) (char * buf, Int size,
    346                                    SizeT current_val, SizeT old_val,
    347                                    LeakCheckDeltaMode delta_mode);
    348 
    349 
    350 Bool MC_(is_valid_aligned_word)     ( Addr a );
    351 Bool MC_(is_within_valid_secondary) ( Addr a );
    352 
    353 // Prints as user msg a description of the given loss record.
    354 void MC_(pp_LossRecord)(UInt n_this_record, UInt n_total_records,
    355                         LossRecord* l);
    356 
    357 
    358 /*------------------------------------------------------------*/
    359 /*--- Errors and suppressions                              ---*/
    360 /*------------------------------------------------------------*/
    361 
    362 /* Did we show to the user, any errors for which an uninitialised
    363    value origin could have been collected (but wasn't) ?  If yes,
    364    then, at the end of the run, print a 1 line message advising that a
    365    rerun with --track-origins=yes might help. */
    366 extern Bool MC_(any_value_errors);
    367 
    368 /* Standard functions for error and suppressions as required by the
    369    core/tool iface */
    370 Bool MC_(eq_Error)           ( VgRes res, Error* e1, Error* e2 );
    371 void MC_(before_pp_Error)    ( Error* err );
    372 void MC_(pp_Error)           ( Error* err );
    373 UInt MC_(update_Error_extra) ( Error* err );
    374 
    375 Bool MC_(is_recognised_suppression) ( Char* name, Supp* su );
    376 
    377 Bool MC_(read_extra_suppression_info) ( Int fd, Char** buf,
    378                                         SizeT* nBuf, Supp *su );
    379 
    380 Bool MC_(error_matches_suppression) ( Error* err, Supp* su );
    381 
    382 Bool MC_(get_extra_suppression_info) ( Error* err,
    383                                        /*OUT*/Char* buf, Int nBuf );
    384 
    385 Char* MC_(get_error_name) ( Error* err );
    386 
    387 /* Recording of errors */
    388 void MC_(record_address_error) ( ThreadId tid, Addr a, Int szB,
    389                                  Bool isWrite );
    390 void MC_(record_cond_error)    ( ThreadId tid, UInt otag );
    391 void MC_(record_value_error)   ( ThreadId tid, Int szB, UInt otag );
    392 void MC_(record_jump_error)    ( ThreadId tid, Addr a );
    393 
    394 void MC_(record_free_error)            ( ThreadId tid, Addr a );
    395 void MC_(record_illegal_mempool_error) ( ThreadId tid, Addr a );
    396 void MC_(record_freemismatch_error)    ( ThreadId tid, MC_Chunk* mc );
    397 
    398 void MC_(record_overlap_error)  ( ThreadId tid, Char* function,
    399                                   Addr src, Addr dst, SizeT szB );
    400 void MC_(record_core_mem_error) ( ThreadId tid, Char* msg );
    401 void MC_(record_regparam_error) ( ThreadId tid, Char* msg, UInt otag );
    402 void MC_(record_memparam_error) ( ThreadId tid, Addr a,
    403                                   Bool isAddrErr, Char* msg, UInt otag );
    404 void MC_(record_user_error)     ( ThreadId tid, Addr a,
    405                                   Bool isAddrErr, UInt otag );
    406 
    407 Bool MC_(record_leak_error)     ( ThreadId tid,
    408                                   UInt n_this_record,
    409                                   UInt n_total_records,
    410                                   LossRecord* lossRecord,
    411                                   Bool print_record,
    412                                   Bool count_error );
    413 
    414 /* prints a description of address a */
    415 void MC_(pp_describe_addr) (Addr a);
    416 
    417 /* Is this address in a user-specified "ignored range" ? */
    418 Bool MC_(in_ignored_range) ( Addr a );
    419 
    420 
    421 /*------------------------------------------------------------*/
    422 /*--- Client blocks                                        ---*/
    423 /*------------------------------------------------------------*/
    424 
    425 /* Describes a client block.  See mc_main.c.  An unused block has
    426    start == size == 0.  */
    427 typedef
    428    struct {
    429       Addr        start;
    430       SizeT       size;
    431       ExeContext* where;
    432       Char*       desc;
    433    }
    434    CGenBlock;
    435 
    436 /* Get access to the client block array. */
    437 void MC_(get_ClientBlock_array)( /*OUT*/CGenBlock** blocks,
    438                                  /*OUT*/UWord* nBlocks );
    439 
    440 
    441 /*------------------------------------------------------------*/
    442 /*--- Command line options + defaults                      ---*/
    443 /*------------------------------------------------------------*/
    444 
    445 /* Allow loads from partially-valid addresses?  default: YES */
    446 extern Bool MC_(clo_partial_loads_ok);
    447 
    448 /* Max volume of the freed blocks queue. */
    449 extern Long MC_(clo_freelist_vol);
    450 
    451 /* Blocks with a size >= MC_(clo_freelist_big_blocks) will be put
    452    in the "big block" freed blocks queue. */
    453 extern Long MC_(clo_freelist_big_blocks);
    454 
    455 /* Do leak check at exit?  default: NO */
    456 extern LeakCheckMode MC_(clo_leak_check);
    457 
    458 /* How closely should we compare ExeContexts in leak records? default: 2 */
    459 extern VgRes MC_(clo_leak_resolution);
    460 
    461 /* In leak check, show reachable-but-not-freed blocks?  default: NO */
    462 extern Bool MC_(clo_show_reachable);
    463 
    464 /* In leak check, show possibly-lost blocks?  default: YES */
    465 extern Bool MC_(clo_show_possibly_lost);
    466 
    467 /* Assume accesses immediately below %esp are due to gcc-2.96 bugs.
    468  * default: NO */
    469 extern Bool MC_(clo_workaround_gcc296_bugs);
    470 
    471 /* Fill malloc-d/free-d client blocks with a specific value?  -1 if
    472    not, else 0x00 .. 0xFF indicating the fill value to use.  Can be
    473    useful for causing programs with bad heap corruption to fail in
    474    more repeatable ways.  Note that malloc-filled and free-filled
    475    areas are still undefined and noaccess respectively.  This merely
    476    causes them to contain the specified values. */
    477 extern Int MC_(clo_malloc_fill);
    478 extern Int MC_(clo_free_fill);
    479 
    480 /* Indicates the level of instrumentation/checking done by Memcheck.
    481 
    482    1 = No undefined value checking, Addrcheck-style behaviour only:
    483        only address checking is done.  This is faster but finds fewer
    484        errors.  Note that although Addrcheck had 1 bit per byte
    485        overhead vs the old Memcheck's 9 bits per byte, with this mode
    486        and compressed V bits, no memory is saved with this mode --
    487        it's still 2 bits per byte overhead.  This is a little wasteful
    488        -- it could be done with 1 bit per byte -- but lets us reuse
    489        the many shadow memory access functions.  Note that in this
    490        mode neither the secondary V bit table nor the origin-tag cache
    491        are used.
    492 
    493    2 = Address checking and Undefined value checking are performed,
    494        but origins are not tracked.  So the origin-tag cache is not
    495        used in this mode.  This setting is the default and corresponds
    496        to the "normal" Memcheck behaviour that has shipped for years.
    497 
    498    3 = Address checking, undefined value checking, and origins for
    499        undefined values are tracked.
    500 
    501    The default is 2.
    502 */
    503 extern Int MC_(clo_mc_level);
    504 
    505 
    506 /*------------------------------------------------------------*/
    507 /*--- Instrumentation                                      ---*/
    508 /*------------------------------------------------------------*/
    509 
    510 /* Functions defined in mc_main.c */
    511 
    512 /* For the fail_w_o functions, the UWord arg is actually the 32-bit
    513    origin tag and should really be UInt, but to be simple and safe
    514    considering it's called from generated code, just claim it to be a
    515    UWord. */
    516 VG_REGPARM(2) void MC_(helperc_value_checkN_fail_w_o) ( HWord, UWord );
    517 VG_REGPARM(1) void MC_(helperc_value_check8_fail_w_o) ( UWord );
    518 VG_REGPARM(1) void MC_(helperc_value_check4_fail_w_o) ( UWord );
    519 VG_REGPARM(1) void MC_(helperc_value_check1_fail_w_o) ( UWord );
    520 VG_REGPARM(1) void MC_(helperc_value_check0_fail_w_o) ( UWord );
    521 
    522 /* And call these ones instead to report an uninitialised value error
    523    but with no origin available. */
    524 VG_REGPARM(1) void MC_(helperc_value_checkN_fail_no_o) ( HWord );
    525 VG_REGPARM(0) void MC_(helperc_value_check8_fail_no_o) ( void );
    526 VG_REGPARM(0) void MC_(helperc_value_check4_fail_no_o) ( void );
    527 VG_REGPARM(0) void MC_(helperc_value_check1_fail_no_o) ( void );
    528 VG_REGPARM(0) void MC_(helperc_value_check0_fail_no_o) ( void );
    529 
    530 /* V-bits load/store helpers */
    531 VG_REGPARM(1) void MC_(helperc_STOREV64be) ( Addr, ULong );
    532 VG_REGPARM(1) void MC_(helperc_STOREV64le) ( Addr, ULong );
    533 VG_REGPARM(2) void MC_(helperc_STOREV32be) ( Addr, UWord );
    534 VG_REGPARM(2) void MC_(helperc_STOREV32le) ( Addr, UWord );
    535 VG_REGPARM(2) void MC_(helperc_STOREV16be) ( Addr, UWord );
    536 VG_REGPARM(2) void MC_(helperc_STOREV16le) ( Addr, UWord );
    537 VG_REGPARM(2) void MC_(helperc_STOREV8)   ( Addr, UWord );
    538 
    539 VG_REGPARM(1) ULong MC_(helperc_LOADV64be) ( Addr );
    540 VG_REGPARM(1) ULong MC_(helperc_LOADV64le) ( Addr );
    541 VG_REGPARM(1) UWord MC_(helperc_LOADV32be) ( Addr );
    542 VG_REGPARM(1) UWord MC_(helperc_LOADV32le) ( Addr );
    543 VG_REGPARM(1) UWord MC_(helperc_LOADV16be) ( Addr );
    544 VG_REGPARM(1) UWord MC_(helperc_LOADV16le) ( Addr );
    545 VG_REGPARM(1) UWord MC_(helperc_LOADV8)    ( Addr );
    546 
    547 void MC_(helperc_MAKE_STACK_UNINIT) ( Addr base, UWord len,
    548                                                  Addr nia );
    549 
    550 /* Origin tag load/store helpers */
    551 VG_REGPARM(2) void  MC_(helperc_b_store1) ( Addr a, UWord d32 );
    552 VG_REGPARM(2) void  MC_(helperc_b_store2) ( Addr a, UWord d32 );
    553 VG_REGPARM(2) void  MC_(helperc_b_store4) ( Addr a, UWord d32 );
    554 VG_REGPARM(2) void  MC_(helperc_b_store8) ( Addr a, UWord d32 );
    555 VG_REGPARM(2) void  MC_(helperc_b_store16)( Addr a, UWord d32 );
    556 VG_REGPARM(2) void  MC_(helperc_b_store32)( Addr a, UWord d32 );
    557 VG_REGPARM(1) UWord MC_(helperc_b_load1) ( Addr a );
    558 VG_REGPARM(1) UWord MC_(helperc_b_load2) ( Addr a );
    559 VG_REGPARM(1) UWord MC_(helperc_b_load4) ( Addr a );
    560 VG_REGPARM(1) UWord MC_(helperc_b_load8) ( Addr a );
    561 VG_REGPARM(1) UWord MC_(helperc_b_load16)( Addr a );
    562 VG_REGPARM(1) UWord MC_(helperc_b_load32)( Addr a );
    563 
    564 /* Functions defined in mc_translate.c */
    565 IRSB* MC_(instrument) ( VgCallbackClosure* closure,
    566                         IRSB* bb_in,
    567                         VexGuestLayout* layout,
    568                         VexGuestExtents* vge,
    569                         IRType gWordTy, IRType hWordTy );
    570 
    571 IRSB* MC_(final_tidy) ( IRSB* );
    572 
    573 #endif /* ndef __MC_INCLUDE_H */
    574 
    575 /*--------------------------------------------------------------------*/
    576 /*--- end                                                          ---*/
    577 /*--------------------------------------------------------------------*/
    578