Author: sewardj
Date: 2008-01-11 07:24:37 +0000 (Fri, 11 Jan 2008)
New Revision: 7338

Log:
Enhancements to debuginfo segment-lookup functions:

Change VG_(seginfo_sect_kind) so it also produces an object file
name as well as a VgSectKind.  Adjust users accordingly.  Make
use of this in Memcheck's address-describer.

Remove VG_(seginfo_sect_kind_name) and replace it with
VG_(pp_SectKind), so as to independently have a way to print
VgSectKinds without doing the address lookup.

Modified:
   branches/DATASYMS/callgrind/bb.c
   branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c
   branches/DATASYMS/exp-drd/drd_error.c
   branches/DATASYMS/exp-drd/drd_main.c
   branches/DATASYMS/include/pub_tool_debuginfo.h
   branches/DATASYMS/memcheck/mc_main.c


Modified: branches/DATASYMS/callgrind/bb.c
===================================================================
--- branches/DATASYMS/callgrind/bb.c    2008-01-10 17:54:50 UTC (rev 7337)
+++ branches/DATASYMS/callgrind/bb.c    2008-01-11 07:24:37 UTC (rev 7338)
@@ -141,7 +141,7 @@
    new->jmp         = (CJmpInfo*) &(new->instr[instr_count]);
    new->instr_len   = 0;
    new->cost_count  = 0;
-   new->sect_kind   = VG_(seginfo_sect_kind)(offset + obj->offset);
+   new->sect_kind   = VG_(seginfo_sect_kind)(NULL, 0, offset + obj->offset);
    new->fn          = 0;
    new->line        = 0;
    new->is_entry    = 0;

Modified: branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c 2008-01-10 17:54:50 UTC 
(rev 7337)
+++ branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c 2008-01-11 07:24:37 UTC 
(rev 7338)
@@ -1511,9 +1511,58 @@
    return di->text_bias;
 }
 
