This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa mudflap] instrumentation tweaks
- From: "Frank Ch. Eigler" <fche at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 27 Aug 2002 18:10:44 -0400
- Subject: [tree-ssa mudflap] instrumentation tweaks
Hi -
I'm about to commit the following patch. Nothing that interesting
this time.
2002-08-27 Frank Ch. Eigler <fche@redhat.com>
Better static registration:
* varasm.c (make_decl_rtl): Handle DECL_RTL_SET_P case for
mudflap static registration.
* tree-mudflap.c (mudflap_enqueue_decl): Rewrite to handle
deferred statics.
(mudflap_finish_file): Call above fn back for deferred statics.
Cleanup:
* tree-mudflap.c (mf_varname_tree, mf_file_function_line_tree):
Reorganize output_buffer reuse mechanism.
(mf_build_check_statement_for): Set TREE_SIDE_EFFECTS.
(mx_xfn_indirect_ref): Correct file/line collection tests.
Dynamic linking support:
* gcc.c (MFWRAP_SPEC): Make conditional on -static. Add the
newer wrapped functions dlopen/mmap/munmap.
(MFLIB_SPEC): Be sensitive to -static. Partial support for
dynamic linking.
Index: gcc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcc.c,v
retrieving revision 1.324.2.9
diff -u -w -s -p -r1.324.2.9 gcc.c
--- gcc.c 14 Aug 2002 16:08:08 -0000 1.324.2.9
+++ gcc.c 27 Aug 2002 22:04:55 -0000
@@ -549,7 +549,7 @@ proper position among the other output f
/* XXX: valid only if linking with static libmudflap.a */
/* XXX: valid only for GNU ld */
/* XXX: should exactly match hooks provided by libmudflap.a */
-#define MFWRAP_SPEC " %{fmudflap:\
+#define MFWRAP_SPEC " %{fmudflap: %{static:\
--wrap=malloc --wrap=free --wrap=calloc --wrap=realloc\
--wrap=memcpy --wrap=memmove\
--wrap=memset --wrap=memcmp --wrap=memchr --wrap=memrchr\
@@ -558,10 +558,11 @@ proper position among the other output f
--wrap=strdup --wrap=strndup --wrap=strchr --wrap=strrchr\
--wrap=strstr --wrap=memmem --wrap=strlen --wrap=strnlen\
--wrap=bzero --wrap=bcopy --wrap=bcmp --wrap=index --wrap=rindex\
-}"
+ --wrap=dlopen --wrap=mmap --wrap=munmap\
+}}"
#endif
#ifndef MFLIB_SPEC
-#define MFLIB_SPEC " %{fmudflap: -lmudflap}"
+#define MFLIB_SPEC " %{fmudflap: -export-dynamic -lmudflap %{!static:-ldl} %{static:%(link_gcc_c_sequence) -lmudflap}}"
#endif
/* config.h can define LIBGCC_SPEC to override how and when libgcc.a is
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varasm.c,v
retrieving revision 1.295.2.6
diff -u -w -s -p -r1.295.2.6 varasm.c
--- varasm.c 26 Aug 2002 01:34:56 -0000 1.295.2.6
+++ varasm.c 27 Aug 2002 22:04:56 -0000
@@ -834,6 +834,11 @@ make_decl_rtl (decl, asmspec)
This is necessary, for example, when one machine specific
decl attribute overrides another. */
(* targetm.encode_section_info) (decl, false);
+
+ /* Make this function static known to the mudflap runtime. */
+ if (flag_mudflap && TREE_CODE (decl) == VAR_DECL)
+ mudflap_enqueue_decl (decl, name);
+
return;
}
Index: tree-mudflap.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-mudflap.c,v
retrieving revision 1.1.2.6
diff -u -w -s -p -r1.1.2.6 tree-mudflap.c
--- tree-mudflap.c 22 Aug 2002 16:51:07 -0000 1.1.2.6
+++ tree-mudflap.c 27 Aug 2002 22:04:56 -0000
@@ -116,18 +116,67 @@ mudflap_c_function (t)
label is given.
*/
+
+/* A list of globals whose incomplete declarations we encountered.
+ Instead of emitting the __mf_register call for them here, it's
+ delayed until program finish time. If they're still incomplete by
+ then, warnings are emitted. */
+
+static varray_type GTY ((param_is(union tree_node))) deferred_static_decls;
+static varray_type GTY ((skip(""))) deferred_static_decl_labels;
+static int deferred_static_decls_init;
+
+/* What I really want is a std::map<union tree_node,std::string> .. :-( */
+
+
void
mudflap_enqueue_decl (obj, label)
tree obj;
const char *label;
{
- if (! TREE_MUDFLAPPED_P (obj))
+ if (TREE_MUDFLAPPED_P (obj))
+ return;
+
+ /*
+ fprintf (stderr, "enqueue_decl obj=`");
+ print_c_tree (stderr, obj);
+ fprintf (stderr, "' label=`%s'\n", label);
+ */
+
+ if (COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (obj)))
{
mf_enqueue_register_call (label,
c_size_in_bytes (TREE_TYPE (obj)),
build_int_2 (3, 0), /* __MF_TYPE_STATIC */
mf_varname_tree (obj));
}
+ else
+ {
+ unsigned i;
+ int found_p;
+
+ if (! deferred_static_decls_init)
+ {
+ deferred_static_decls_init = 1;
+ VARRAY_TREE_INIT (deferred_static_decls, 10, "deferred static list");
+ VARRAY_CHAR_PTR_INIT (deferred_static_decl_labels, 10, "label list");
+ }
+
+ /* Ugh, linear search... */
+ found_p = 0;
+ for (i=0; i < VARRAY_SIZE (deferred_static_decls); i++)
+ if (VARRAY_TREE (deferred_static_decls, i) == obj)
+ found_p = 1;
+
+ if (found_p)
+ warning_with_decl (obj, "mudflap cannot track lifetime of `%s'",
+ IDENTIFIER_POINTER (DECL_NAME (obj)));
+ else
+ {
+ VARRAY_PUSH_TREE (deferred_static_decls, obj);
+ VARRAY_PUSH_CHAR_PTR (deferred_static_decl_labels, label);
+ }
+ }
}
@@ -136,8 +185,10 @@ mudflap_enqueue_constant (obj, label)
tree obj;
const char *label;
{
- if ((TREE_CODE (obj) == STRING_CST) &&
- ! TREE_MUDFLAPPED_P (obj))
+ if (TREE_MUDFLAPPED_P (obj))
+ return;
+
+ if (TREE_CODE (obj) == STRING_CST)
{
mf_enqueue_register_call (label,
build_int_2 (TREE_STRING_LENGTH (obj), 0),
@@ -145,14 +196,40 @@ mudflap_enqueue_constant (obj, label)
mx_flag (fix_string_type
(build_string (15, "string literal"))));
}
+ else
+ {
+ warning (obj, "mudflap cannot track object lifetime");
+ print_c_tree (stderr, obj);
+ }
/* XXX: what about other object types? */
}
+
/* Emit any file-wide instrumentation. */
void
mudflap_finish_file ()
{
+ /* Try to give the deferred objects one final try. */
+ if (deferred_static_decls_init)
+ {
+ unsigned i;
+
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_static_decls); i++)
+ {
+ tree obj = VARRAY_TREE (deferred_static_decls, i);
+ const char *label = VARRAY_CHAR_PTR (deferred_static_decl_labels, i);
+
+ /* Call enqueue_decl again on the same object it has previously
+ put into the table. (It won't modify the table this time, so
+ infinite iteration is not a problem.) */
+ mudflap_enqueue_decl (obj, label);
+ }
+
+ VARRAY_CLEAR (deferred_static_decls);
+ VARRAY_CLEAR (deferred_static_decl_labels);
+ }
+
mf_flush_enqueued_calls ();
}
@@ -329,10 +406,10 @@ static tree
mf_varname_tree (decl)
tree decl;
{
- output_buffer buf_rec;
+ static output_buffer buf_rec;
+ static int initialized = 0;
output_buffer *buf = & buf_rec;
const char *buf_contents;
- static int initialized = 0;
tree result;
if (decl == NULL_TREE)
@@ -343,6 +420,7 @@ mf_varname_tree (decl)
init_output_buffer (buf, /* prefix */ NULL, /* line-width */ 0);
initialized = 1;
}
+ output_clear_message_text (buf);
/* Add FILENAME[:LINENUMBER]. */
{
@@ -401,12 +479,18 @@ mf_file_function_line_tree (file, line)
const char * file;
int line;
{
- output_buffer buf_rec;
+ static output_buffer buf_rec;
+ static int initialized = 0;
output_buffer *buf = & buf_rec;
const char *buf_contents;
tree result;
+ if (!initialized)
+ {
init_output_buffer (buf, /* prefix */ NULL, /* line-width */ 0);
+ initialized = 1;
+ }
+ output_clear_message_text (buf);
/* Add FILENAME[:LINENUMBER]. */
if (file == NULL && current_function_decl != NULL_TREE)
@@ -628,6 +712,7 @@ mf_build_check_statement_for (ptrvalue,
t1 = build1 (COMPOUND_STMT, return_type, t1_1);
t0 = build1 (STMT_EXPR, return_type, t1);
+ TREE_SIDE_EFFECTS (t0) = 1;
return t0;
}
@@ -680,9 +765,9 @@ mx_xfn_indirect_ref (t, continue_p, data
/* Track file-name/line-numbers. */
if (statement_code_p (TREE_CODE (*t)))
last_lineno = STMT_LINENO (*t);
- else if (TREE_CODE (*t) == FILE_STMT)
+ if (TREE_CODE (*t) == FILE_STMT)
last_filename = FILE_STMT_FILENAME (*t);
- else if (TREE_CODE (*t) == EXPR_WITH_FILE_LOCATION)
+ if (TREE_CODE (*t) == EXPR_WITH_FILE_LOCATION)
{
last_filename = EXPR_WFL_FILENAME (*t);
last_lineno = EXPR_WFL_LINENO (*t);
- FChE