Merge 07-seginfo from Jeremy Fitzhardinge:

API for skins to extract information about mapped segments.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@1245 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/vg_symtab2.c b/coregrind/vg_symtab2.c
index 1c0d41a..08928cd 100644
--- a/coregrind/vg_symtab2.c
+++ b/coregrind/vg_symtab2.c
@@ -89,36 +89,41 @@
 
 
 /* A structure which contains information pertaining to one mapped
-   text segment. */
-typedef
-   struct _SegInfo {
-      struct _SegInfo* next;
-      /* Description of the mapped segment. */
-      Addr   start;
-      UInt   size;
-      UChar* filename; /* in mallocville */
-      UInt   foffset;
-      /* An expandable array of symbols. */
-      RiSym* symtab;
-      UInt   symtab_used;
-      UInt   symtab_size;
-      /* An expandable array of locations. */
-      RiLoc* loctab;
-      UInt   loctab_used;
-      UInt   loctab_size;
-      /* An expandable array of characters -- the string table. */
-      Char*  strtab;
-      UInt   strtab_used;
-      UInt   strtab_size;
-      /* offset    is what we need to add to symbol table entries
-                   to get the real location of that symbol in memory.
-                   For executables, offset is zero.  
-                   For .so's, offset == base_addr.
-                   This seems like a giant kludge to me.
-      */
-      UInt   offset;
-   } 
-   SegInfo;
+   text segment. (typedef in vg_skin.h) */
+struct _SegInfo {
+   struct _SegInfo* next;
+   /* Description of the mapped segment. */
+   Addr   start;
+   UInt   size;
+   UChar* filename; /* in mallocville */
+   UInt   foffset;
+   /* An expandable array of symbols. */
+   RiSym* symtab;
+   UInt   symtab_used;
+   UInt   symtab_size;
+   /* An expandable array of locations. */
+   RiLoc* loctab;
+   UInt   loctab_used;
+   UInt   loctab_size;
+   /* An expandable array of characters -- the string table. */
+   Char*  strtab;
+   UInt   strtab_used;
+   UInt   strtab_size;
+   /* offset    is what we need to add to symbol table entries
+      to get the real location of that symbol in memory.
+      For executables, offset is zero.  
+      For .so's, offset == base_addr.
+      This seems like a giant kludge to me.
+   */
+   UInt   offset;
+
+   /* Bounds of PLT and GOT, so that skins can see what section an
+      address is in */
+   Addr	  plt_start;
+   UInt   plt_size;
+   Addr   got_start;
+   UInt   got_size;
+};
 
 
 static void freeSegInfo ( SegInfo* si )
@@ -332,7 +337,6 @@
    addLoc ( si, &loc );
 }
 
-
 /*------------------------------------------------------------*/
 /*--- Helpers                                              ---*/
 /*------------------------------------------------------------*/
@@ -1485,14 +1489,18 @@
          */
          if (0 == VG_(strcmp)(".got",sh_strtab + shdr[i].sh_name)) {
             o_got    = (UChar*)(si->offset
-                                + shdr[i].sh_offset);
+                                + shdr[i].sh_addr);
             o_got_sz = shdr[i].sh_size;
+	    si->got_start= (Addr)o_got;
+	    si->got_size = o_got_sz;
             /* check image overrun here */
          }
          if (0 == VG_(strcmp)(".plt",sh_strtab + shdr[i].sh_name)) {
             o_plt    = (UChar*)(si->offset
-                                + shdr[i].sh_offset);
+                                + shdr[i].sh_addr);
             o_plt_sz = shdr[i].sh_size;
+	    si->plt_start= (Addr)o_plt;
+	    si->plt_size = o_plt_sz;
             /* check image overrun here */
          }
 
@@ -2139,6 +2147,65 @@
 
 #undef APPEND
 
+/*------------------------------------------------------------*/
+/*--- SegInfo accessor functions                           ---*/
+/*------------------------------------------------------------*/
+
+const SegInfo* VG_(next_seginfo)(const SegInfo* seg)
+{
+   ensure_debug_info_inited();
+
+   if (seg == NULL)
+      return segInfo;
+   return seg->next;
+}
+
+Addr VG_(seg_start)(const SegInfo* seg)
+{
+   return seg->start;
+}
+
+UInt VG_(seg_size)(const SegInfo* seg)
+{
+   return seg->size;
+}
+
+const UChar* VG_(seg_filename)(const SegInfo* seg)
+{
+   return seg->filename;
+}
+
+UInt VG_(seg_sym_offset)(const SegInfo* seg)
+{
+   return seg->offset;
+}
+
+VgSectKind VG_(seg_sect_kind)(Addr a)
+{
+   SegInfo* seg;
+   VgSectKind ret = Vg_SectUnknown;
+
+   ensure_debug_info_inited();
+
+   for(seg = segInfo; seg != NULL; seg = seg->next) {
+      if (a >= seg->start && a < (seg->start + seg->size)) {
+	 if (0)
+	    VG_(printf)("addr=%p seg=%p %s got=%p %d  plt=%p %d\n",
+			a, seg, seg->filename, 
+			seg->got_start, seg->got_size,
+			seg->plt_start, seg->plt_size);
+	 ret = Vg_SectText;
+
+	 if (a >= seg->plt_start && a < (seg->plt_start + seg->plt_size))
+	    ret = Vg_SectPLT;
+	 else if (a >= seg->got_start && a < (seg->got_start + seg->got_size))
+	    ret = Vg_SectGOT;
+      }
+   }
+
+   return ret;
+}
+
 /*--------------------------------------------------------------------*/
 /*--- end                                             vg_symtab2.c ---*/
 /*--------------------------------------------------------------------*/
diff --git a/include/vg_skin.h b/include/vg_skin.h
index 46cc838..7a2249d 100644
--- a/include/vg_skin.h
+++ b/include/vg_skin.h
@@ -1071,6 +1071,26 @@
    It doesn't matter if debug info is present or not. */
 extern Bool VG_(get_objname)  ( Addr a, Char* objname,  Int n_objname  );
 
+/* A way to get information about what segments are mapped */
+typedef struct _SegInfo SegInfo;
+
+extern const SegInfo* VG_(next_seginfo)(const SegInfo *);
+extern Addr VG_(seg_start)(const SegInfo *);
+extern UInt VG_(seg_size)(const SegInfo *);
+extern const UChar* VG_(seg_filename)(const SegInfo *);
+extern UInt VG_(seg_sym_offset)(const SegInfo *);
+
+typedef
+   enum {
+      Vg_SectUnknown,
+      Vg_SectText,
+      Vg_SectGOT,
+      Vg_SectPLT
+   }
+   VgSectKind;
+
+extern VgSectKind VG_(seg_sect_kind)(Addr);
+
 
 /*====================================================================*/
 /*=== Shadow chunks and block-finding                              ===*/