-VgSectKind VG_(seginfo_sect_kind)(Addr a)
+Int VG_(seginfo_syms_howmany) ( const DebugInfo *si )
 {
+   return si->symtab_used;
+}
+
+void VG_(seginfo_syms_getidx) ( const DebugInfo *si, 
+                                      Int idx,
+                               /*OUT*/Addr*   addr,
+                               /*OUT*/Addr*   tocptr,
+                               /*OUT*/UInt*   size,
+                               /*OUT*/HChar** name,
+                               /*OUT*/Bool*   isText )
+{
+   vg_assert(idx >= 0 && idx < si->symtab_used);
+   if (addr)   *addr   = si->symtab[idx].addr;
+   if (tocptr) *tocptr = si->symtab[idx].tocptr;
+   if (size)   *size   = si->symtab[idx].size;
+   if (name)   *name   = (HChar*)si->symtab[idx].name;
+   if (isText) *isText = si->symtab[idx].isText;
+}
+
+
+/*------------------------------------------------------------*/
+/*--- SectKind query functions                             ---*/
+/*------------------------------------------------------------*/
+
+/* Convert a VgSectKind to a string, which must be copied if you want
+   to change it. */
+const HChar* VG_(pp_SectKind)( VgSectKind kind )
+{
+   switch (kind) {
+      case Vg_SectUnknown: return "Unknown";
+      case Vg_SectText:    return "Text";
+      case Vg_SectData:    return "Data";
+      case Vg_SectBSS:     return "BSS";
+      case Vg_SectGOT:     return "GOT";
+      case Vg_SectPLT:     return "PLT";
+      case Vg_SectOPD:     return "OPD";
+      default:             vg_assert(0);
+   }
+}
+
+/* Given an address 'a', make a guess of which section of which object
+   it comes from.  If name is non-NULL, then the last n_name-1
+   characters of the object's name is put in name[0 .. n_name-2], and
+   name[n_name-1] is set to zero (guaranteed zero terminated). */
+
+VgSectKind VG_(seginfo_sect_kind)( /*OUT*/UChar* name, SizeT n_name, 
+                                   Addr a)
+{
    DebugInfo* di;
+   VgSectKind res = Vg_SectUnknown;
 
    for (di = debugInfo_list; di != NULL; di = di->next) {
 
@@ -1527,84 +1576,69 @@
             di->bss_avma,  di->bss_size);
 
       if (di->text_size > 0
-          && a >= di->text_avma && a < di->text_avma + di->text_size)
-         return Vg_SectText;
-
+          && a >= di->text_avma && a < di->text_avma + di->text_size) {
+         res = Vg_SectText;
+         break;
+      }
       if (di->data_size > 0
-          && a >= di->data_avma && a < di->data_avma + di->data_size)
-         return Vg_SectData;
-
+          && a >= di->data_avma && a < di->data_avma + di->data_size) {
+         res = Vg_SectData;
+         break;
+      }
       if (di->bss_size > 0
-          && a >= di->bss_avma && a < di->bss_avma + di->bss_size)
-         return Vg_SectBSS;
-
+          && a >= di->bss_avma && a < di->bss_avma + di->bss_size) {
+         res = Vg_SectBSS;
+         break;
+      }
       if (di->plt_size > 0
-          && a >= di->plt_avma && a < di->plt_avma + di->plt_size)
-         return Vg_SectPLT;
-
+          && a >= di->plt_avma && a < di->plt_avma + di->plt_size) {
+         res = Vg_SectPLT;
+         break;
+      }
       if (di->got_size > 0
-          && a >= di->got_avma && a < di->got_avma + di->got_size)
-         return Vg_SectGOT;
-
+          && a >= di->got_avma && a < di->got_avma + di->got_size) {
+         res = Vg_SectGOT;
+         break;
+      }
       if (di->opd_size > 0
-          && a >= di->opd_avma && a < di->opd_avma + di->opd_size)
-         return Vg_SectOPD;
-
+          && a >= di->opd_avma && a < di->opd_avma + di->opd_size) {
+         res = Vg_SectOPD;
+         break;
+      }
       /* we could also check for .eh_frame, if anyone really cares */
    }
 
-   return Vg_SectUnknown;
-}
+   vg_assert( (di == NULL && res == Vg_SectUnknown)
+              || (di != NULL && res != Vg_SectUnknown) );
 
