]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Cleaned up m_redir.c: renamed some variables and functions, added some
authorNicholas Nethercote <njn@valgrind.org>
Sun, 26 Jun 2005 04:49:25 +0000 (04:49 +0000)
committerNicholas Nethercote <njn@valgrind.org>
Sun, 26 Jun 2005 04:49:25 +0000 (04:49 +0000)
comments, neatened the debugging output, avoided unexpected side-effects
in functions, tweaked code to make it clearer.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@4028

coregrind/m_debuginfo/symtab.c
coregrind/m_redir.c
coregrind/pub_core_redir.h

index 379a5e8cd8414001339b90a891a1c6afd94e57da..9a516b454418958b50639d2cb17a34dcd7322311 100644 (file)
@@ -1650,7 +1650,7 @@ SegInfo *VG_(read_seg_symbols) ( Addr seg_addr, SizeT seg_len,
       canonicaliseCfiSI    ( si );
 
       /* do redirects */
-      VG_(resolve_seg_redirs)( si );
+      VG_(resolve_existing_redirs_with_seginfo)( si );
    }
    VGP_POPCC(VgpReadSyms);
 
index 78e29eeef14a546693ceea82ec53e28ea955b60e..0f66a578329b2136d98f6b1c2784355c0b3f6cf3 100644 (file)
@@ -46,6 +46,9 @@
 /*--- General purpose redirection.                         ---*/
 /*------------------------------------------------------------*/
 
+#define TRACE_REDIR(format, args...) \
+   if (VG_(clo_trace_redir)) { VG_(message)(Vg_DebugMsg, format, ## args); }
+
 /*
   wraps and redirections, indexed by from_addr
 
@@ -71,29 +74,24 @@ struct _CodeRedirect {
    const Char  *from_sym;      /* symbol */
    Addr                from_addr;      /* old addr */
 
-   /* used for redirection */
-   Addr                to_addr;        /* new addr */
-
-   /* used for wrapping */
-   const FuncWrapper *wrapper;
+   Addr                to_addr;        /* used for redirection -- new addr */
+   const FuncWrapper *wrapper;  /* used for wrapping */
 
-   CodeRedirect *next; /* next pointer on unresolved list */
+   CodeRedirect *next;         /* next pointer on unresolved list */
 };
 
 static Char *straddr(void *p)
 {
    static Char buf[16];
-
    VG_(sprintf)(buf, "%p", *(Addr *)p);
-
    return buf;
 }
 
-static SkipList sk_resolved_redir = 
+static SkipList sk_resolved_redirs = 
    VG_SKIPLIST_INIT(CodeRedirect, from_addr, VG_(cmp_Addr), 
                     straddr, VG_AR_SYMTAB);
 
-static CodeRedirect *unresolved_redir = NULL;
+static CodeRedirect *unresolved_redirs = NULL;
 
 static Bool soname_matches(const Char *pattern, const Char* soname)
 {
@@ -107,25 +105,31 @@ static Bool soname_matches(const Char *pattern, const Char* soname)
    return VG_(string_match)(pattern + 7, soname);
 }
 
-static inline Bool from_resolved(const CodeRedirect *redir)
+Bool VG_(is_resolved)(const CodeRedirect *redir)
 {
    return redir->from_addr != 0;
 }
 
-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 = unresolved_redirs;
+   unresolved_redirs = redir;
 }
 
