Merge in the DATASYMS branch.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@7540 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/include/pub_tool_debuginfo.h b/include/pub_tool_debuginfo.h
index 1c03ce0..a6849ab 100644
--- a/include/pub_tool_debuginfo.h
+++ b/include/pub_tool_debuginfo.h
@@ -74,9 +74,27 @@
    entry points within it. */
 extern Bool VG_(get_fnname_if_entry) ( Addr a, Char* fnname, Int n_fnname );
 
+/* Looks up data_addr in the collection of data symbols, and if found
+   puts its name (or as much as will fit) into dname[0 .. n_dname-1],
+   which is guaranteed to be zero terminated.  Also data_addr's offset
+   from the symbol start is put into *offset. */
+extern Bool VG_(get_datasym_and_offset)( Addr data_addr,
+                                         /*OUT*/Char* dname, Int n_dname,
+                                         /*OUT*/OffT* offset );
+
+/* Try to form some description of data_addr by looking at the DWARF3
+   debug info we have.  This considers all global variables, and all
+   frames in the stacks of all threads.  Result (or as much as will
+   fit) is put into into dname{1,2}[0 .. n_dname-1] and is guaranteed
+   to be zero terminated. */
+extern Bool VG_(get_data_description)( /*OUT*/Char* dname1,
+                                       /*OUT*/Char* dname2,
+                                       Int  n_dname,
+                                       Addr data_addr );
+
 /* Succeeds if the address is within a shared object or the main executable.
    It doesn't matter if debug info is present or not. */
-extern Bool VG_(get_objname)  ( Addr a, Char* objname,  Int n_objname  );
+extern Bool VG_(get_objname)  ( Addr a, Char* objname, Int n_objname );
 
 /* Puts into 'buf' info about the code address %eip:  the address, function
    name (if known) and filename/line number (if known), like this:
@@ -87,42 +105,44 @@
 */
 extern Char* VG_(describe_IP)(Addr eip, Char* buf, Int n_buf);
 
-
 /*====================================================================*/
 /*=== Obtaining segment information                                ===*/
 /*====================================================================*/
 
 /* A way to get information about what segments are mapped */
-typedef struct _SegInfo SegInfo;
+typedef struct _DebugInfo DebugInfo;
 
-/* Returns NULL if the SegInfo isn't found.  It doesn't matter if debug info
-   is present or not. */
-extern       SegInfo* VG_(find_seginfo)      ( Addr a );
+/* Returns NULL if the DebugInfo isn't found.  It doesn't matter if
+   debug info is present or not. */
+extern       DebugInfo* VG_(find_seginfo)      ( Addr a );
 
-/* Fish bits out of SegInfos. */
-extern       Addr     VG_(seginfo_start)     ( const SegInfo *si );
-extern       SizeT    VG_(seginfo_size)      ( const SegInfo *si );
-extern const UChar*   VG_(seginfo_soname)    ( const SegInfo *si );
-extern const UChar*   VG_(seginfo_filename)  ( const SegInfo *si );
-extern       ULong    VG_(seginfo_sym_offset)( const SegInfo *si );
+/* Fish bits out of DebugInfos. */
+extern       Addr     VG_(seginfo_get_text_avma)( const DebugInfo *di );
+extern       SizeT    VG_(seginfo_get_text_size)( const DebugInfo *di );
+extern const UChar*   VG_(seginfo_soname)       ( const DebugInfo *di );
+extern const UChar*   VG_(seginfo_filename)     ( const DebugInfo *di );
+extern       ULong    VG_(seginfo_get_text_bias)( const DebugInfo *di );
 
 /* Function for traversing the seginfo list.  When called with NULL it
    returns the first element; otherwise it returns the given element's
    successor. */
-extern const SegInfo* VG_(next_seginfo)      ( const SegInfo *si );
+extern const DebugInfo* VG_(next_seginfo)    ( const DebugInfo *di );
 