-Char* VG_(seginfo_sect_kind_name)(Addr a, Char* buf, UInt n_buf)
-{
-   switch (VG_(seginfo_sect_kind)(a)) {
-      case Vg_SectUnknown:
-         VG_(snprintf)(buf, n_buf, "Unknown");
-         break;
-      case Vg_SectText:
-         VG_(snprintf)(buf, n_buf, "Text");
-         break;
-      case Vg_SectData:
-         VG_(snprintf)(buf, n_buf, "Data");
-         break;
-      case Vg_SectBSS:
-         VG_(snprintf)(buf, n_buf, "BSS");
-         break;
-      case Vg_SectGOT:
-         VG_(snprintf)(buf, n_buf, "GOT");
-         break;
-      case Vg_SectPLT:
-         VG_(snprintf)(buf, n_buf, "PLT");
-         break;
-      case Vg_SectOPD:
-         VG_(snprintf)(buf, n_buf, "OPD");
-         break;
-      default:
-         vg_assert(0);
+   if (name) {
+
+      vg_assert(n_name >= 8);
+
+      if (di && di->filename) {
+         Int i, j;
+         Int fnlen = VG_(strlen)(di->filename);
+         Int start_at = 1 + fnlen - n_name;
+         if (start_at < 0) start_at = 0;
+         vg_assert(start_at < fnlen);
+         i = start_at; j = 0;
+         while (True) {
+            vg_assert(j >= 0 && j+1 < n_name);
+            vg_assert(i >= 0 && i <= fnlen);
+            name[j] = di->filename[i];
+            name[j+1] = 0;
+            if (di->filename[i] == 0) break;
+            i++; j++;
+         }
+      } else {
+         VG_(snprintf)(name, n_name, "%s", "???");
+      }
+
+      name[n_name-1] = 0;
    }
-   return buf;
-}
 
-Int VG_(seginfo_syms_howmany) ( const DebugInfo *si )
-{
-   return si->symtab_used;
-}
+   return res;
 
-void VG_(seginfo_syms_getidx) ( const DebugInfo *si, 
-                                      Int idx,
-                               /*OUT*/Addr*   addr,
-                               /*OUT*/Addr*   tocptr,
-                               /*OUT*/UInt*   size,
-                               /*OUT*/HChar** name,
-                               /*OUT*/Bool*   isText )
-{
-   vg_assert(idx >= 0 && idx < si->symtab_used);
-   if (addr)   *addr   = si->symtab[idx].addr;
-   if (tocptr) *tocptr = si->symtab[idx].tocptr;
-   if (size)   *size   = si->symtab[idx].size;
-   if (name)   *name   = (HChar*)si->symtab[idx].name;
-   if (isText) *isText = si->symtab[idx].isText;
 }
 
 

Modified: branches/DATASYMS/exp-drd/drd_error.c
===================================================================
--- branches/DATASYMS/exp-drd/drd_error.c       2008-01-10 17:54:50 UTC (rev 
7337)
+++ branches/DATASYMS/exp-drd/drd_error.c       2008-01-11 07:24:37 UTC (rev 
7338)
@@ -132,10 +132,8 @@
       {
          Char filename[512];
          Char soname[512];
-         Char sect_kind_name[16];
-
-         VG_(seginfo_sect_kind_name)(a, sect_kind_name,
-                                     sizeof(sect_kind_name));
+         VgSectKind kind = VG_(seginfo_sect_kind)(NULL, 0, a);
+         const HChar* sect_kind_name = VG_(pp_SectKind)(kind);
          VG_(strncpy)(filename, VG_(seginfo_filename)(sg), sizeof(filename));
          filename[sizeof(filename) - 1] = 0;
          make_path_relative(filename);

Modified: branches/DATASYMS/exp-drd/drd_main.c
===================================================================
--- branches/DATASYMS/exp-drd/drd_main.c        2008-01-10 17:54:50 UTC (rev 
7337)
+++ branches/DATASYMS/exp-drd/drd_main.c        2008-01-11 07:24:37 UTC (rev 
7338)
@@ -524,7 +524,8 @@
       switch (st->tag)
       {
       case Ist_IMark:
-         instrument = VG_(seginfo_sect_kind)(st->Ist.IMark.addr) != Vg_SectPLT;
+         instrument = VG_(seginfo_sect_kind)(NULL, 0, st->Ist.IMark.addr)
+                      != Vg_SectPLT;
          break;
 
       case Ist_AbiHint:

Modified: branches/DATASYMS/include/pub_tool_debuginfo.h
===================================================================
--- branches/DATASYMS/include/pub_tool_debuginfo.h      2008-01-10 17:54:50 UTC 
(rev 7337)
+++ branches/DATASYMS/include/pub_tool_debuginfo.h      2008-01-11 07:24:37 UTC 
(rev 7338)
@@ -130,6 +130,9 @@
                                         /*OUT*/UInt*   size,
                                         /*OUT*/HChar** name,
                                         /*OUT*/Bool*   isText );
+
+/* A simple enumeration to describe the 'kind' of various kinds of
+   segments that arise from the mapping of object files. */
 typedef
    enum {
       Vg_SectUnknown,
@@ -142,9 +145,18 @@
    }
    VgSectKind;
 
-extern VgSectKind VG_(seginfo_sect_kind)(Addr);
+/* Convert a VgSectKind to a string, which must be copied if you want
+   to change it. */
+extern
+const HChar* VG_(pp_SectKind)( VgSectKind kind );
 
-extern Char* VG_(seginfo_sect_kind_name)(Addr a, Char* buf, UInt n_buf);
+/* Given an address 'a', make a guess of which section of which object
+   it comes from.  If name is non-NULL, then the last n_name-1
+   characters of the object's name is put in name[0 .. n_name-2], and
+   name[n_name-1] is set to zero (guaranteed zero terminated). */
+extern 
+VgSectKind VG_(seginfo_sect_kind)( /*OUT*/UChar* name, SizeT n_name, 
+                                   Addr a);
 
 
 #endif   // __PUB_TOOL_DEBUGINFO_H

Modified: branches/DATASYMS/memcheck/mc_main.c
===================================================================
--- branches/DATASYMS/memcheck/mc_main.c        2008-01-10 17:54:50 UTC (rev 
7337)
+++ branches/DATASYMS/memcheck/mc_main.c        2008-01-11 07:24:37 UTC (rev 
7338)
@@ -2626,11 +2626,12 @@
 /* The classification of a faulting address. */
 typedef 
    enum { 
-      Addr_Undescribed,   // as-yet unclassified
-      Addr_Unknown,       // classification yielded nothing useful
-      Addr_Stack,          
-      Addr_Block,
-      Addr_GlobalData
+      Addr_Undescribed, // as-yet unclassified
+      Addr_Unknown,     // classification yielded nothing useful
+      Addr_Stack,       // on a thread's stack       
+      Addr_Block,       // in malloc'd/free'd block
+      Addr_GlobalData,  // in a global data sym
+      Addr_SectKind     // last-ditch classification attempt
    }
    AddrTag;
 
@@ -2666,6 +2667,13 @@
          OffT offset;
       } GlobalData;
 
+      // Could only narrow it down to be the PLT/GOT/etc of a given
+      // object.  Better than nothing, perhaps.
+      struct {
+         Char       objname[64];
+         VgSectKind kind;
+      } SectKind;
+
       // Classification yielded nothing useful.
       struct { } Unknown;
 
@@ -2853,6 +2861,16 @@
                       xpost);
          break;
 