-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=%p -> ",
-                      redir->from_lib, redir->from_sym, redir->from_addr);
-         VG_(message)(Vg_DebugMsg, "                  %p)", redir->to_addr);
-      }
+   vg_assert(redir->from_addr);
+
+   switch (redir->type) {
+   case R_REDIRECT: {
+      CodeRedirect* r;
+   
+      TRACE_REDIR("  redir resolved (%s:%s=%p -> %p)", 
+                  redir->from_lib, redir->from_sym, redir->from_addr,
+                  redir->to_addr);
+
+      vg_assert(redir->to_addr != 0);
 
       if (VG_(search_transtab)(NULL, (Addr64)redir->from_addr, False)) {
          /* For some given (from, to) redir, the "from" function got
@@ -145,191 +149,173 @@ static void add_resolved(CodeRedirect *redir)
             Note, this is potentially expensive -- discarding
             translations causes complete unchaining.  
          */
-         if (VG_(clo_verbosity) > 2 && VG_(clo_trace_redir)) {
-            VG_(message)(Vg_UserMsg,   
-                         "Discarding translation due to redirect of already called function" );
-            VG_(message)(Vg_UserMsg,
-                         "   %s (%p -> %p)",
-                         redir->from_sym, redir->from_addr, redir->to_addr );
-         }
+         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);
       }
 
-      {
-         CodeRedirect *r = VG_(SkipList_Find_Exact)(&sk_resolved_redir, &redir->from_addr);
-
-         if (r == 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 duplicated\n",
-                            redir->from_lib, redir->from_sym, redir->from_addr,
-                            redir->to_addr);
-         }
+      r = VG_(SkipList_Find_Exact)(&sk_resolved_redirs, &redir->from_addr);
+
+      if (r == 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;
+   }
 
    case R_WRAPPER:
-      if (VG_(clo_trace_redir)) {
-         VG_(message)(Vg_DebugMsg, "  wrapper resolved (%s:%s=%p -> wrapper)",
-                      redir->from_lib, redir->from_sym, redir->from_addr);
-      }
+      TRACE_REDIR("  wrapper resolved (%s:%s=%p -> wrapper)",
+                  redir->from_lib, redir->from_sym, redir->from_addr);
+
+      vg_assert(redir->wrapper);
 
       /* XXX redir leaked */
       //VG_(wrap_function)(redir->from_addr, redir->wrapper);
       break;
 
    case R_CLIENT_WRAPPER:
+      vg_assert(redir->wrapper);
       VG_(core_panic)("not implemented");
       break;
    }
 }
 
