#include "config.h"#include "system.h"#include "coretypes.h"#include "tm.h"#include "hard-reg-set.h"#include "rtl.h"#include "tree.h"#include "tm_p.h"#include "basic-block.h"#include "flags.h"#include "function.h"#include "tree-inline.h"#include "tree-gimple.h"#include "tree-flow.h"#include "tree-mudflap.h"#include "tree-dump.h"#include "tree-pass.h"#include "hashtab.h"#include "diagnostic.h"#include <demangle.h>#include "langhooks.h"#include "ggc.h"#include "cgraph.h"#include "toplev.h"#include "gt-tree-mudflap.h"Include dependency graph for tree-mudflap.c:

Go to the source code of this file.
Data Structures | |
| struct | mf_xform_decls_data |
Defines | |
| #define | flag_mudflap_threads (flag_mudflap == 2) |
| #define | build_function_type_0(rtype) build_function_type (rtype, void_list_node) |
| #define | build_function_type_1(rtype, arg1) build_function_type (rtype, tree_cons (0, arg1, void_list_node)) |
| #define | build_function_type_3(rtype, arg1, arg2, arg3) |
| #define | build_function_type_4(rtype, arg1, arg2, arg3, arg4) |
Functions | |
| static tree | mf_build_string (const char *string) |
| static tree | mf_varname_tree (tree) |
| static tree | mf_file_function_line_tree (location_t) |
| static void | mf_decl_cache_locals (void) |
| static void | mf_decl_clear_locals (void) |
| static void | mf_xform_derefs (void) |
| static unsigned int | execute_mudflap_function_ops (void) |
| static void | mf_xform_decls (tree, tree) |
| static tree | mx_xfn_xform_decls (tree *, int *, void *) |
| static void | mx_register_decls (tree, tree *) |
| static unsigned int | execute_mudflap_function_decls (void) |
| static tree | mf_build_string () |
| static tree | mf_varname_tree () |
| static tree | mf_file_function_line_tree () |
| static tree | mf_make_builtin () |
| static tree | mf_make_mf_cache_struct_type () |
| void | mudflap_init () |
| static void | mf_build_check_statement_for (tree base, tree limit, block_stmt_iterator *instr_bsi, location_t *locus, tree dirflag) |
| static int | mf_decl_eligible_p () |
| static void | mf_xform_derefs_1 (block_stmt_iterator *iter, tree *tp, location_t *locus, tree dirflag) |
| static void | mx_register_decls () |
| static tree | mx_xfn_xform_decls () |
| static void | mf_xform_decls () |
| tree | mf_mark () |
| int | mf_marked_p () |
| static | VEC (tree, gc) |
| void | mudflap_enqueue_decl () |
| void | mudflap_enqueue_constant () |
| void | mudflap_finish_file () |
| static bool | gate_mudflap () |
Variables | |
| static tree | mf_uintptr_type |
| static tree | mf_cache_struct_type |
| static tree | mf_cache_structptr_type |
| static tree | mf_cache_array_decl |
| static tree | mf_cache_shift_decl |
| static tree | mf_cache_mask_decl |
| static tree | mf_cache_shift_decl_l |
| static tree | mf_cache_mask_decl_l |
| static tree | mf_check_fndecl |
| static tree | mf_register_fndecl |
| static tree | mf_unregister_fndecl |
| static tree | mf_init_fndecl |
| static tree | mf_set_options_fndecl |
| static htab_t | marked_trees = NULL |
| tree_opt_pass | pass_mudflap_1 |
| tree_opt_pass | pass_mudflap_2 |
|
|
Definition at line 330 of file tree-mudflap.c. Referenced by mudflap_init(). |
|
|
Definition at line 332 of file tree-mudflap.c. Referenced by mudflap_init(). |
|
|
Value: build_function_type (rtype, tree_cons (0, arg1, tree_cons (0, arg2, \ tree_cons (0, arg3, void_list_node)))) Definition at line 334 of file tree-mudflap.c. Referenced by mudflap_init(). |
|
|
Value: build_function_type (rtype, tree_cons (0, arg1, tree_cons (0, arg2, \ tree_cons (0, arg3, tree_cons (0, arg4, \ void_list_node))))) Definition at line 337 of file tree-mudflap.c. Referenced by mudflap_init(). |
|
|
Options. Definition at line 53 of file tree-mudflap.c. Referenced by execute_mudflap_function_ops(), and mf_build_check_statement_for(). |
|
|
ADDR_EXPR transforms. Perform the declaration-related mudflap tree transforms on the current function. This is the first part of the mudflap instrumentation. It works on high-level GIMPLE because after lowering, all variables are moved out of their BIND_EXPR binding context, and we lose liveness information for the declarations we wish to instrument. Definition at line 953 of file tree-mudflap.c. References current_function_decl, DECL_ARGUMENTS, DECL_ARTIFICIAL, DECL_SAVED_TREE, mf_marked_p(), mf_xform_decls(), pop_gimplify_context(), and push_gimplify_context(). 00954 { 00955 /* Don't instrument functions such as the synthetic constructor 00956 built during mudflap_finish_file. */ 00957 if (mf_marked_p (current_function_decl) || 00958 DECL_ARTIFICIAL (current_function_decl)) 00959 return 0; 00960 00961 push_gimplify_context (); 00962 00963 mf_xform_decls (DECL_SAVED_TREE (current_function_decl), 00964 DECL_ARGUMENTS (current_function_decl)); 00965 00966 pop_gimplify_context (NULL); 00967 return 0; 00968 }
|
|
|
Memory reference transforms. Perform the mudflap indirection-related tree transforms on the current function. This is the second part of the mudflap instrumentation. It works on low-level GIMPLE using the CFG, because we want to run this pass after tree optimizations have been performed, but we have to preserve the CFG for expansion from trees to RTL. Definition at line 417 of file tree-mudflap.c. References current_function_decl, DECL_ARTIFICIAL, flag_mudflap_threads, mf_decl_cache_locals(), mf_decl_clear_locals(), mf_marked_p(), mf_xform_derefs(), pop_gimplify_context(), and push_gimplify_context(). 00418 { 00419 /* Don't instrument functions such as the synthetic constructor 00420 built during mudflap_finish_file. */ 00421 if (mf_marked_p (current_function_decl) || 00422 DECL_ARTIFICIAL (current_function_decl)) 00423 return 0; 00424 00425 push_gimplify_context (); 00426 00427 /* In multithreaded mode, don't cache the lookup cache parameters. */ 00428 if (! flag_mudflap_threads) 00429 mf_decl_cache_locals (); 00430 00431 mf_xform_derefs (); 00432 00433 if (! flag_mudflap_threads) 00434 mf_decl_clear_locals (); 00435 00436 pop_gimplify_context (NULL); 00437 return 0; 00438 }
|
|
|
Definition at line 1305 of file tree-mudflap.c.
|
|
||||||||||||||||||||||||
|
Definition at line 497 of file tree-mudflap.c. References bb_for_stmt(), boolean_type_node, BSI_CONTINUE_LINKING, bsi_end_p(), bsi_insert_after(), bsi_last, bsi_next(), bsi_prev(), bsi_start, bsi_stmt(), build1, build2, build3, build4, build_function_call_expr(), convert(), create_tmp_var, flag_mudflap_threads, fold_build2, gimplify_to_stmt_list(), integer_one_node, integer_type_node, mf_cache_array_decl, mf_cache_mask_decl, mf_cache_mask_decl_l, mf_cache_shift_decl, mf_cache_shift_decl_l, mf_cache_struct_type, mf_cache_structptr_type, mf_check_fndecl, mf_file_function_line_tree(), mf_uintptr_type, NULL_TREE, SET_EXPR_LOCUS, tree_block_label(), TREE_CHAIN, tree_cons, TREE_TYPE, TSI_CONTINUE_LINKING, tsi_end_p(), tsi_last(), tsi_link_after(), tsi_next(), tsi_start(), tsi_stmt(), TYPE_FIELDS, unshare_expr(), and void_type_node. Referenced by mf_xform_derefs_1(). 00500 { 00501 tree_stmt_iterator head, tsi; 00502 block_stmt_iterator bsi; 00503 basic_block cond_bb, then_bb, join_bb; 00504 edge e; 00505 tree cond, t, u, v; 00506 tree mf_base; 00507 tree mf_elem; 00508 tree mf_limit; 00509 00510 /* We first need to split the current basic block, and start altering 00511 the CFG. This allows us to insert the statements we're about to 00512 construct into the right basic blocks. */ 00513 00514 cond_bb = bb_for_stmt (bsi_stmt (*instr_bsi)); 00515 bsi = *instr_bsi; 00516 bsi_prev (&bsi); 00517 if (! bsi_end_p (bsi)) 00518 e = split_block (cond_bb, bsi_stmt (bsi)); 00519 else 00520 e = split_block_after_labels (cond_bb); 00521 cond_bb = e->src; 00522 join_bb = e->dest; 00523 00524 /* A recap at this point: join_bb is the basic block at whose head 00525 is the gimple statement for which this check expression is being 00526 built. cond_bb is the (possibly new, synthetic) basic block the 00527 end of which will contain the cache-lookup code, and a 00528 conditional that jumps to the cache-miss code or, much more 00529 likely, over to join_bb. */ 00530 00531 /* Create the bb that contains the cache-miss fallback block (mf_check). */ 00532 then_bb = create_empty_bb (cond_bb); 00533 make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE); 00534 make_single_succ_edge (then_bb, join_bb, EDGE_FALLTHRU); 00535 00536 /* Mark the pseudo-fallthrough edge from cond_bb to join_bb. */ 00537 e = find_edge (cond_bb, join_bb); 00538 e->flags = EDGE_FALSE_VALUE; 00539 e->count = cond_bb->count; 00540 e->probability = REG_BR_PROB_BASE; 00541 00542 /* Update dominance info. Note that bb_join's data was 00543 updated by split_block. */ 00544 if (dom_info_available_p (CDI_DOMINATORS)) 00545 { 00546 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb); 00547 set_immediate_dominator (CDI_DOMINATORS, join_bb, cond_bb); 00548 } 00549 00550 /* Build our local variables. */ 00551 mf_elem = create_tmp_var (mf_cache_structptr_type, "__mf_elem"); 00552 mf_base = create_tmp_var (mf_uintptr_type, "__mf_base"); 00553 mf_limit = create_tmp_var (mf_uintptr_type, "__mf_limit"); 00554 00555 /* Build: __mf_base = (uintptr_t) <base address expression>. */ 00556 t = build2 (MODIFY_EXPR, void_type_node, mf_base, 00557 convert (mf_uintptr_type, unshare_expr (base))); 00558 SET_EXPR_LOCUS (t, locus); 00559 gimplify_to_stmt_list (&t); 00560 head = tsi_start (t); 00561 tsi = tsi_last (t); 00562 00563 /* Build: __mf_limit = (uintptr_t) <limit address expression>. */ 00564 t = build2 (MODIFY_EXPR, void_type_node, mf_limit, 00565 convert (mf_uintptr_type, unshare_expr (limit))); 00566 SET_EXPR_LOCUS (t, locus); 00567 gimplify_to_stmt_list (&t); 00568 tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING); 00569 00570 /* Build: __mf_elem = &__mf_lookup_cache [(__mf_base >> __mf_shift) 00571 & __mf_mask]. */ 00572 t = build2 (RSHIFT_EXPR, mf_uintptr_type, mf_base, 00573 (flag_mudflap_threads ? mf_cache_shift_decl : mf_cache_shift_decl_l)); 00574 t = build2 (BIT_AND_EXPR, mf_uintptr_type, t, 00575 (flag_mudflap_threads ? mf_cache_mask_decl : mf_cache_mask_decl_l)); 00576 t = build4 (ARRAY_REF, 00577 TREE_TYPE (TREE_TYPE (mf_cache_array_decl)), 00578 mf_cache_array_decl, t, NULL_TREE, NULL_TREE); 00579 t = build1 (ADDR_EXPR, mf_cache_structptr_type, t); 00580 t = build2 (MODIFY_EXPR, void_type_node, mf_elem, t); 00581 SET_EXPR_LOCUS (t, locus); 00582 gimplify_to_stmt_list (&t); 00583 tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING); 00584 00585 /* Quick validity check. 00586 00587 if (__mf_elem->low > __mf_base 00588 || (__mf_elem_high < __mf_limit)) 00589 { 00590 __mf_check (); 00591 ... and only if single-threaded: 00592 __mf_lookup_shift_1 = f...; 00593 __mf_lookup_mask_l = ...; 00594 } 00595 00596 It is expected that this body of code is rarely executed so we mark 00597 the edge to the THEN clause of the conditional jump as unlikely. */ 00598 00599 /* Construct t <-- '__mf_elem->low > __mf_base'. */ 00600 t = build3 (COMPONENT_REF, mf_uintptr_type, 00601 build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem), 00602 TYPE_FIELDS (mf_cache_struct_type), NULL_TREE); 00603 t = build2 (GT_EXPR, boolean_type_node, t, mf_base); 00604 00605 /* Construct '__mf_elem->high < __mf_limit'. 00606 00607 First build: 00608 1) u <-- '__mf_elem->high' 00609 2) v <-- '__mf_limit'. 00610 00611 Then build 'u <-- (u < v). */ 00612 00613 u = build3 (COMPONENT_REF, mf_uintptr_type, 00614 build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem), 00615 TREE_CHAIN (TYPE_FIELDS (mf_cache_struct_type)), NULL_TREE); 00616 00617 v = mf_limit; 00618 00619 u = build2 (LT_EXPR, boolean_type_node, u, v); 00620 00621 /* Build the composed conditional: t <-- 't || u'. Then store the 00622 result of the evaluation of 't' in a temporary variable which we 00623 can use as the condition for the conditional jump. */ 00624 t = build2 (TRUTH_OR_EXPR, boolean_type_node, t, u); 00625 cond = create_tmp_var (boolean_type_node, "__mf_unlikely_cond"); 00626 t = build2 (MODIFY_EXPR, boolean_type_node, cond, t); 00627 gimplify_to_stmt_list (&t); 00628 tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING); 00629 00630 /* Build the conditional jump. 'cond' is just a temporary so we can 00631 simply build a void COND_EXPR. We do need labels in both arms though. */ 00632 t = build3 (COND_EXPR, void_type_node, cond, 00633 build1 (GOTO_EXPR, void_type_node, tree_block_label (then_bb)), 00634 build1 (GOTO_EXPR, void_type_node, tree_block_label (join_bb))); 00635 SET_EXPR_LOCUS (t, locus); 00636 tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING); 00637 00638 /* At this point, after so much hard work, we have only constructed 00639 the conditional jump, 00640 00641 if (__mf_elem->low > __mf_base 00642 || (__mf_elem_high < __mf_limit)) 00643 00644 The lowered GIMPLE tree representing this code is in the statement 00645 list starting at 'head'. 00646 00647 We can insert this now in the current basic block, i.e. the one that 00648 the statement we're instrumenting was originally in. */ 00649 bsi = bsi_last (cond_bb); 00650 for (tsi = head; ! tsi_end_p (tsi); tsi_next (&tsi)) 00651 bsi_insert_after (&bsi, tsi_stmt (tsi), BSI_CONTINUE_LINKING); 00652 00653 /* Now build up the body of the cache-miss handling: 00654 00655 __mf_check(); 00656 refresh *_l vars. 00657 00658 This is the body of the conditional. */ 00659 00660 u = tree_cons (NULL_TREE, 00661 mf_file_function_line_tree (locus == NULL ? UNKNOWN_LOCATION 00662 : *locus), 00663 NULL_TREE); 00664 u = tree_cons (NULL_TREE, dirflag, u); 00665 /* NB: we pass the overall [base..limit] range to mf_check. */ 00666 u = tree_cons (NULL_TREE, 00667 fold_build2 (PLUS_EXPR, integer_type_node, 00668 fold_build2 (MINUS_EXPR, mf_uintptr_type, mf_limit, mf_base), 00669 integer_one_node), 00670 u); 00671 u = tree_cons (NULL_TREE, mf_base, u); 00672 t = build_function_call_expr (mf_check_fndecl, u); 00673 gimplify_to_stmt_list (&t); 00674 head = tsi_start (t); 00675 tsi = tsi_last (t); 00676 00677 if (! flag_mudflap_threads) 00678 { 00679 t = build2 (MODIFY_EXPR, void_type_node, 00680 mf_cache_shift_decl_l, mf_cache_shift_decl); 00681 tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING); 00682 00683 t = build2 (MODIFY_EXPR, void_type_node, 00684 mf_cache_mask_decl_l, mf_cache_mask_decl); 00685 tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING); 00686 } 00687 00688 /* Insert the check code in the THEN block. */ 00689 bsi = bsi_start (then_bb); 00690 for (tsi = head; ! tsi_end_p (tsi); tsi_next (&tsi)) 00691 bsi_insert_after (&bsi, tsi_stmt (tsi), BSI_CONTINUE_LINKING); 00692 00693 *instr_bsi = bsi_start (join_bb); 00694 bsi_next (instr_bsi); 00695 }
|
|
|
Build a reference to a literal string. Definition at line 78 of file tree-mudflap.c. References build1, build_array_type(), build_index_type(), build_int_cst(), build_pointer_type(), build_string(), char_type_node, mf_mark(), NULL_TREE, TREE_CONSTANT, TREE_INVARIANT, TREE_READONLY, TREE_STATIC, and TREE_TYPE. 00079 { 00080 size_t len = strlen (string); 00081 tree result = mf_mark (build_string (len + 1, string)); 00082 00083 TREE_TYPE (result) = build_array_type 00084 (char_type_node, build_index_type (build_int_cst (NULL_TREE, len))); 00085 TREE_CONSTANT (result) = 1; 00086 TREE_INVARIANT (result) = 1; 00087 TREE_READONLY (result) = 1; 00088 TREE_STATIC (result) = 1; 00089 00090 result = build1 (ADDR_EXPR, build_pointer_type (char_type_node), result); 00091 00092 return mf_mark (result); 00093 }
|
|
|
Helpers. Referenced by mf_file_function_line_tree(), mf_varname_tree(), mudflap_enqueue_constant(), and mudflap_finish_file(). |
|
|
Create and initialize local shadow variables for the lookup cache globals. Put their decls in the *_l globals for use by mf_build_check_statement_for. Definition at line 445 of file tree-mudflap.c. References bsi_commit_edge_inserts(), build2, create_tmp_var, current_function_decl, DECL_SOURCE_LOCATION, gimplify_to_stmt_list(), insert_edge_copies(), mf_cache_mask_decl, mf_cache_mask_decl_l, mf_cache_shift_decl, mf_cache_shift_decl_l, mf_mark(), SET_EXPR_LOCATION, TREE_TYPE, tsi_end_p(), tsi_next(), tsi_start(), and tsi_stmt(). Referenced by execute_mudflap_function_ops(). 00446 { 00447 tree t, shift_init_stmts, mask_init_stmts; 00448 tree_stmt_iterator tsi; 00449 00450 /* Build the cache vars. */ 00451 mf_cache_shift_decl_l 00452 = mf_mark (create_tmp_var (TREE_TYPE (mf_cache_shift_decl), 00453 "__mf_lookup_shift_l")); 00454 00455 mf_cache_mask_decl_l 00456 = mf_mark (create_tmp_var (TREE_TYPE (mf_cache_mask_decl), 00457 "__mf_lookup_mask_l")); 00458 00459 /* Build initialization nodes for the cache vars. We just load the 00460 globals into the cache variables. */ 00461 t = build2 (MODIFY_EXPR, TREE_TYPE (mf_cache_shift_decl_l), 00462 mf_cache_shift_decl_l, mf_cache_shift_decl); 00463 SET_EXPR_LOCATION (t, DECL_SOURCE_LOCATION (current_function_decl)); 00464 gimplify_to_stmt_list (&t); 00465 shift_init_stmts = t; 00466 00467 t = build2 (MODIFY_EXPR, TREE_TYPE (mf_cache_mask_decl_l), 00468 mf_cache_mask_decl_l, mf_cache_mask_decl); 00469 SET_EXPR_LOCATION (t, DECL_SOURCE_LOCATION (current_function_decl)); 00470 gimplify_to_stmt_list (&t); 00471 mask_init_stmts = t; 00472 00473 /* Anticipating multiple entry points, we insert the cache vars 00474 initializers in each successor of the ENTRY_BLOCK_PTR. */ 00475 for (tsi = tsi_start (shift_init_stmts); 00476 ! tsi_end_p (tsi); 00477 tsi_next (&tsi)) 00478 insert_edge_copies (tsi_stmt (tsi), ENTRY_BLOCK_PTR); 00479 00480 for (tsi = tsi_start (mask_init_stmts); 00481 ! tsi_end_p (tsi); 00482 tsi_next (&tsi)) 00483 insert_edge_copies (tsi_stmt (tsi), ENTRY_BLOCK_PTR); 00484 bsi_commit_edge_inserts (); 00485 }
|
|
|
Definition at line 489 of file tree-mudflap.c. References mf_cache_mask_decl_l, mf_cache_shift_decl_l, and NULL_TREE. Referenced by execute_mudflap_function_ops(). 00490 { 00491 /* Unset local shadows. */ 00492 mf_cache_shift_decl_l = NULL_TREE; 00493 mf_cache_mask_decl_l = NULL_TREE; 00494 }
|
|
|
Check whether the given decl, generally a VAR_DECL or PARM_DECL, is eligible for instrumentation. For the mudflap1 pass, this implies that it should be registered with the libmudflap runtime. For the mudflap2 pass this means instrumenting an indirection operation with respect to the object. Definition at line 705 of file tree-mudflap.c. References COMPLETE_OR_VOID_TYPE_P, DECL_HAS_VALUE_EXPR_P, TREE_ADDRESSABLE, TREE_CODE, and TREE_TYPE. Referenced by mf_xform_derefs_1(), and mx_register_decls(). 00706 { 00707 return ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL) 00708 /* The decl must have its address taken. In the case of 00709 arrays, this flag is also set if the indexes are not 00710 compile-time known valid constants. */ 00711 && TREE_ADDRESSABLE (decl) /* XXX: not sufficient: return-by-value structs! */ 00712 /* The type of the variable must be complete. */ 00713 && COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (decl)) 00714 /* The decl hasn't been decomposed somehow. */ 00715 && !DECL_HAS_VALUE_EXPR_P (decl)); 00716 }
|
|
|
And another friend, for producing a simpler message. Definition at line 200 of file tree-mudflap.c. References current_function_decl, DECL_SOURCE_FILE, mf_build_string(), and NULL_TREE. 00201 { 00202 expanded_location xloc = expand_location (location); 00203 const char *file = NULL, *colon, *line, *op, *name, *cp; 00204 char linecolbuf[30]; /* Enough for two decimal numbers plus a colon. */ 00205 char *string; 00206 tree result; 00207 00208 /* Add FILENAME[:LINENUMBER[:COLUMNNUMBER]]. */ 00209 file = xloc.file; 00210 if (file == NULL && current_function_decl != NULL_TREE) 00211 file = DECL_SOURCE_FILE (current_function_decl); 00212 if (file == NULL) 00213 file = "<unknown file>"; 00214 00215 if (xloc.line > 0) 00216 { 00217 #ifdef USE_MAPPED_LOCATION 00218 if (xloc.column > 0) 00219 sprintf (linecolbuf, "%d:%d", xloc.line, xloc.column); 00220 else 00221 #endif 00222 sprintf (linecolbuf, "%d", xloc.line); 00223 colon = ":"; 00224 line = linecolbuf; 00225 } 00226 else 00227 colon = line = ""; 00228 00229 /* Add (FUNCTION). */ 00230 name = lang_hooks.decl_printable_name (current_function_decl, 1); 00231 if (name) 00232 { 00233 op = " ("; 00234 cp = ")"; 00235 } 00236 else 00237 op = name = cp = ""; 00238 00239 string = concat (file, colon, line, op, name, cp, NULL); 00240 result = mf_build_string (string); 00241 free (string); 00242 00243 return result; 00244 }
|
|
|
Referenced by mf_build_check_statement_for(). |
|
|
Helper for mudflap_init: construct a decl with the given category, name, and type, mark it an external reference, and pushdecl it. Definition at line 298 of file tree-mudflap.c. References build_decl, DECL_EXTERNAL, get_identifier(), mf_mark(), and TREE_PUBLIC. Referenced by mudflap_init(). 00299 { 00300 tree decl = mf_mark (build_decl (category, get_identifier (name), type)); 00301 TREE_PUBLIC (decl) = 1; 00302 DECL_EXTERNAL (decl) = 1; 00303 lang_hooks.decls.pushdecl (decl); 00304 return decl; 00305 }
|
|
|
Helper for mudflap_init: construct a tree corresponding to the type
struct __mf_cache { uintptr_t low; uintptr_t high; };
where uintptr_t is the FIELD_TYPE argument. Definition at line 311 of file tree-mudflap.c. References build_decl, DECL_CONTEXT, get_identifier(), layout_type(), make_node, TREE_CHAIN, TYPE_FIELDS, and TYPE_NAME. Referenced by mudflap_init(). 00312 { 00313 /* There is, abominably, no language-independent way to construct a 00314 RECORD_TYPE. So we have to call the basic type construction 00315 primitives by hand. */ 00316 tree fieldlo = build_decl (FIELD_DECL, get_identifier ("low"), field_type); 00317 tree fieldhi = build_decl (FIELD_DECL, get_identifier ("high"), field_type); 00318 00319 tree struct_type = make_node (RECORD_TYPE); 00320 DECL_CONTEXT (fieldlo) = struct_type; 00321 DECL_CONTEXT (fieldhi) = struct_type; 00322 TREE_CHAIN (fieldlo) = fieldhi; 00323 TYPE_FIELDS (struct_type) = fieldlo; 00324 TYPE_NAME (struct_type) = get_identifier ("__mf_cache"); 00325 layout_type (struct_type); 00326 00327 return struct_type; 00328 }
|
|
|
Definition at line 1133 of file tree-mudflap.c. Referenced by copy_tree_r(), mf_build_string(), mf_decl_cache_locals(), mf_make_builtin(), mudflap_init(), and mx_register_decls(). 01134 { 01135 void **slot; 01136 01137 if (marked_trees == NULL) 01138 marked_trees = htab_create_ggc (31, htab_hash_pointer, htab_eq_pointer, NULL); 01139 01140 slot = htab_find_slot (marked_trees, t, INSERT); 01141 *slot = t; 01142 return t; 01143 }
|
|
|
Definition at line 1146 of file tree-mudflap.c. Referenced by copy_tree_r(), execute_mudflap_function_decls(), execute_mudflap_function_ops(), mf_xform_derefs_1(), mudflap_enqueue_constant(), mudflap_enqueue_decl(), mudflap_finish_file(), and mx_register_decls(). 01147 { 01148 void *entry; 01149 01150 if (marked_trees == NULL) 01151 return 0; 01152 01153 entry = htab_find (marked_trees, t); 01154 return (entry != NULL); 01155 }
|
|
|
Create a properly typed STRING_CST node that describes the given declaration. It will be used as an argument for __mf_register(). Try to construct a helpful string, including file/function/variable name. Definition at line 101 of file tree-mudflap.c. References current_function_decl, DECL_NAME, DECL_SOURCE_FILE, DECL_SOURCE_LOCATION, IDENTIFIER_POINTER, initialized, mf_build_string(), and NULL_TREE. 00102 { 00103 static pretty_printer buf_rec; 00104 static int initialized = 0; 00105 pretty_printer *buf = & buf_rec; 00106 const char *buf_contents; 00107 tree result; 00108 00109 gcc_assert (decl); 00110 00111 if (!initialized) 00112 { 00113 pp_construct (buf, /* prefix */ NULL, /* line-width */ 0); 00114 initialized = 1; 00115 } 00116 pp_clear_output_area (buf); 00117 00118 /* Add FILENAME[:LINENUMBER[:COLUMNNUMBER]]. */ 00119 { 00120 expanded_location xloc = expand_location (DECL_SOURCE_LOCATION (decl)); 00121 const char *sourcefile; 00122 unsigned sourceline = xloc.line; 00123 unsigned sourcecolumn = 0; 00124 #ifdef USE_MAPPED_LOCATION 00125 sourcecolumn = xloc.column; 00126 #endif 00127 sourcefile = xloc.file; 00128 if (sourcefile == NULL && current_function_decl != NULL_TREE) 00129 sourcefile = DECL_SOURCE_FILE (current_function_decl); 00130 if (sourcefile == NULL) 00131 sourcefile = "<unknown file>"; 00132 00133 pp_string (buf, sourcefile); 00134 00135 if (sourceline != 0) 00136 { 00137 pp_string (buf, ":"); 00138 pp_decimal_int (buf, sourceline); 00139 00140 if (sourcecolumn != 0) 00141 { 00142 pp_string (buf, ":"); 00143 pp_decimal_int (buf, sourcecolumn); 00144 } 00145 } 00146 } 00147 00148 if (current_function_decl != NULL_TREE) 00149 { 00150 /* Add (FUNCTION) */ 00151 pp_string (buf, " ("); 00152 { 00153 const char *funcname = NULL; 00154 if (DECL_NAME (current_function_decl)) 00155 funcname = lang_hooks.decl_printable_name (current_function_decl, 1); 00156 if (funcname == NULL) 00157 funcname = "anonymous fn"; 00158 00159 pp_string (buf, funcname); 00160 } 00161 pp_string (buf, ") "); 00162 } 00163 else 00164 pp_string (buf, " "); 00165 00166 /* Add <variable-declaration>, possibly demangled. */ 00167 { 00168 const char *declname = NULL; 00169 00170 if (DECL_NAME (decl) != NULL) 00171 { 00172 if (strcmp ("GNU C++", lang_hooks.name) == 0) 00173 { 00174 /* The gcc/cp decl_printable_name hook doesn't do as good a job as 00175 the libiberty demangler. */ 00176 declname = cplus_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)), 00177 DMGL_AUTO | DMGL_VERBOSE); 00178 } 00179 if (declname == NULL) 00180 declname = lang_hooks.decl_printable_name (decl, 3); 00181 } 00182 if (declname == NULL) 00183 declname = "<unnamed variable>"; 00184 00185 pp_string (buf, declname); 00186 } 00187 00188 /* Return the lot as a new STRING_CST. */ 00189 buf_contents = pp_base_formatted_text (buf); 00190 result = mf_build_string (buf_contents); 00191 pp_clear_output_area (buf); 00192 00193 return result; 00194 }
|
|
|
Referenced by mudflap_finish_file(), and mx_register_decls(). |
|
|
Perform the object lifetime tracking mudflap transform on the given function tree. The tree is mutated in place, with possibly copied subtree nodes. For every auto variable declared, if its address is ever taken within the function, then supply its lifetime to the mudflap runtime with the __mf_register and __mf_unregister calls. Definition at line 1116 of file tree-mudflap.c. References mx_xfn_xform_decls(), mf_xform_decls_data::param_decls, and walk_tree_without_duplicates(). 01117 { 01118 struct mf_xform_decls_data d; 01119 d.param_decls = fnparams; 01120 walk_tree_without_duplicates (&fnbody, mx_xfn_xform_decls, &d); 01121 }
|
|
||||||||||||
|
Addressable variables instrumentation. Referenced by execute_mudflap_function_decls(). |
|
|
Definition at line 898 of file tree-mudflap.c. References bsi_end_p(), bsi_next(), bsi_start, bsi_stmt(), EXPR_LOCUS, integer_one_node, integer_zero_node, mf_xform_derefs_1(), NULL_TREE, TREE_CODE, and TREE_OPERAND. Referenced by execute_mudflap_function_ops(). 00899 { 00900 basic_block bb, next; 00901 block_stmt_iterator i; 00902 int saved_last_basic_block = last_basic_block; 00903 00904 bb = ENTRY_BLOCK_PTR ->next_bb; 00905 do 00906 { 00907 next = bb->next_bb; 00908 for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i)) 00909 { 00910 tree s = bsi_stmt (i); 00911 00912 /* Only a few GIMPLE statements can reference memory. */ 00913 switch (TREE_CODE (s)) 00914 { 00915 case MODIFY_EXPR: 00916 mf_xform_derefs_1 (&i, &TREE_OPERAND (s, 0), EXPR_LOCUS (s), 00917 integer_one_node); 00918 mf_xform_derefs_1 (&i, &TREE_OPERAND (s, 1), EXPR_LOCUS (s), 00919 integer_zero_node); 00920 break; 00921 00922 case RETURN_EXPR: 00923 if (TREE_OPERAND (s, 0) != NULL_TREE) 00924 { 00925 if (TREE_CODE (TREE_OPERAND (s, 0)) == MODIFY_EXPR) 00926 mf_xform_derefs_1 (&i, &TREE_OPERAND (TREE_OPERAND (s, 0), 1), 00927 EXPR_LOCUS (s), integer_zero_node); 00928 else 00929 mf_xform_derefs_1 (&i, &TREE_OPERAND (s, 0), EXPR_LOCUS (s), 00930 integer_zero_node); 00931 } 00932 break; 00933 00934 default: 00935 ; 00936 } 00937 } 00938 bb = next; 00939 } 00940 while (bb && bb->index <= saved_last_basic_block); 00941 }
|
|
||||||||||||||||||||
|
Definition at line 720 of file tree-mudflap.c. References bitsize_int, bitsizetype, build1, build_int_cst(), build_pointer_type(), byte_position(), convert(), DECL_BIT_FIELD_TYPE, DECL_SIZE_UNIT, error_mark_node, fold_build2, fold_convert(), INDIRECT_REF_P, integer_one_node, integer_zero_node, mf_build_check_statement_for(), mf_decl_eligible_p(), mf_marked_p(), mf_uintptr_type, NULL_TREE, ptr_type_node, size_binop(), sizetype, TREE_CODE, tree_mem_ref_addr(), TREE_OPERAND, TREE_TYPE, and TYPE_SIZE_UNIT. Referenced by mf_xform_derefs(). 00722 { 00723 tree type, base, limit, addr, size, t; 00724 00725 /* Don't instrument read operations. */ 00726 if (dirflag == integer_zero_node && flag_mudflap_ignore_reads) 00727 return; 00728 00729 /* Don't instrument marked nodes. */ 00730 if (mf_marked_p (*tp)) 00731 return; 00732 00733 t = *tp; 00734 type = TREE_TYPE (t); 00735 00736 if (type == error_mark_node) 00737 return; 00738 00739 size = TYPE_SIZE_UNIT (type); 00740 00741 switch (TREE_CODE (t)) 00742 { 00743 case ARRAY_REF: 00744 case COMPONENT_REF: 00745 { 00746 /* This is trickier than it may first appear. The reason is 00747 that we are looking at expressions from the "inside out" at 00748 this point. We may have a complex nested aggregate/array 00749 expression (e.g. "a.b[i].c"), maybe with an indirection as 00750 the leftmost operator ("p->a.b.d"), where |