-/* Functions for traversing all the symbols in a SegInfo.  _howmany
+/* Functions for traversing all the symbols in a DebugInfo.  _howmany
    tells how many there are.  _getidx retrieves the n'th, for n in 0
    .. _howmany-1.  You may not modify the function name thereby
    acquired; if you want to do so, first strdup it. */
-extern Int  VG_(seginfo_syms_howmany) ( const SegInfo *si );
-extern void VG_(seginfo_syms_getidx)  ( const SegInfo *si, 
+extern Int  VG_(seginfo_syms_howmany) ( const DebugInfo *di );
+extern void VG_(seginfo_syms_getidx)  ( const DebugInfo *di, 
                                         Int idx,
-                                        /*OUT*/Addr*   addr,
+                                        /*OUT*/Addr*   avma,
                                         /*OUT*/Addr*   tocptr,
                                         /*OUT*/UInt*   size,
-                                        /*OUT*/HChar** name );
+                                        /*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,
@@ -130,13 +150,23 @@
       Vg_SectData,
       Vg_SectBSS,
       Vg_SectGOT,
-      Vg_SectPLT
+      Vg_SectPLT,
+      Vg_SectOPD
    }
    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
diff --git a/include/pub_tool_libcbase.h b/include/pub_tool_libcbase.h
index 309ad4d..5b8cdad 100644
--- a/include/pub_tool_libcbase.h
+++ b/include/pub_tool_libcbase.h
@@ -135,8 +135,9 @@
 extern void VG_(ssort)( void* base, SizeT nmemb, SizeT size,
                         Int (*compar)(void*, void*) );
 
-/* Returns the base-2 logarithm of x.  Returns -1 if x is not a power of two. */
-extern Int VG_(log2) ( Int x );
+/* Returns the base-2 logarithm of x.  Returns -1 if x is not a power
+   of two. */
+extern Int VG_(log2) ( UInt x );
 
 // A pseudo-random number generator returning a random UInt.  If pSeed
 // is NULL, it uses its own seed, which starts at zero.  If pSeed is
diff --git a/include/pub_tool_machine.h b/include/pub_tool_machine.h
index e261593..c8556b5 100644
--- a/include/pub_tool_machine.h
+++ b/include/pub_tool_machine.h
@@ -94,11 +94,13 @@
 // doing leak checking.
 extern void VG_(apply_to_GP_regs)(void (*f)(UWord val));
 
-// This iterator lets you inspect each live thread's stack bounds.  The
-// params are all 'out' params.  Returns False at the end.
-extern void VG_(thread_stack_reset_iter) ( void );
-extern Bool VG_(thread_stack_next)       ( ThreadId* tid, Addr* stack_min,
-                                                          Addr* stack_max );
+// This iterator lets you inspect each live thread's stack bounds.
+// Returns False at the end.  'tid' is the iterator and you can only
+// safely change it by making calls to these functions.
+extern void VG_(thread_stack_reset_iter) ( /*OUT*/ThreadId* tid );
+extern Bool VG_(thread_stack_next)       ( /*MOD*/ThreadId* tid,
+                                           /*OUT*/Addr* stack_min, 
+                                           /*OUT*/Addr* stack_max );
 
 // Returns .client_stack_highest_word for the given thread
 extern Addr VG_(thread_get_stack_max) ( ThreadId tid );
diff --git a/include/pub_tool_oset.h b/include/pub_tool_oset.h
index 44b1a19..a068d3e 100644
--- a/include/pub_tool_oset.h
+++ b/include/pub_tool_oset.h
@@ -39,9 +39,9 @@
 // It has two interfaces.  
 //
 // - The "OSetWord_" interface provides an easier-to-use interface for the
-//   case where you just want to store Word-sized values.  The user provides
-//   the allocation and deallocation functions, and possibly a comparison
-//   function.
+//   case where you just want to store UWord-sized values.  The user
+//   provides the allocation and deallocation functions, and possibly a 
+//   comparison function.
 //
 // - The "OSetGen_" interface provides a totally generic interface, which
 //   allows any kind of structure to be put into the set.  The user provides
@@ -81,7 +81,7 @@
 typedef void  (*OSetFree_t)        ( void* p );
 
 /*--------------------------------------------------------------------*/
-/*--- Creating and destroying OSets (Word)                         ---*/
+/*--- Creating and destroying OSets (UWord)                        ---*/
 /*--------------------------------------------------------------------*/
 
 // * Create: allocates and initialises the OSet.  Arguments:
@@ -102,7 +102,7 @@
 extern void  VG_(OSetWord_Destroy)      ( OSet* os );
 
 /*--------------------------------------------------------------------*/
-/*--- Operations on OSets (Word)                                   ---*/
+/*--- Operations on OSets (UWord)                                  ---*/
 /*--------------------------------------------------------------------*/
 
 // In everything that follows, the parameter 'key' is always the *address*
@@ -124,8 +124,8 @@
 // 
 // * Next: Copies the next value according to the OSet's iterator into &val,
 //   advances the iterator by one, and returns True;  the elements are
-//   visited in order.  Or, returns False if the iterator has reached the
-//   set's end.
+//   visited in increasing order of unsigned words (UWord).  Or, returns
+//   False if the iterator has reached the set's end.
 //   
 //   You can thus iterate in order through a set like this:
 //
@@ -141,12 +141,12 @@
 //   they will return False if VG_(OSetWord_Next)() is called without an
 //   intervening call to VG_(OSetWord_ResetIter)().
 
-extern Int   VG_(OSetWord_Size)         ( OSet* os );
-extern void  VG_(OSetWord_Insert)       ( OSet* os, Word val );
-extern Bool  VG_(OSetWord_Contains)     ( OSet* os, Word val );
-extern Bool  VG_(OSetWord_Remove)       ( OSet* os, Word val );
+extern Word  VG_(OSetWord_Size)         ( OSet* os );
+extern void  VG_(OSetWord_Insert)       ( OSet* os, UWord val );
+extern Bool  VG_(OSetWord_Contains)     ( OSet* os, UWord val );
+extern Bool  VG_(OSetWord_Remove)       ( OSet* os, UWord val );
 extern void  VG_(OSetWord_ResetIter)    ( OSet* os );
-extern Bool  VG_(OSetWord_Next)         ( OSet* os, Word* val );
+extern Bool  VG_(OSetWord_Next)         ( OSet* os, /*OUT*/UWord* val );
 
 
 /*--------------------------------------------------------------------*/
@@ -234,15 +234,22 @@
 //   they will return NULL if VG_(OSetGen_Next)() is called without an
 //   intervening call to VG_(OSetGen_ResetIter)().
 
-extern Int   VG_(OSetGen_Size)         ( const OSet* os );
+extern Word  VG_(OSetGen_Size)         ( const OSet* os );
 extern void  VG_(OSetGen_Insert)       ( OSet* os, void* elem );
 extern Bool  VG_(OSetGen_Contains)     ( const OSet* os, const void* key  );
 extern void* VG_(OSetGen_Lookup)       ( const OSet* os, const void* key  );
-extern void* VG_(OSetGen_LookupWithCmp)( OSet* os, const void* key, OSetCmp_t cmp );
+extern void* VG_(OSetGen_LookupWithCmp)( OSet* os,
+                                         const void* key, OSetCmp_t cmp );
 extern void* VG_(OSetGen_Remove)       ( OSet* os, const void* key  );
 extern void  VG_(OSetGen_ResetIter)    ( OSet* os );
 extern void* VG_(OSetGen_Next)         ( OSet* os );
 
+// set up 'oset' for iteration so that the first key subsequently
+// produced VG_(OSetGen_Next) is the smallest key in the map 
+// >= start_at.  Naturally ">=" is defined by the comparison 
+// function supplied to VG_(OSetGen_Create).
+extern void VG_(OSetGen_ResetIterAt) ( OSet* oset, void* key );
+
 #endif   // __PUB_TOOL_OSET_H
 
 /*--------------------------------------------------------------------*/
diff --git a/include/pub_tool_stacktrace.h b/include/pub_tool_stacktrace.h
index 5387676..9fda821 100644
--- a/include/pub_tool_stacktrace.h
+++ b/include/pub_tool_stacktrace.h
@@ -34,13 +34,20 @@
 // The basic stack trace type:  just an array of code addresses.
 typedef Addr* StackTrace;
 
-// Walks the stack to get instruction pointers from the top stack frames for
-// thread 'tid'.  Maximum of 'n_ips' addresses put into 'ips';  0 is the top
-// of the stack, 1 is its caller, etc.  Everything from ips[n_ips] onwards
-// is undefined and should not be read.  The initial IP value to 
-// use is adjusted by first_ip_delta before the stack is unwound.
-// A safe value to pass is zero.
-extern UInt VG_(get_StackTrace) ( ThreadId tid, StackTrace ips, UInt n_ips,
+// Walks the stack to get instruction pointers from the top stack frames 
+// for thread 'tid'.  Maximum of 'n_ips' addresses put into 'ips';
+// 0 is the top of the stack, 1 is its caller, etc.  Everything from
+// ips[return_value] onwards is undefined and should not be read.
+// The initial IP value to use is adjusted by first_ip_delta before
+// the stack is unwound. A safe value to pass is zero.
+//
+// If sps and fps are non-NULL, the corresponding frame-pointer and
+// stack-pointer values for each frame are stored there.
+
+extern UInt VG_(get_StackTrace) ( ThreadId tid, 
+                                  /*OUT*/StackTrace ips, UInt n_ips,
+                                  /*OUT*/StackTrace sps,
+                                  /*OUT*/StackTrace fps,
                                   Word first_ip_delta );
 
 // Apply a function to every element in the StackTrace.  The parameter 'n'
diff --git a/include/pub_tool_tooliface.h b/include/pub_tool_tooliface.h
index 0c0dafa..f75c74a 100644
--- a/include/pub_tool_tooliface.h
+++ b/include/pub_tool_tooliface.h
@@ -416,8 +416,8 @@
    Bool(*expensive_sanity_check)(void)
 );
 
-/* Do we need to see data symbols? */
-extern void VG_(needs_data_syms) ( void );
+/* Do we need to see variable type and location information? */
+extern void VG_(needs_var_info) ( void );
 
 /* Does the tool replace malloc() and friends with its own versions?
    This has to be combined with the use of a vgpreload_<tool>.so module
diff --git a/include/pub_tool_xarray.h b/include/pub_tool_xarray.h
index 6862982..b223fea 100644
--- a/include/pub_tool_xarray.h
+++ b/include/pub_tool_xarray.h
@@ -66,6 +66,11 @@
    invalidated if the array is later sortXA'd. */
 extern Int VG_(addToXA) ( XArray*, void* elem );
 
+/* Add a sequence of bytes to an XArray of bytes.  Asserts if nbytes
+   is negative or the array's element size is not 1.  Returns the
+   index at which the first byte was added. */
+extern Int VG_(addBytesToXA) ( XArray* xao, void* bytesV, Int nbytes );
+
 /* Sort an XArray using its comparison function, if set; else bomb.
    Probably not a stable sort w.r.t. equal elements module cmpFn. */
 extern void VG_(sortXA) ( XArray* );
@@ -94,6 +99,11 @@
    than n elements in the array. */
 extern void VG_(dropTailXA) ( XArray*, Word );
 
+/* Make a new, completely independent copy of the given XArray, using
+   the existing allocation function to allocate the new space.
+   Returns NULL if the allocation function didn't manage to allocate
+   space (but did return NULL rather than merely abort.) */
+extern XArray* VG_(cloneXA)( XArray* xa );
 
 #endif   // __PUB_TOOL_XARRAY_H