|
From: <sv...@va...> - 2005-06-26 04:50:25
|
Author: njn
Date: 2005-06-26 05:49:25 +0100 (Sun, 26 Jun 2005)
New Revision: 4028
Log:
Cleaned up m_redir.c: renamed some variables and functions, added some
comments, neatened the debugging output, avoided unexpected side-effects
in functions, tweaked code to make it clearer.
Modified:
trunk/coregrind/m_debuginfo/symtab.c
trunk/coregrind/m_redir.c
trunk/coregrind/pub_core_redir.h
Modified: trunk/coregrind/m_debuginfo/symtab.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/m_debuginfo/symtab.c 2005-06-26 02:19:17 UTC (rev 402=
7)
+++ trunk/coregrind/m_debuginfo/symtab.c 2005-06-26 04:49:25 UTC (rev 402=
8)
@@ -1650,7 +1650,7 @@
canonicaliseCfiSI ( si );
=20
/* do redirects */
- VG_(resolve_seg_redirs)( si );
+ VG_(resolve_existing_redirs_with_seginfo)( si );
}
VGP_POPCC(VgpReadSyms);
=20
Modified: trunk/coregrind/m_redir.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/m_redir.c 2005-06-26 02:19:17 UTC (rev 4027)
+++ trunk/coregrind/m_redir.c 2005-06-26 04:49:25 UTC (rev 4028)
@@ -46,6 +46,9 @@
/*--- General purpose redirection. ---*/
/*------------------------------------------------------------*/
=20
+#define TRACE_REDIR(format, args...) \
+ if (VG_(clo_trace_redir)) { VG_(message)(Vg_DebugMsg, format, ## args=
); }
+
/*
wraps and redirections, indexed by from_addr
=20
@@ -71,29 +74,24 @@
const Char *from_sym; /* symbol */
Addr from_addr; /* old addr */
=20
- /* used for redirection */
- Addr to_addr; /* new addr */
+ Addr to_addr; /* used for redirection -- new addr */
+ const FuncWrapper *wrapper; /* used for wrapping */
=20
- /* used for wrapping */
- const FuncWrapper *wrapper;
-
- CodeRedirect *next; /* next pointer on unresolved list */
+ CodeRedirect *next; /* next pointer on unresolved list */
};
=20
static Char *straddr(void *p)
{
static Char buf[16];
-
VG_(sprintf)(buf, "%p", *(Addr *)p);
-
return buf;
}
=20
-static SkipList sk_resolved_redir =3D=20
+static SkipList sk_resolved_redirs =3D=20
VG_SKIPLIST_INIT(CodeRedirect, from_addr, VG_(cmp_Addr),=20
straddr, VG_AR_SYMTAB);
=20
-static CodeRedirect *unresolved_redir =3D NULL;
+static CodeRedirect *unresolved_redirs =3D NULL;
=20
static Bool soname_matches(const Char *pattern, const Char* soname)
{
@@ -107,26 +105,32 @@
return VG_(string_match)(pattern + 7, soname);
}
=20
-static inline Bool from_resolved(const CodeRedirect *redir)
+Bool VG_(is_resolved)(const CodeRedirect *redir)
{
return redir->from_addr !=3D 0;
}
=20
-Bool VG_(is_resolved)(const CodeRedirect *redir)
+// Prepends redir to the unresolved list.
+static void add_redir_to_unresolved_list(CodeRedirect *redir)
{
- return from_resolved(redir);
+ redir->next =3D unresolved_redirs;
+ unresolved_redirs =3D redir;
}
=20
-static void add_resolved(CodeRedirect *redir)
+static void add_redir_to_resolved_list(CodeRedirect *redir)
{
- switch(redir->type) {
- case R_REDIRECT:
- if (VG_(clo_trace_redir)) {
- VG_(message)(Vg_DebugMsg, " redir resolved (%s:%s=3D%p -> ",
- redir->from_lib, redir->from_sym, redir->from_addr=
);
- VG_(message)(Vg_DebugMsg, " %p)", redir->to_ad=
dr);
- }
+ vg_assert(redir->from_addr);
=20
+ switch (redir->type) {
+ case R_REDIRECT: {
+ CodeRedirect* r;
+ =20
+ TRACE_REDIR(" redir resolved (%s:%s=3D%p -> %p)",=20
+ redir->from_lib, redir->from_sym, redir->from_addr,
+ redir->to_addr);
+
+ vg_assert(redir->to_addr !=3D 0);
+
if (VG_(search_transtab)(NULL, (Addr64)redir->from_addr, False)) {
/* For some given (from, to) redir, the "from" function got
called before the .so containing "to" became available. We
@@ -145,191 +149,173 @@
Note, this is potentially expensive -- discarding
translations causes complete unchaining. =20
*/
- if (VG_(clo_verbosity) > 2 && VG_(clo_trace_redir)) {
- VG_(message)(Vg_UserMsg, =20
- "Discarding translation due to redirect of alre=
ady called function" );
- VG_(message)(Vg_UserMsg,
- " %s (%p -> %p)",
- redir->from_sym, redir->from_addr, redir->to_ad=
dr );
- }
+ TRACE_REDIR("Discarding translation due to redirect of already =
called function" );
+ TRACE_REDIR(" %s:%s(%p) -> %p)", redir->from_lib, redir->from=
_sym,
+ redir->from_addr, redir->to_=
addr );
VG_(discard_translations)((Addr64)redir->from_addr, 1);
}
=20
- {
- CodeRedirect *r =3D VG_(SkipList_Find_Exact)(&sk_resolved_redir=
, &redir->from_addr);
+ r =3D VG_(SkipList_Find_Exact)(&sk_resolved_redirs, &redir->from_a=
ddr);
=20
- if (r =3D=3D NULL)
- VG_(SkipList_Insert)(&sk_resolved_redir, redir);
- else {
- /* XXX leak redir */
- if (VG_(clo_trace_redir))
- VG_(message)(Vg_DebugMsg, " redir %s:%s:%p->%p duplicate=
d\n",
- redir->from_lib, redir->from_sym, redir->fro=
m_addr,
- redir->to_addr);
- }
+ if (r =3D=3D NULL) {
+ VG_(SkipList_Insert)(&sk_resolved_redirs, redir);
+ } else {
+ /* XXX leak redir */
+ TRACE_REDIR(" redir %s:%s:%p->%p duplicated\n",
+ redir->from_lib, redir->from_sym, redir->from_addr,
+ redir->to_addr);
}
break;
+ }
=20
case R_WRAPPER:
- if (VG_(clo_trace_redir)) {
- VG_(message)(Vg_DebugMsg, " wrapper resolved (%s:%s=3D%p -> wr=
apper)",
- redir->from_lib, redir->from_sym, redir->from_addr=
);
- }
+ TRACE_REDIR(" wrapper resolved (%s:%s=3D%p -> wrapper)",
+ redir->from_lib, redir->from_sym, redir->from_addr);
=20
+ vg_assert(redir->wrapper);
+
/* XXX redir leaked */
//VG_(wrap_function)(redir->from_addr, redir->wrapper);
break;
=20
case R_CLIENT_WRAPPER:
+ vg_assert(redir->wrapper);
VG_(core_panic)("not implemented");
break;
}
}
=20
-/* Resolve a redir using si if possible, and add it to the resolved
- list */
-static Bool resolve_redir(CodeRedirect *redir, const SegInfo *si)
+// Resolve a redir using si if possible. Returns True if it succeeded.
+static Bool resolve_redir_with_seginfo(CodeRedirect *redir, const SegInf=
o *si)
{
- Bool resolved;
+ Bool ok;
=20
vg_assert(si !=3D NULL);
+ vg_assert(redir->from_addr =3D=3D 0 );
+ vg_assert(redir->from_sym !=3D NULL);
=20
- resolved =3D from_resolved(redir);
- vg_assert(!resolved);
- vg_assert(redir->from_sym !=3D NULL);
-
- if (soname_matches(redir->from_lib, VG_(seginfo_soname)(si))) {
+ // Resolved if the soname matches and we find the symbol.
+ ok =3D soname_matches(redir->from_lib, VG_(seginfo_soname)(si));
+ if (ok) {
redir->from_addr =3D VG_(reverse_search_one_symtab)(si, redir->fro=
m_sym);
- if (VG_(clo_trace_redir) && redir->from_addr !=3D 0)
- VG_(printf)(" bind FROM: %p =3D %s:%s\n",=20
- redir->from_addr,redir->from_lib, redir->from_sym )=
;
+ ok =3D ( redir->from_addr =3D=3D 0 ? False : True );
}
-
- resolved =3D from_resolved(redir);
-
- if (0 && VG_(clo_trace_redir))
- VG_(printf)("resolve_redir: %s:%s from=3D%p to=3D%p\n",
- redir->from_lib, redir->from_sym, redir->from_addr,=20
- redir->to_addr);
-
- if (resolved) add_resolved(redir);
-
- return resolved;
+ return ok; =20
}
=20
-static Bool resolve_redir_allsegs(CodeRedirect *redir)
+// Resolve a redir using any SegInfo if possible.
+static Bool resolve_redir_with_existing_seginfos(CodeRedirect *redir)
{
const SegInfo *si;
=20
- for(si =3D VG_(next_seginfo)(NULL);=20
- si !=3D NULL;=20
- si =3D VG_(next_seginfo)(si))
+ for (si =3D VG_(next_seginfo)(NULL);=20
+ si !=3D NULL;=20
+ si =3D VG_(next_seginfo)(si))
{
- if (resolve_redir(redir, si))
+ if (resolve_redir_with_seginfo(redir, si))
return True;
}
return False;
}
=20
-/* Go through the complete redir list, resolving as much as possible wit=
h this SegInfo.
-
- This should be called when a new SegInfo symtab is loaded.
- */
-void VG_(resolve_seg_redirs)(SegInfo *si)
+// Resolve as many unresolved redirs as possible with this SegInfo. Thi=
s
+// should be called when a new SegInfo symtab is loaded.
+void VG_(resolve_existing_redirs_with_seginfo)(SegInfo *si)
{
- CodeRedirect **prevp =3D &unresolved_redir;
+ CodeRedirect **prevp =3D &unresolved_redirs;
CodeRedirect *redir, *next;
=20
- if (VG_(clo_trace_redir))
- VG_(printf)("Considering redirs to/from %s(soname=3D%s)\n",
- VG_(seginfo_filename)(si), VG_(seginfo_soname)(si));
+ TRACE_REDIR("Just loaded %s (soname=3D%s),",
+ VG_(seginfo_filename)(si), VG_(seginfo_soname)(si));
+ TRACE_REDIR(" resolving any unresolved redirs with it");
=20
- /* visit each unresolved redir - if it becomes resolved, then
- remove it from the unresolved list */
- for(redir =3D unresolved_redir; redir !=3D NULL; redir =3D next) {
+ // Visit each unresolved redir - if it becomes resolved, then
+ // move it from the unresolved list to the resolved list.
+ for (redir =3D unresolved_redirs; redir !=3D NULL; redir =3D next) {
next =3D redir->next;
=20
- if (resolve_redir(redir, si)) {
+ if (resolve_redir_with_seginfo(redir, si)) {
*prevp =3D next;
redir->next =3D NULL;
+ add_redir_to_resolved_list(redir);
} else
prevp =3D &redir->next;
}
+
+ TRACE_REDIR(" Finished resolving");
}
=20
-static void add_redirect_X_to_addr(
- const Char *from_lib, const Char *from_sym, Addr from_addr, Addr to_a=
ddr
-)
+/* Redirect a function at from_addr to a function at to_addr */
+__attribute__((unused)) // It is used, but not on all platforms...
+static void add_redirect_addr_to_addr( Addr from_addr, Addr to_addr )
{
- CodeRedirect *redir =3D VG_(SkipNode_Alloc)(&sk_resolved_redir);
+ CodeRedirect *redir =3D VG_(SkipNode_Alloc)(&sk_resolved_redirs);
=20
- redir->type =3D R_REDIRECT;
+ vg_assert(0 !=3D from_addr && 0 !=3D to_addr);
=20
- if (from_lib) redir->from_lib =3D VG_(arena_strdup)(VG_AR_SYMTAB, fr=
om_lib);
- else redir->from_lib =3D NULL;
- if (from_sym) redir->from_sym =3D VG_(arena_strdup)(VG_AR_SYMTAB, fr=
om_sym);
- else redir->from_sym =3D NULL;
- =20
+ redir->type =3D R_REDIRECT;
+
+ redir->from_lib =3D NULL;
+ redir->from_sym =3D NULL;
redir->from_addr =3D from_addr;
=20
- vg_assert(0 !=3D to_addr);
- redir->to_addr =3D to_addr;
- redir->wrapper =3D 0;
+ redir->to_addr =3D to_addr;
+ redir->wrapper =3D 0;
=20
- if (VG_(clo_verbosity) >=3D 2 && VG_(clo_trace_redir))
- VG_(message)(Vg_UserMsg,=20
- "REDIRECT %s:%s(%p) to %p",
- from_lib, from_sym, from_addr, to_addr);
+ TRACE_REDIR("REDIRECT addr to addr: %p to %p", from_addr, to_addr);
=20
- /* Check against all existing segments to see if this redirection
- can be resolved immediately */
- if (VG_(is_resolved)(redir)) {
- add_resolved(redir);
- }
- else if (!resolve_redir_allsegs(redir)) {
- /* nope, add to list */
- redir->next =3D unresolved_redir;
- unresolved_redir =3D redir;
- }
+ // This redirection is already resolved, put it straight in the list.
+ add_redir_to_resolved_list(redir);
}
=20
/* Redirect a lib/symbol reference to a function at addr */
-static void add_redirect_sym_to_addr(const Char *from_lib, const Char *f=
rom_sym,
- Addr to_addr)
+static void add_redirect_sym_to_addr(
+ const Char *from_lib, const Char *from_sym, Addr to_addr
+)
{
- add_redirect_X_to_addr(from_lib, from_sym, 0, to_addr);
-}
+ CodeRedirect *redir =3D VG_(SkipNode_Alloc)(&sk_resolved_redirs);
=20
-/* Redirect a function at from_addr to a function at to_addr */
-__attribute__((unused)) // It is used, but not on all platforms...
-static void add_redirect_addr_to_addr(Addr from_addr, Addr to_addr)
-{
- add_redirect_X_to_addr(NULL, NULL, from_addr, to_addr);
+ vg_assert(from_lib && from_sym && 0 !=3D to_addr);
+
+ redir->type =3D R_REDIRECT;
+ redir->from_lib =3D VG_(arena_strdup)(VG_AR_SYMTAB, from_lib);
+ redir->from_sym =3D VG_(arena_strdup)(VG_AR_SYMTAB, from_sym);
+ redir->from_addr =3D 0;
+ redir->to_addr =3D to_addr;
+ redir->wrapper =3D 0;
+
+ TRACE_REDIR("REDIR sym to addr: %s:%s to %p", from_lib, from_sym, to_=
addr);
+
+ // Check against all existing segments to see if this redirection
+ // can be resolved immediately. Then add it to the appropriate list.
+ if (resolve_redir_with_existing_seginfos(redir)) {
+ add_redir_to_resolved_list(redir);
+ } else {
+ add_redir_to_unresolved_list(redir);
+ }
}
=20
CodeRedirect *VG_(add_wrapper)(const Char *from_lib, const Char *from_sy=
m,
const FuncWrapper *wrapper)
{
- CodeRedirect *redir =3D VG_(SkipNode_Alloc)(&sk_resolved_redir);
+ CodeRedirect *redir =3D VG_(SkipNode_Alloc)(&sk_resolved_redirs);
=20
- if (0)
- VG_(printf)("adding wrapper for %s:%s -> (%p,%p)\n",
- from_lib, from_sym, wrapper->before, wrapper->after);
-
- redir->type =3D R_WRAPPER;
-
+ redir->type =3D R_WRAPPER;
redir->from_lib =3D VG_(arena_strdup)(VG_AR_SYMTAB, from_lib);
redir->from_sym =3D VG_(arena_strdup)(VG_AR_SYMTAB, from_sym);
redir->from_addr =3D 0;
redir->to_addr =3D 0;
redir->wrapper =3D wrapper;
=20
- /* Check against all existing segments to see if this redirection
- can be resolved immediately */
- if (!resolve_redir_allsegs(redir)) {
- /* nope, add to list */
- redir->next =3D unresolved_redir;
- unresolved_redir =3D redir;
+ TRACE_REDIR("REDIR sym to wrapper: %s:%s to (%p,%p)",
+ from_lib, from_sym, wrapper->before, wrapper->after);
+
+ // Check against all existing segments to see if this redirection
+ // can be resolved immediately. Then add it to the appropriate list.
+ if (resolve_redir_with_existing_seginfos(redir)) {
+ add_redir_to_resolved_list(redir);
+ } else {
+ add_redir_to_unresolved_list(redir);
}
=20
return redir;
@@ -341,7 +327,7 @@
{
CodeRedirect* r;
=20
- r =3D VG_(SkipList_Find_Exact)(&sk_resolved_redir, &a);
+ r =3D VG_(SkipList_Find_Exact)(&sk_resolved_redirs, &a);
if (r =3D=3D NULL)
return a;
=20
Modified: trunk/coregrind/pub_core_redir.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/pub_core_redir.h 2005-06-26 02:19:17 UTC (rev 4027)
+++ trunk/coregrind/pub_core_redir.h 2005-06-26 04:49:25 UTC (rev 4028)
@@ -71,7 +71,7 @@
/* Set up some default redirects */
extern void VG_(setup_code_redirect_table) ( void );
=20
-extern void VG_(resolve_seg_redirs)(SegInfo *si);
+extern void VG_(resolve_existing_redirs_with_seginfo)(SegInfo *si);
=20
=20
//--------------------------------------------------------------------
|