Home | History | Annotate | Download | only in coregrind
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- Stuff relating to tool data structures.                      ---*/
      4 /*---                                                m_tooliface.c ---*/
      5 /*--------------------------------------------------------------------*/
      6 
      7 /*
      8    This file is part of Valgrind, a dynamic binary instrumentation
      9    framework.
     10 
     11    Copyright (C) 2000-2012 Nicholas Nethercote
     12       njn (at) valgrind.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 #include "pub_core_basics.h"
     33 #include "pub_core_tooliface.h"
     34 
     35 // The core/tool dictionary of functions (initially zeroed, as we want it)
     36 VgToolInterface VG_(tdict);
     37 
     38 /*--------------------------------------------------------------------*/
     39 /* Setting basic functions */
     40 
     41 void VG_(basic_tool_funcs)(
     42    void(*post_clo_init)(void),
     43    IRSB*(*instrument)(VgCallbackClosure*, IRSB*,
     44                       VexGuestLayout*, VexGuestExtents*, IRType, IRType),
     45    void(*fini)(Int)
     46 )
     47 {
     48    VG_(tdict).tool_post_clo_init = post_clo_init;
     49    VG_(tdict).tool_instrument    = instrument;
     50    VG_(tdict).tool_fini          = fini;
     51 }
     52 
     53 
     54 /*--------------------------------------------------------------------*/
     55 /* Setting details */
     56 
     57 /* Init with default values. */
     58 VgDetails VG_(details) = {
     59    .name                  = NULL,
     60    .version               = NULL,
     61    .description           = NULL,
     62    .copyright_author      = NULL,
     63    .bug_reports_to        = NULL,
     64    .avg_translation_sizeB = VG_DEFAULT_TRANS_SIZEB,
     65 };
     66 
     67 /* Use macro because they're so repetitive */
     68 #define DETAILS(type, detail)                       \
     69    extern void VG_(details_##detail)(type detail)   \
     70    {                                                \
     71       VG_(details).detail = detail;                 \
     72    }
     73 
     74 DETAILS(Char*, name)
     75 DETAILS(Char*, version)
     76 DETAILS(Char*, description)
     77 DETAILS(Char*, copyright_author)
     78 DETAILS(Char*, bug_reports_to)
     79 DETAILS(UInt,  avg_translation_sizeB)
     80 
     81 
     82 /*--------------------------------------------------------------------*/
     83 /* Setting needs */
     84 
     85 VgNeeds VG_(needs) = {
     86    .core_errors          = False,
     87    .tool_errors          = False,
     88    .libc_freeres         = False,
     89    .superblock_discards  = False,
     90    .command_line_options = False,
     91    .client_requests      = False,
     92    .syscall_wrapper      = False,
     93    .sanity_checks        = False,
     94    .var_info	         = False,
     95    .malloc_replacement   = False,
     96    .xml_output           = False,
     97    .final_IR_tidy_pass   = False
     98 };
     99 
    100 /* static */
    101 Bool VG_(sanity_check_needs)(Char** failmsg)
    102 {
    103    Bool any_new_mem_stack_N, any_new_mem_stack_N_w_ECU;
    104    Bool any_new_mem_stack_w_conflicting_otags;
    105    Bool any_die_mem_stack_N;
    106 
    107 #define CHECK_NOT(var, value)                                  \
    108    if ((var)==(value)) {                                       \
    109       *failmsg = "Tool error: '" #var "' not initialised\n";   \
    110       return False;                                            \
    111    }
    112 
    113    /* Ones that must be set */
    114    CHECK_NOT(VG_(details).name,             NULL);
    115    /* Nb: .version can be NULL */
    116    CHECK_NOT(VG_(details).description,      NULL);
    117    CHECK_NOT(VG_(details).copyright_author, NULL);
    118    CHECK_NOT(VG_(details).bug_reports_to,   NULL);
    119 
    120    /* Check that new_mem_stack is defined if any new_mem_stack_N
    121       are. */
    122    any_new_mem_stack_N
    123       = VG_(tdict).track_new_mem_stack_4   ||
    124         VG_(tdict).track_new_mem_stack_8   ||
    125         VG_(tdict).track_new_mem_stack_12  ||
    126         VG_(tdict).track_new_mem_stack_16  ||
    127         VG_(tdict).track_new_mem_stack_32  ||
    128         VG_(tdict).track_new_mem_stack_112 ||
    129         VG_(tdict).track_new_mem_stack_128 ||
    130         VG_(tdict).track_new_mem_stack_144 ||
    131         VG_(tdict).track_new_mem_stack_160;
    132 
    133    if (any_new_mem_stack_N && ! VG_(tdict).track_new_mem_stack) {
    134       *failmsg = "Tool error: one of the specialised 'new_mem_stack_N'\n"
    135                  "   events tracked, but not the generic 'new_mem_stack' one.\n"
    136                  "   'new_mem_stack' should be defined\n";
    137       return False;
    138    }
    139 
    140    /* Check that new_mem_stack_w_ECU is defined if any
    141       new_mem_stack_N_w_ECU are. */
    142    any_new_mem_stack_N_w_ECU
    143       = VG_(tdict).track_new_mem_stack_4_w_ECU   ||
    144         VG_(tdict).track_new_mem_stack_8_w_ECU   ||
    145         VG_(tdict).track_new_mem_stack_12_w_ECU  ||
    146         VG_(tdict).track_new_mem_stack_16_w_ECU  ||
    147         VG_(tdict).track_new_mem_stack_32_w_ECU  ||
    148         VG_(tdict).track_new_mem_stack_112_w_ECU ||
    149         VG_(tdict).track_new_mem_stack_128_w_ECU ||
    150         VG_(tdict).track_new_mem_stack_144_w_ECU ||
    151         VG_(tdict).track_new_mem_stack_160_w_ECU;
    152 
    153    if (any_new_mem_stack_N_w_ECU && ! VG_(tdict).track_new_mem_stack_w_ECU) {
    154       *failmsg = "Tool error: one of the specialised 'new_mem_stack_N_w_ECU'\n"
    155                  "   events tracked, but not the generic 'new_mem_stack_w_ECU' one.\n"
    156                  "   'new_mem_stack_w_ECU' should be defined\n";
    157       return False;
    158    }
    159 
    160    /* Check that in no cases are both with- and without-otag versions of the
    161       same new_mem_stack_ function defined. */
    162    any_new_mem_stack_w_conflicting_otags
    163       = (VG_(tdict).track_new_mem_stack_4   && VG_(tdict).track_new_mem_stack_4_w_ECU)   ||
    164         (VG_(tdict).track_new_mem_stack_8   && VG_(tdict).track_new_mem_stack_8_w_ECU)   ||
    165         (VG_(tdict).track_new_mem_stack_12  && VG_(tdict).track_new_mem_stack_12_w_ECU)  ||
    166         (VG_(tdict).track_new_mem_stack_16  && VG_(tdict).track_new_mem_stack_16_w_ECU)  ||
    167         (VG_(tdict).track_new_mem_stack_32  && VG_(tdict).track_new_mem_stack_32_w_ECU)  ||
    168         (VG_(tdict).track_new_mem_stack_112 && VG_(tdict).track_new_mem_stack_112_w_ECU) ||
    169         (VG_(tdict).track_new_mem_stack_128 && VG_(tdict).track_new_mem_stack_128_w_ECU) ||
    170         (VG_(tdict).track_new_mem_stack_144 && VG_(tdict).track_new_mem_stack_144_w_ECU) ||
    171         (VG_(tdict).track_new_mem_stack_160 && VG_(tdict).track_new_mem_stack_160_w_ECU) ||
    172         (VG_(tdict).track_new_mem_stack     && VG_(tdict).track_new_mem_stack_w_ECU);
    173 
    174    if (any_new_mem_stack_w_conflicting_otags) {
    175       *failmsg = "Tool error: tool supplies both a 'new_mem_stack_N' and a\n"
    176                  "   'new_mem_stack_N_w_ECU' function for some N (or none),\n"
    177                  "   but you can only have one or the other (not both)\n";
    178       return False;
    179    }
    180 
    181    /* Check that die_mem_stack is defined if any die_mem_stack_N
    182       are. */
    183    any_die_mem_stack_N
    184       = VG_(tdict).track_die_mem_stack_4   ||
    185         VG_(tdict).track_die_mem_stack_8   ||
    186         VG_(tdict).track_die_mem_stack_12  ||
    187         VG_(tdict).track_die_mem_stack_16  ||
    188         VG_(tdict).track_die_mem_stack_32  ||
    189         VG_(tdict).track_die_mem_stack_112 ||
    190         VG_(tdict).track_die_mem_stack_128 ||
    191         VG_(tdict).track_die_mem_stack_144 ||
    192         VG_(tdict).track_die_mem_stack_160;
    193 
    194     if (any_die_mem_stack_N && ! VG_(tdict).track_die_mem_stack) {
    195       *failmsg = "Tool error: one of the specialised 'die_mem_stack_N'\n"
    196                  "   events tracked, but not the generic 'die_mem_stack' one.\n"
    197                  "   'die_mem_stack' should be defined\n";
    198       return False;
    199    }
    200 
    201    return True;
    202 
    203 #undef CHECK_NOT
    204 }
    205 
    206 /* Use macro because they're so repetitive */
    207 #define NEEDS(need)  \
    208    extern void VG_(needs_##need)(void) \
    209    {                                   \
    210       VG_(needs).need = True;          \
    211    }
    212 
    213 // These ones don't require any tool-supplied functions
    214 NEEDS(libc_freeres)
    215 NEEDS(core_errors)
    216 NEEDS(var_info)
    217 
    218 void VG_(needs_superblock_discards)(
    219    void (*discard)(Addr64, VexGuestExtents)
    220 )
    221 {
    222    VG_(needs).superblock_discards = True;
    223    VG_(tdict).tool_discard_superblock_info = discard;
    224 }
    225 
    226 void VG_(needs_tool_errors)(
    227    Bool (*eq)         (VgRes, Error*, Error*),
    228    void (*before_pp)  (Error*),
    229    void (*pp)         (Error*),
    230    Bool show_TIDs,
    231    UInt (*update)     (Error*),
    232    Bool (*recog)      (Char*, Supp*),
    233    Bool (*read_extra) (Int, Char**, SizeT*, Supp*),
    234    Bool (*matches)    (Error*, Supp*),
    235    Char* (*name)      (Error*),
    236    Bool (*get_xtra_si)(Error*,/*OUT*/Char*,Int)
    237 )
    238 {
    239    VG_(needs).tool_errors = True;
    240    VG_(tdict).tool_eq_Error                     = eq;
    241    VG_(tdict).tool_before_pp_Error              = before_pp;
    242    VG_(tdict).tool_pp_Error                     = pp;
    243    VG_(tdict).tool_show_ThreadIDs_for_errors    = show_TIDs;
    244    VG_(tdict).tool_update_extra                 = update;
    245    VG_(tdict).tool_recognised_suppression       = recog;
    246    VG_(tdict).tool_read_extra_suppression_info  = read_extra;
    247    VG_(tdict).tool_error_matches_suppression    = matches;
    248    VG_(tdict).tool_get_error_name               = name;
    249    VG_(tdict).tool_get_extra_suppression_info   = get_xtra_si;
    250 }
    251 
    252 void VG_(needs_command_line_options)(
    253    Bool (*process)(Char*),
    254    void (*usage)(void),
    255    void (*debug_usage)(void)
    256 )
    257 {
    258    VG_(needs).command_line_options = True;
    259    VG_(tdict).tool_process_cmd_line_option = process;
    260    VG_(tdict).tool_print_usage             = usage;
    261    VG_(tdict).tool_print_debug_usage       = debug_usage;
    262 }
    263 
    264 void VG_(needs_client_requests)(
    265    Bool (*handle)(ThreadId, UWord*, UWord*)
    266 )
    267 {
    268    VG_(needs).client_requests = True;
    269    VG_(tdict).tool_handle_client_request = handle;
    270 }
    271 
    272 void VG_(needs_syscall_wrapper)(
    273    void(*pre) (ThreadId, UInt, UWord*, UInt),
    274    void(*post)(ThreadId, UInt, UWord*, UInt, SysRes res)
    275 )
    276 {
    277    VG_(needs).syscall_wrapper = True;
    278    VG_(tdict).tool_pre_syscall  = pre;
    279    VG_(tdict).tool_post_syscall = post;
    280 }
    281 
    282 void VG_(needs_sanity_checks)(
    283    Bool(*cheap)(void),
    284    Bool(*expen)(void)
    285 )
    286 {
    287    VG_(needs).sanity_checks = True;
    288    VG_(tdict).tool_cheap_sanity_check     = cheap;
    289    VG_(tdict).tool_expensive_sanity_check = expen;
    290 }
    291 
    292 void VG_(needs_malloc_replacement)(
    293    void* (*malloc)               ( ThreadId, SizeT ),
    294    void* (*__builtin_new)        ( ThreadId, SizeT ),
    295    void* (*__builtin_vec_new)    ( ThreadId, SizeT ),
    296    void* (*memalign)             ( ThreadId, SizeT, SizeT ),
    297    void* (*calloc)               ( ThreadId, SizeT, SizeT ),
    298    void  (*free)                 ( ThreadId, void* ),
    299    void  (*__builtin_delete)     ( ThreadId, void* ),
    300    void  (*__builtin_vec_delete) ( ThreadId, void* ),
    301    void* (*realloc)              ( ThreadId, void*, SizeT ),
    302    SizeT (*malloc_usable_size)   ( ThreadId, void* ),
    303    SizeT client_malloc_redzone_szB
    304 )
    305 {
    306    VG_(needs).malloc_replacement        = True;
    307    VG_(tdict).tool_malloc               = malloc;
    308    VG_(tdict).tool___builtin_new        = __builtin_new;
    309    VG_(tdict).tool___builtin_vec_new    = __builtin_vec_new;
    310    VG_(tdict).tool_memalign             = memalign;
    311    VG_(tdict).tool_calloc               = calloc;
    312    VG_(tdict).tool_free                 = free;
    313    VG_(tdict).tool___builtin_delete     = __builtin_delete;
    314    VG_(tdict).tool___builtin_vec_delete = __builtin_vec_delete;
    315    VG_(tdict).tool_realloc              = realloc;
    316    VG_(tdict).tool_malloc_usable_size   = malloc_usable_size;
    317    VG_(tdict).tool_client_redzone_szB   = client_malloc_redzone_szB;
    318 }
    319 
    320 void VG_(needs_xml_output)( void )
    321 {
    322    VG_(needs).xml_output = True;
    323 }
    324 
    325 void VG_(needs_final_IR_tidy_pass)(
    326    IRSB*(*final_tidy)(IRSB*)
    327 )
    328 {
    329    VG_(needs).final_IR_tidy_pass = True;
    330    VG_(tdict).tool_final_IR_tidy_pass = final_tidy;
    331 }
    332 
    333 /*--------------------------------------------------------------------*/
    334 /* Tracked events.  Digit 'n' on DEFn is the REGPARMness. */
    335 
    336 #define DEF0(fn, args...) \
    337 void VG_(fn)(void(*f)(args)) { \
    338    VG_(tdict).fn = f; \
    339 }
    340 
    341 #define DEF1(fn, args...) \
    342 void VG_(fn)(VG_REGPARM(1) void(*f)(args)) { \
    343    VG_(tdict).fn = f; \
    344 }
    345 
    346 #define DEF2(fn, args...) \
    347 void VG_(fn)(VG_REGPARM(2) void(*f)(args)) { \
    348    VG_(tdict).fn = f; \
    349 }
    350 
    351 DEF0(track_new_mem_startup,       Addr, SizeT, Bool, Bool, Bool, ULong)
    352 DEF0(track_new_mem_stack_signal,  Addr, SizeT, UInt)
    353 DEF0(track_new_mem_brk,           Addr, SizeT, UInt)
    354 DEF0(track_new_mem_mmap,          Addr, SizeT, Bool, Bool, Bool, ULong)
    355 
    356 DEF0(track_copy_mem_remap,        Addr, Addr, SizeT)
    357 DEF0(track_change_mem_mprotect,   Addr, SizeT, Bool, Bool, Bool)
    358 DEF0(track_die_mem_stack_signal,  Addr, SizeT)
    359 DEF0(track_die_mem_brk,           Addr, SizeT)
    360 DEF0(track_die_mem_munmap,        Addr, SizeT)
    361 
    362 DEF2(track_new_mem_stack_4_w_ECU,    Addr, UInt)
    363 DEF2(track_new_mem_stack_8_w_ECU,    Addr, UInt)
    364 DEF2(track_new_mem_stack_12_w_ECU,   Addr, UInt)
    365 DEF2(track_new_mem_stack_16_w_ECU,   Addr, UInt)
    366 DEF2(track_new_mem_stack_32_w_ECU,   Addr, UInt)
    367 DEF2(track_new_mem_stack_112_w_ECU,  Addr, UInt)
    368 DEF2(track_new_mem_stack_128_w_ECU,  Addr, UInt)
    369 DEF2(track_new_mem_stack_144_w_ECU,  Addr, UInt)
    370 DEF2(track_new_mem_stack_160_w_ECU,  Addr, UInt)
    371 DEF0(track_new_mem_stack_w_ECU,      Addr, SizeT, UInt)
    372 
    373 DEF1(track_new_mem_stack_4,       Addr)
    374 DEF1(track_new_mem_stack_8,       Addr)
    375 DEF1(track_new_mem_stack_12,      Addr)
    376 DEF1(track_new_mem_stack_16,      Addr)
    377 DEF1(track_new_mem_stack_32,      Addr)
    378 DEF1(track_new_mem_stack_112,     Addr)
    379 DEF1(track_new_mem_stack_128,     Addr)
    380 DEF1(track_new_mem_stack_144,     Addr)
    381 DEF1(track_new_mem_stack_160,     Addr)
    382 DEF0(track_new_mem_stack,         Addr, SizeT)
    383 
    384 DEF1(track_die_mem_stack_4,       Addr)
    385 DEF1(track_die_mem_stack_8,       Addr)
    386 DEF1(track_die_mem_stack_12,      Addr)
    387 DEF1(track_die_mem_stack_16,      Addr)
    388 DEF1(track_die_mem_stack_32,      Addr)
    389 DEF1(track_die_mem_stack_112,     Addr)
    390 DEF1(track_die_mem_stack_128,     Addr)
    391 DEF1(track_die_mem_stack_144,     Addr)
    392 DEF1(track_die_mem_stack_160,     Addr)
    393 DEF0(track_die_mem_stack,         Addr, SizeT)
    394 
    395 DEF0(track_ban_mem_stack,         Addr, SizeT)
    396 
    397 DEF0(track_pre_mem_read,          CorePart, ThreadId, Char*, Addr, SizeT)
    398 DEF0(track_pre_mem_read_asciiz,   CorePart, ThreadId, Char*, Addr)
    399 DEF0(track_pre_mem_write,         CorePart, ThreadId, Char*, Addr, SizeT)
    400 DEF0(track_post_mem_write,        CorePart, ThreadId, Addr, SizeT)
    401 
    402 DEF0(track_pre_reg_read,          CorePart, ThreadId, Char*, PtrdiffT, SizeT)
    403 DEF0(track_post_reg_write,        CorePart, ThreadId,        PtrdiffT, SizeT)
    404 
    405 DEF0(track_post_reg_write_clientcall_return, ThreadId, PtrdiffT, SizeT, Addr)
    406 
    407 DEF0(track_start_client_code,     ThreadId, ULong)
    408 DEF0(track_stop_client_code,      ThreadId, ULong)
    409 
    410 DEF0(track_pre_thread_ll_create,  ThreadId, ThreadId)
    411 DEF0(track_pre_thread_first_insn, ThreadId)
    412 DEF0(track_pre_thread_ll_exit,    ThreadId)
    413 
    414 DEF0(track_pre_deliver_signal,    ThreadId, Int sigNo, Bool)
    415 DEF0(track_post_deliver_signal,   ThreadId, Int sigNo)
    416 
    417 /*--------------------------------------------------------------------*/
    418 /*--- end                                                          ---*/
    419 /*--------------------------------------------------------------------*/
    420