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