+      case Addr_SectKind:
+         VG_(message)(Vg_UserMsg, 
+                      "%sAddress 0x%llx is in the %t segment of %t%s",
+                      xpre, 
+                      (ULong)a, 
+                      VG_(pp_SectKind)(ai->Addr.SectKind.kind),
+                      ai->Addr.SectKind.objname, 
+                      xpost);
+         break;
+
       default:
          VG_(tool_panic)("mc_pp_AddrInfo");
    }
@@ -3343,9 +3361,10 @@
    putting the result in ai. */
 static void describe_addr ( Addr a, AddrInfo* ai )
 {
-   MC_Chunk* mc;
-   ThreadId  tid;
-   Addr      stack_min, stack_max;
+   MC_Chunk*  mc;
+   ThreadId   tid;
+   Addr       stack_min, stack_max;
+   VgSectKind sect;
 
    tl_assert(Addr_Undescribed == ai->tag);
 
@@ -3400,6 +3419,20 @@
                     [ sizeof(ai->Addr.GlobalData.name)-1 ] == 0);
       return;
    }
+   /* last ditch attempt at classification */
+   tl_assert( sizeof(ai->Addr.SectKind.objname) > 4 );
+   VG_(memset)( &ai->Addr.SectKind.objname, 
+                0, sizeof(ai->Addr.SectKind.objname));
+   VG_(strcpy)( ai->Addr.SectKind.objname, "???" );
+   sect = VG_(seginfo_sect_kind)( &ai->Addr.SectKind.objname[0],
+                                  sizeof(ai->Addr.SectKind.objname)-1, a);
+   if (sect != Vg_SectUnknown) {
+      ai->tag = Addr_SectKind;
+      ai->Addr.SectKind.kind = sect;
+      tl_assert( ai->Addr.SectKind.objname
+                    [ sizeof(ai->Addr.SectKind.objname)-1 ] == 0);
+      return;
+   }
    /* Clueless ... */
    ai->tag = Addr_Unknown;
    return;


-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
Valgrind-developers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/valgrind-developers

Reply via email to