-/* 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 SegInfo *si)
 {
-   Bool resolved;
+   Bool ok;
 
    vg_assert(si != NULL);
+   vg_assert(redir->from_addr == 0 );
+   vg_assert(redir->from_sym  != NULL);
 
-   resolved = from_resolved(redir);
-   vg_assert(!resolved);
-   vg_assert(redir->from_sym != NULL);
-
-   if (soname_matches(redir->from_lib, VG_(seginfo_soname)(si))) {
+   // Resolved if the soname matches and we find the symbol.
+   ok = soname_matches(redir->from_lib, VG_(seginfo_soname)(si));
+   if (ok) {
       redir->from_addr = VG_(reverse_search_one_symtab)(si, redir->from_sym);
-      if (VG_(clo_trace_redir) && redir->from_addr != 0)
-         VG_(printf)("   bind FROM: %p = %s:%s\n", 
-                     redir->from_addr,redir->from_lib, redir->from_sym );
+      ok = ( redir->from_addr == 0 ? False : True );
    }
-
-   resolved = from_resolved(redir);
-
-   if (0 && VG_(clo_trace_redir))
-      VG_(printf)("resolve_redir: %s:%s from=%p to=%p\n",
-                 redir->from_lib, redir->from_sym, redir->from_addr, 
-                 redir->to_addr);
-
-   if (resolved) add_resolved(redir);
-
-   return resolved;
+   return ok;   
 }
 
-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;
 
-   for(si = VG_(next_seginfo)(NULL); 
-       si != NULL; 
-       si = VG_(next_seginfo)(si))
+   for (si = VG_(next_seginfo)(NULL); 
+        si != NULL; 
+        si = VG_(next_seginfo)(si))
    {
-      if (resolve_redir(redir, si))
+      if (resolve_redir_with_seginfo(redir, si))
         return True;
    }
    return False;
 }
 
-/* Go through the complete redir list, resolving as much as possible with 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.  This
+// should be called when a new SegInfo symtab is loaded.
+void VG_(resolve_existing_redirs_with_seginfo)(SegInfo *si)
 {
-   CodeRedirect **prevp = &unresolved_redir;
+   CodeRedirect **prevp = &unresolved_redirs;
    CodeRedirect *redir, *next;
 
-   if (VG_(clo_trace_redir))
-      VG_(printf)("Considering redirs to/from %s(soname=%s)\n",
-                  VG_(seginfo_filename)(si), VG_(seginfo_soname)(si));
+   TRACE_REDIR("Just loaded %s (soname=%s),",
+               VG_(seginfo_filename)(si), VG_(seginfo_soname)(si));
+   TRACE_REDIR(" resolving any unresolved redirs with it");
 
-   /* visit each unresolved redir - if it becomes resolved, then
-      remove it from the unresolved list */
-   for(redir = unresolved_redir; redir != NULL; redir = next) {
+   // Visit each unresolved redir - if it becomes resolved, then
+   // move it from the unresolved list to the resolved list.
+   for (redir = unresolved_redirs; redir != NULL; redir = next) {
       next = redir->next;
 
-      if (resolve_redir(redir, si)) {
+      if (resolve_redir_with_seginfo(redir, si)) {
         *prevp = next;
         redir->next = NULL;
+         add_redir_to_resolved_list(redir);
       } else
         prevp = &redir->next;
    }
+
+   TRACE_REDIR(" Finished resolving");
 }
 
-static void add_redirect_X_to_addr(
-   const Char *from_lib, const Char *from_sym, Addr from_addr, Addr to_addr
-)
+/* 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 = VG_(SkipNode_Alloc)(&sk_resolved_redir);
+   CodeRedirect *redir = VG_(SkipNode_Alloc)(&sk_resolved_redirs);
 
-   redir->type = R_REDIRECT;
+   vg_assert(0 != from_addr && 0 != to_addr);
 
-   if (from_lib) redir->from_lib  = VG_(arena_strdup)(VG_AR_SYMTAB, from_lib);
-   else          redir->from_lib  = NULL;
-   if (from_sym) redir->from_sym  = VG_(arena_strdup)(VG_AR_SYMTAB, from_sym);
-   else          redir->from_sym  = NULL;
-   
+   redir->type      = R_REDIRECT;
+
+   redir->from_lib  = NULL;
+   redir->from_sym  = NULL;
    redir->from_addr = from_addr;
 
-   vg_assert(0 != to_addr);
-   redir->to_addr = to_addr;
-   redir->wrapper = 0;
+   redir->to_addr   = to_addr;
+   redir->wrapper   = 0;
 
-   if (VG_(clo_verbosity) >= 2 && VG_(clo_trace_redir))
-      VG_(message)(Vg_UserMsg, 
-                   "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);
 
-   /* 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 = unresolved_redir;
-      unresolved_redir = redir;
-   }
+   // This redirection is already resolved, put it straight in the list.
+   add_redir_to_resolved_list(redir);
 }
 
 /* Redirect a lib/symbol reference to a function at addr */
-static void add_redirect_sym_to_addr(const Char *from_lib, const Char *from_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 = VG_(SkipNode_Alloc)(&sk_resolved_redirs);
 
-/* 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 != to_addr);
+
+   redir->type      = R_REDIRECT;
+   redir->from_lib  = VG_(arena_strdup)(VG_AR_SYMTAB, from_lib);
+   redir->from_sym  = VG_(arena_strdup)(VG_AR_SYMTAB, from_sym);
+   redir->from_addr = 0;
+   redir->to_addr   = to_addr;
+   redir->wrapper   = 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);
+   }
 }
 
 CodeRedirect *VG_(add_wrapper)(const Char *from_lib, const Char *from_sym,
                               const FuncWrapper *wrapper)
 {
-   CodeRedirect *redir = VG_(SkipNode_Alloc)(&sk_resolved_redir);
-
-   if (0)
-      VG_(printf)("adding wrapper for %s:%s -> (%p,%p)\n",
-                 from_lib, from_sym, wrapper->before, wrapper->after);
-
-   redir->type = R_WRAPPER;
+   CodeRedirect *redir = VG_(SkipNode_Alloc)(&sk_resolved_redirs);
 
+   redir->type      = R_WRAPPER;
    redir->from_lib  = VG_(arena_strdup)(VG_AR_SYMTAB, from_lib);
    redir->from_sym  = VG_(arena_strdup)(VG_AR_SYMTAB, from_sym);
    redir->from_addr = 0;
    redir->to_addr   = 0;
    redir->wrapper   = wrapper;
    
-   /* 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 = unresolved_redir;
-      unresolved_redir = 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);
    }
 
    return redir;
@@ -341,7 +327,7 @@ Addr VG_(code_redirect)(Addr a)
 {
    CodeRedirect* r;
 
-   r = VG_(SkipList_Find_Exact)(&sk_resolved_redir, &a);
+   r = VG_(SkipList_Find_Exact)(&sk_resolved_redirs, &a);
    if (r == NULL)
       return a;
 
index 06f69b542c2371f28d2550559140af29cd04b355..37435887d51d82978d598e8f6140d04222596dae 100644 (file)
@@ -71,7 +71,7 @@ extern Addr VG_(code_redirect) ( Addr orig );
 /* Set up some default redirects */
 extern void VG_(setup_code_redirect_table) ( void );
 
-extern void VG_(resolve_seg_redirs)(SegInfo *si);
+extern void VG_(resolve_existing_redirs_with_seginfo)(SegInfo *si);
 
 
 //--------------------------------------------------------------------