Changes to allow compilation with -Wwrite-strings. That compiler option
is not used for testcases, just for valgrind proper.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13137 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/Makefile.tool-tests.am b/Makefile.tool-tests.am
index da07ec7..c8fd434 100644
--- a/Makefile.tool-tests.am
+++ b/Makefile.tool-tests.am
@@ -27,6 +27,10 @@
 noinst_DSYMS = $(check_PROGRAMS)
 endif
 
+if HAS_WRITE_STRINGS_WARNING
+CFLAGS += -Wno-write-strings
+endif
+
 check-local: build-noinst_DSYMS
 
 clean-local: clean-noinst_DSYMS
diff --git a/cachegrind/cg_merge.c b/cachegrind/cg_merge.c
index 54b82a3..20556fc 100644
--- a/cachegrind/cg_merge.c
+++ b/cachegrind/cg_merge.c
@@ -111,7 +111,7 @@
 //------------------------------------------------------------------//
 
 
-static char* argv0 = "cg_merge";
+static const char* argv0 = "cg_merge";
 
 /* Keep track of source filename/line no so as to be able to
    print decent error messages. */
@@ -129,7 +129,7 @@
 }
 
 __attribute__((noreturn))
-static void mallocFail ( SOURCE* s, char* who )
+static void mallocFail ( SOURCE* s, const char* who )
 {
    fprintf(stderr, "%s: out of memory in %s\n", argv0, who );
    printSrcLoc( s );
@@ -137,7 +137,7 @@
 }
 
 __attribute__((noreturn))
-static void parseError ( SOURCE* s, char* msg )
+static void parseError ( SOURCE* s, const char* msg )
 {
    fprintf(stderr, "%s: parse error: %s\n", argv0, msg );
    printSrcLoc( s );
@@ -145,7 +145,7 @@
 }
 
 __attribute__((noreturn))
-static void barf ( SOURCE* s, char* msg )
+static void barf ( SOURCE* s, const char* msg )
 {
    fprintf(stderr, "%s: %s\n", argv0, msg );
    printSrcLoc( s );
@@ -186,12 +186,12 @@
    return line[0] != 0;
 }
 
-static Bool streqn ( char* s1, char* s2, size_t n )
+static Bool streqn ( const char* s1, const char* s2, size_t n )
 {
    return 0 == strncmp(s1, s2, n);
 }
 
-static Bool streq ( char* s1, char* s2 )
+static Bool streq ( const char* s1, const char* s2 )
 {
    return 0 == strcmp(s1, s2 );
 }
@@ -534,7 +534,7 @@
 static
 void handle_counts ( SOURCE* s,
                      CacheProfFile* cpf, 
-                     char* fi, char* fn, char* newCountsStr )
+                     const char* fi, const char* fn, char* newCountsStr )
 {
    WordFM* countsMap;
    Bool    freeNewCounts;
@@ -604,10 +604,8 @@
    int            n_tmp_desclines = 0;
    CacheProfFile* cpf;
    Counts*        summaryRead; 
-   char*          curr_fn_init = "???";
-   char*          curr_fl_init = "???";
-   char*          curr_fn      = curr_fn_init;
-   char*          curr_fl      = curr_fl_init;
+   char*          curr_fn = strdup("???");
+   char*          curr_fl = strdup("???");
 
    cpf = new_CacheProfFile( NULL, NULL, NULL, 0, NULL, NULL, NULL );
    if (cpf == NULL)
@@ -686,15 +684,13 @@
       }
       else
       if (streqn(line, "fn=", 3)) {
-         if (curr_fn != curr_fn_init)
-            free(curr_fn);
+         free(curr_fn);
          curr_fn = strdup(line+3);
          continue;
       }
       else
       if (streqn(line, "fl=", 3)) {
-         if (curr_fl != curr_fl_init)
-            free(curr_fl);
+         free(curr_fl);
          curr_fl = strdup(line+3);
          continue;
       }
@@ -742,10 +738,8 @@
       cpf->summary_line = NULL;
    }
 
-   if (curr_fn != curr_fn_init)
-      free(curr_fn);
-   if (curr_fl != curr_fl_init)
-      free(curr_fl);
+   free(curr_fn);
+   free(curr_fl);
 
    // All looks OK
    return cpf;
diff --git a/callgrind/dump.c b/callgrind/dump.c
index 8cdade6..0f38e09 100644
--- a/callgrind/dump.c
+++ b/callgrind/dump.c
@@ -145,7 +145,7 @@
 
 #if 0
 static __inline__
-static void my_fwrite(Int fd, HChar* buf, Int len)
+static void my_fwrite(Int fd, const HChar* buf, Int len)
 {
 	VG_(write)(fd, buf, len);
 }
@@ -165,7 +165,7 @@
     fwrite_pos = 0;
 }
 
-static void my_fwrite(Int fd, HChar* buf, Int len)
+static void my_fwrite(Int fd, const HChar* buf, Int len)
 {
     if (fwrite_fd != fd) {
 	fwrite_flush();
diff --git a/callgrind/main.c b/callgrind/main.c
index d82d382..c15e6c2 100644
--- a/callgrind/main.c
+++ b/callgrind/main.c
@@ -1376,8 +1376,9 @@
     CLG_(zero_cost)( CLG_(sets).full, CLG_(current_state).cost );
 }
 
-/* Ups, this can go very wrong... */
-extern void VG_(discard_translations) ( Addr64 start, ULong range, HChar* who );
+/* Ups, this can go very wrong...
+   FIXME: We should export this function or provide other means to get a handle */
+extern void VG_(discard_translations) ( Addr64 start, ULong range, const HChar* who );
 
 void CLG_(set_instrument_state)(const HChar* reason, Bool state)
 {
diff --git a/configure.in b/configure.in
index 17deedd..31e0815 100644
--- a/configure.in
+++ b/configure.in
@@ -1417,6 +1417,29 @@
 AM_CONDITIONAL(HAS_POINTER_SIGN_WARNING, test x$no_pointer_sign = xyes)
 
 
+# does this compiler support -Wno-write-strings ?
+AC_MSG_CHECKING([if gcc accepts -Wwrite-strings])
+
+safe_CFLAGS=$CFLAGS
+CFLAGS="-Wwrite-strings"
+
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[
+  return 0;
+]])], [
+no_write_strings=yes
+AC_MSG_RESULT([yes])
+], [
+no_write_strings=no
+AC_MSG_RESULT([no])
+])
+CFLAGS=$safe_CFLAGS
+
+if test x$no_write_strings = xyes; then
+  CFLAGS="$CFLAGS -Wwrite-strings"
+fi
+
+AM_CONDITIONAL(HAS_WRITE_STRINGS_WARNING, test x$no_write_strings = xyes)
+
 # does this compiler support -Wno-empty-body ?
 
 AC_MSG_CHECKING([if gcc accepts -Wno-empty-body])
diff --git a/coregrind/m_commandline.c b/coregrind/m_commandline.c
index 64133a3..6d5871a 100644
--- a/coregrind/m_commandline.c
+++ b/coregrind/m_commandline.c
@@ -53,7 +53,7 @@
 // Note that we deliberately don't free the malloc'd memory.  See
 // comment at call site.
 
-static HChar* read_dot_valgrindrc ( HChar* dir )
+static HChar* read_dot_valgrindrc ( const HChar* dir )
 {
    Int    n;
    SysRes fd;
diff --git a/coregrind/m_debuginfo/d3basics.c b/coregrind/m_debuginfo/d3basics.c
index e6f6c7d..88475bc 100644
--- a/coregrind/m_debuginfo/d3basics.c
+++ b/coregrind/m_debuginfo/d3basics.c
@@ -48,7 +48,7 @@
 #include "priv_d3basics.h"      /* self */
 #include "priv_storage.h"
 
-HChar* ML_(pp_DW_children) ( DW_children hashch )
+const HChar* ML_(pp_DW_children) ( DW_children hashch )
 {
    switch (hashch) {
       case DW_children_no:  return "no children";
@@ -57,7 +57,7 @@
    return "DW_children_???";
 }
 
-HChar* ML_(pp_DW_TAG) ( DW_TAG tag )
+const HChar* ML_(pp_DW_TAG) ( DW_TAG tag )
 {
    switch (tag) {
       case DW_TAG_padding:            return "DW_TAG_padding";
@@ -152,7 +152,7 @@
    return "DW_TAG_???";
 }
 
-HChar* ML_(pp_DW_FORM) ( DW_FORM form )
+const HChar* ML_(pp_DW_FORM) ( DW_FORM form )
 {
    switch (form) {
       case DW_FORM_addr:      return "DW_FORM_addr";
@@ -186,7 +186,7 @@
    return "DW_FORM_???";
 }
 
-HChar* ML_(pp_DW_AT) ( DW_AT attr )
+const HChar* ML_(pp_DW_AT) ( DW_AT attr )
 {
    switch (attr) {
       case DW_AT_sibling:             return "DW_AT_sibling";
@@ -1013,7 +1013,7 @@
    Word       i, nGuards;
    MaybeULong *mul, *mul2;
 
-   HChar*  badness = NULL;
+   const HChar*  badness = NULL;
    UChar*  p       = &gx->payload[0]; /* must remain unsigned */
    XArray* results = VG_(newXA)( ML_(dinfo_zalloc), "di.d3basics.etG.1",
                                  ML_(dinfo_free),
diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c
index 16f0cf7..0e7d33e 100644
--- a/coregrind/m_debuginfo/debuginfo.c
+++ b/coregrind/m_debuginfo/debuginfo.c
@@ -298,7 +298,7 @@
 */
 static void discard_DebugInfo ( DebugInfo* di )
 {
-   HChar* reason = "munmap";
+   const HChar* reason = "munmap";
 
    DebugInfo** prev_next_ptr = &debugInfo_list;
    DebugInfo*  curr          =  debugInfo_list;
@@ -1765,7 +1765,7 @@
    Therefore specify "*" to search all the objects.  On TOC-afflicted
    platforms, a symbol is deemed to be found only if it has a nonzero
    TOC pointer.  */
-Bool VG_(lookup_symbol_SLOW)(HChar* sopatt, HChar* name, 
+Bool VG_(lookup_symbol_SLOW)(const HChar* sopatt, HChar* name, 
                              Addr* pEnt, Addr* pToc)
 {
    Bool     require_pToc = False;
@@ -1909,8 +1909,8 @@
    if (VG_(clo_xml)) {
 
       Bool   human_readable = True;
-      HChar* maybe_newline  = human_readable ? "\n      " : "";
-      HChar* maybe_newline2 = human_readable ? "\n    "   : "";
+      const HChar* maybe_newline  = human_readable ? "\n      " : "";
+      const HChar* maybe_newline2 = human_readable ? "\n    "   : "";
 
       /* Print in XML format, dumping in as much info as we know.
          Ensure all tags are balanced even if the individual strings
diff --git a/coregrind/m_debuginfo/priv_d3basics.h b/coregrind/m_debuginfo/priv_d3basics.h
index 457943e..61acc71 100644
--- a/coregrind/m_debuginfo/priv_d3basics.h
+++ b/coregrind/m_debuginfo/priv_d3basics.h
@@ -562,10 +562,10 @@
   }
   DW_OP;
 
-HChar* ML_(pp_DW_children) ( DW_children hashch );
-HChar* ML_(pp_DW_TAG)      ( DW_TAG tag );
-HChar* ML_(pp_DW_FORM)     ( DW_FORM form );
-HChar* ML_(pp_DW_AT)       ( DW_AT attr );
+const HChar* ML_(pp_DW_children) ( DW_children hashch );
+const HChar* ML_(pp_DW_TAG)      ( DW_TAG tag );
+const HChar* ML_(pp_DW_FORM)     ( DW_FORM form );
+const HChar* ML_(pp_DW_AT)       ( DW_AT attr );
 
 
 /* --- To do with evaluation of Dwarf expressions --- */
diff --git a/coregrind/m_debuginfo/priv_storage.h b/coregrind/m_debuginfo/priv_storage.h
index dd90f18..a88c2e4 100644
--- a/coregrind/m_debuginfo/priv_storage.h
+++ b/coregrind/m_debuginfo/priv_storage.h
@@ -843,7 +843,7 @@
 
 /* Add a string to the string table of a DebugInfo.  If len==-1,
    ML_(addStr) will itself measure the length of the string. */
-extern HChar* ML_(addStr) ( struct _DebugInfo* di, HChar* str, Int len );
+extern HChar* ML_(addStr) ( struct _DebugInfo* di, const HChar* str, Int len );
 
 extern void ML_(addVar)( struct _DebugInfo* di,
                          Int    level,
@@ -899,7 +899,7 @@
    terminal.  'serious' errors are always shown, not 'serious' ones
    are shown only at verbosity level 2 and above. */
 extern 
-void ML_(symerr) ( struct _DebugInfo* di, Bool serious, HChar* msg );
+void ML_(symerr) ( struct _DebugInfo* di, Bool serious, const HChar* msg );
 
 /* Print a symbol. */
 extern void ML_(ppSym) ( Int idx, DiSym* sym );
diff --git a/coregrind/m_debuginfo/priv_tytypes.h b/coregrind/m_debuginfo/priv_tytypes.h
index 4ed2dab..5a208b4 100644
--- a/coregrind/m_debuginfo/priv_tytypes.h
+++ b/coregrind/m_debuginfo/priv_tytypes.h
@@ -146,7 +146,7 @@
 void ML_(pp_TyEnt)( TyEnt* );
 
 /* Print a whole XArray of TyEnts, debug-style */
-void ML_(pp_TyEnts)( XArray* tyents, HChar* who );
+void ML_(pp_TyEnts)( XArray* tyents, const HChar* who );
 
 /* Print a TyEnt, C style, chasing stuff as necessary. */
 void ML_(pp_TyEnt_C_ishly)( XArray* /* of TyEnt */ tyents,
@@ -154,11 +154,11 @@
 
 /* Generates a total ordering on TyEnts based only on their .cuOff
    fields. */
-Word ML_(TyEnt__cmp_by_cuOff_only) ( TyEnt* te1, TyEnt* te2 );
+Word ML_(TyEnt__cmp_by_cuOff_only) ( const TyEnt* te1, const TyEnt* te2 );
 
 /* Generates a total ordering on TyEnts based on everything except
    their .cuOff fields. */
-Word ML_(TyEnt__cmp_by_all_except_cuOff) ( TyEnt* te1, TyEnt* te2 );
+Word ML_(TyEnt__cmp_by_all_except_cuOff) ( const TyEnt* te1, const TyEnt* te2 );
 
 /* Free up all directly or indirectly heap-allocated stuff attached to
    this TyEnt, and set its tag to Te_EMPTY.  The .cuOff field is
diff --git a/coregrind/m_debuginfo/readdwarf.c b/coregrind/m_debuginfo/readdwarf.c
index 7cb2380..e547170 100644
--- a/coregrind/m_debuginfo/readdwarf.c
+++ b/coregrind/m_debuginfo/readdwarf.c
@@ -370,7 +370,7 @@
          if (state_machine_regs.is_stmt) {
             if (state_machine_regs.last_address) {
                Bool inRange = False;
-               HChar* filename
+               const HChar* filename
                   = (HChar*)index_WordArray( &inRange, filenames, 
                                              state_machine_regs.last_file);
                if (!inRange || !filename)
@@ -2734,7 +2734,7 @@
    UWord    uw;
    CfiUnop  uop;
    CfiBinop bop;
-   HChar*   opname;
+   const HChar* opname;
 
    Int sp; /* # of top element: valid is -1 .. N_EXPR_STACK-1 */
    Int stack[N_EXPR_STACK];  /* indices into ctx->exprs */
@@ -3737,7 +3737,7 @@
           Bool is_ehframe )
 {
    Int    nbytes;
-   HChar* how = NULL;
+   const HChar* how = NULL;
    Int    n_CIEs = 0;
    UChar* data = frame_image;
    UWord  cfsi_used_orig;
diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c
index 7e924aa..ee79a16 100644
--- a/coregrind/m_debuginfo/readdwarf3.c
+++ b/coregrind/m_debuginfo/readdwarf3.c
@@ -169,8 +169,8 @@
       UChar* region_start_img;
       UWord  region_szB;
       UWord  region_next;
-      void (*barf)( HChar* ) __attribute__((noreturn));
-      HChar* barfstr;
+      void (*barf)( const HChar* ) __attribute__((noreturn));
+      const HChar* barfstr;
    }
    Cursor;
 
@@ -185,8 +185,8 @@
                           UChar*  region_start_img,
                           UWord   region_szB,
                           UWord   region_next,
-                          __attribute__((noreturn)) void (*barf)( HChar* ),
-                          HChar*  barfstr )
+                          __attribute__((noreturn)) void (*barf)( const HChar* ),
+                          const HChar* barfstr )
 {
    vg_assert(c);
    VG_(memset)(c, 0, sizeof(*c));
@@ -343,7 +343,7 @@
 /* Read a DWARF3 'Initial Length' field */
 static ULong get_Initial_Length ( /*OUT*/Bool* is64,
                                   Cursor* c, 
-                                  HChar* barfMsg )
+                                  const HChar* barfMsg )
 {
    ULong w64;
    UInt  w32;
@@ -377,7 +377,7 @@
 typedef
    struct {
       /* Call here if anything goes wrong */
-      void (*barf)( HChar* ) __attribute__((noreturn));
+      void (*barf)( const HChar* ) __attribute__((noreturn));
       /* Is this 64-bit DWARF ? */
       Bool   is_dw64;
       /* Which DWARF version ?  (2, 3 or 4) */
@@ -1045,7 +1045,7 @@
    BARF.  */
 static UWord lookup_signatured_type ( VgHashTable tab,
                                       ULong type_signature,
-                                      void (*barf)( HChar* ) __attribute__((noreturn)) )
+                                      void (*barf)( const HChar* ) __attribute__((noreturn)) )
 {
    D3SignatureType *dstype = VG_(HT_lookup) ( tab, (UWord) type_signature );
    /* This may be unwarranted chumminess with the hash table
@@ -1439,7 +1439,7 @@
    }
    D3VarParser;
 
-static void varstack_show ( D3VarParser* parser, HChar* str ) {
+static void varstack_show ( D3VarParser* parser, const HChar* str ) {
    Word i, j;
    VG_(printf)("  varstack (%s) {\n", str);
    for (i = 0; i <= parser->sp; i++) {
@@ -2164,7 +2164,7 @@
    }
    D3TypeParser;
 
-static void typestack_show ( D3TypeParser* parser, HChar* str ) {
+static void typestack_show ( D3TypeParser* parser, const HChar* str ) {
    Word i;
    VG_(printf)("  typestack (%s) {\n", str);
    for (i = 0; i <= parser->sp; i++) {
@@ -3292,10 +3292,7 @@
 
    /* First we must sort .ents by its .cuOff fields, so we
       can index into it. */
-   VG_(setCmpFnXA)(
-      ents,
-      (Int(*)(void*,void*)) ML_(TyEnt__cmp_by_cuOff_only)
-   );
+   VG_(setCmpFnXA)( ents, (XACmpFn_t) ML_(TyEnt__cmp_by_cuOff_only) );
    VG_(sortXA)( ents );
 
    /* Now repeatedly do commoning and substitution passes over
@@ -3344,7 +3341,7 @@
 
 __attribute__((noinline))
 static void resolve_variable_types (
-               void (*barf)( HChar* ) __attribute__((noreturn)),
+               void (*barf)( const HChar* ) __attribute__((noreturn)),
                /*R-O*/XArray* /* of TyEnt */ ents,
                /*MOD*/TyEntIndexCache* ents_cache,
                /*MOD*/XArray* /* of TempVar* */ vars
@@ -3396,9 +3393,9 @@
 /*---                                                      ---*/
 /*------------------------------------------------------------*/
 
-static Int cmp_TempVar_by_dioff ( void* v1, void* v2 ) {
-   TempVar* t1 = *(TempVar**)v1;
-   TempVar* t2 = *(TempVar**)v2;
+static Int cmp_TempVar_by_dioff ( const void* v1, const void* v2 ) {
+   const TempVar* t1 = *(const TempVar**)v1;
+   const TempVar* t2 = *(const TempVar**)v2;
    if (t1->dioff < t2->dioff) return -1;
    if (t1->dioff > t2->dioff) return 1;
    return 0;
@@ -3518,7 +3515,7 @@
 static
 void new_dwarf3_reader_wrk ( 
    struct _DebugInfo* di,
-   __attribute__((noreturn)) void (*barf)( HChar* ),
+   __attribute__((noreturn)) void (*barf)( const HChar* ),
    UChar* debug_info_img,   SizeT debug_info_sz,
    UChar* debug_types_img,  SizeT debug_types_sz,
    UChar* debug_abbv_img,   SizeT debug_abbv_sz,
@@ -4048,10 +4045,7 @@
       minor) waste of time, since tyents itself is sorted, but
       necessary since VG_(lookupXA) refuses to cooperate if we
       don't. */
-   VG_(setCmpFnXA)(
-      tyents_to_keep,
-      (Int(*)(void*,void*)) ML_(TyEnt__cmp_by_cuOff_only)
-   );
+   VG_(setCmpFnXA)( tyents_to_keep, (XACmpFn_t) ML_(TyEnt__cmp_by_cuOff_only) );
    VG_(sortXA)( tyents_to_keep );
 
    /* Enable cacheing on tyents_to_keep */
@@ -4337,10 +4331,10 @@
 /*------------------------------------------------------------*/
 
 static Bool               d3rd_jmpbuf_valid  = False;
-static HChar*             d3rd_jmpbuf_reason = NULL;
+static const HChar*       d3rd_jmpbuf_reason = NULL;
 static VG_MINIMAL_JMP_BUF(d3rd_jmpbuf);
 
-static __attribute__((noreturn)) void barf ( HChar* reason ) {
+static __attribute__((noreturn)) void barf ( const HChar* reason ) {
    vg_assert(d3rd_jmpbuf_valid);
    d3rd_jmpbuf_reason = reason;
    VG_MINIMAL_LONGJMP(d3rd_jmpbuf);
diff --git a/coregrind/m_debuginfo/readelf.c b/coregrind/m_debuginfo/readelf.c
index 6e022a5..1d04680 100644
--- a/coregrind/m_debuginfo/readelf.c
+++ b/coregrind/m_debuginfo/readelf.c
@@ -149,7 +149,7 @@
                            ElfXX_Sym* sym, const HChar* sym_name, Addr sym_svma,
                            Bool ppc64_linux_format )
 {
-   HChar* space = ppc64_linux_format ? "                  " : "";
+   const HChar* space = ppc64_linux_format ? "                  " : "";
    VG_(printf)("raw symbol [%4d]: ", i);
    switch (ELFXX_ST_BIND(sym->st_info)) {
       case STB_LOCAL:  VG_(printf)("LOC "); break;
diff --git a/coregrind/m_debuginfo/readpdb.c b/coregrind/m_debuginfo/readpdb.c
index ada70e4..cf54285 100644
--- a/coregrind/m_debuginfo/readpdb.c
+++ b/coregrind/m_debuginfo/readpdb.c
@@ -1800,13 +1800,14 @@
 /*---                                                      ---*/
 /*------------------------------------------------------------*/
 
-static Int cmp_FPO_DATA_for_canonicalisation ( void* f1V, void* f2V )
+static Int cmp_FPO_DATA_for_canonicalisation ( const void* f1V,
+                                               const void* f2V )
 {
    /* Cause FPO data to be sorted first in ascending order of range
       starts, and for entries with the same range start, with the
       shorter range (length) first. */
-   FPO_DATA* f1 = (FPO_DATA*)f1V;
-   FPO_DATA* f2 = (FPO_DATA*)f2V;
+   const FPO_DATA* f1 = f1V;
+   const FPO_DATA* f2 = f2V;
    if (f1->ulOffStart < f2->ulOffStart) return -1;
    if (f1->ulOffStart > f2->ulOffStart) return  1;
    if (f1->cbProcSize < f2->cbProcSize) return -1;
@@ -2428,9 +2429,9 @@
    /* Make up the command to run, essentially:
       sh -c "strings (pename) | egrep '\.pdb|\.PDB' > (tmpname)"
    */
-   HChar* sh      = "/bin/sh";
-   HChar* strings = "/usr/bin/strings";
-   HChar* egrep   = "/usr/bin/egrep";
+   const HChar* sh      = "/bin/sh";
+   const HChar* strings = "/usr/bin/strings";
+   const HChar* egrep   = "/usr/bin/egrep";
 
    /* (sh) -c "(strings) (pename) | (egrep) 'pdb' > (tmpname) */
    Int cmdlen = VG_(strlen)(strings) + VG_(strlen)(pename)
diff --git a/coregrind/m_debuginfo/storage.c b/coregrind/m_debuginfo/storage.c
index 840753e..f344c8f 100644
--- a/coregrind/m_debuginfo/storage.c
+++ b/coregrind/m_debuginfo/storage.c
@@ -59,7 +59,7 @@
 /* Show a non-fatal debug info reading error.  Use vg_panic if
    terminal.  'serious' errors are shown regardless of the
    verbosity setting. */
-void ML_(symerr) ( struct _DebugInfo* di, Bool serious, HChar* msg )
+void ML_(symerr) ( struct _DebugInfo* di, Bool serious, const HChar* msg )
 {
    /* XML mode hides everything :-( */
    if (VG_(clo_xml))
@@ -215,7 +215,7 @@
    a chunking memory allocator rather than reallocating, so the
    pointers are stable.
 */
-HChar* ML_(addStr) ( struct _DebugInfo* di, HChar* str, Int len )
+HChar* ML_(addStr) ( struct _DebugInfo* di, const HChar* str, Int len )
 {
    struct strchunk *chunk;
    Int    space_needed;
@@ -725,7 +725,7 @@
 }
 
 static
-void show_scope ( OSet* /* of DiAddrRange */ scope, HChar* who )
+void show_scope ( OSet* /* of DiAddrRange */ scope, const HChar* who )
 {
    DiAddrRange* range;
    VG_(printf)("Scope \"%s\" = {\n", who);
@@ -910,7 +910,7 @@
    Bool       all;
    TyEnt*     ent;
    MaybeULong mul;
-   HChar*     badness;
+   const HChar* badness;
 
    tl_assert(di && di->admin_tyents);
 
@@ -1131,10 +1131,10 @@
    facilitates using binary search to map addresses to symbols when we
    come to query the table.
 */
-static Int compare_DiSym ( void* va, void* vb ) 
+static Int compare_DiSym ( const void* va, const void* vb ) 
 {
-   DiSym* a = (DiSym*)va;
-   DiSym* b = (DiSym*)vb;
+   const DiSym* a = va;
+   const DiSym* b = vb;
    if (a->addr < b->addr) return -1;
    if (a->addr > b->addr) return  1;
    return 0;
@@ -1608,10 +1608,10 @@
    ranges do not overlap.  This facilitates using binary search to map
    addresses to locations when we come to query the table.
 */
-static Int compare_DiLoc ( void* va, void* vb ) 
+static Int compare_DiLoc ( const void* va, const void* vb ) 
 {
-   DiLoc* a = (DiLoc*)va;
-   DiLoc* b = (DiLoc*)vb;
+   const DiLoc* a = va;
+   const DiLoc* b = vb;
    if (a->addr < b->addr) return -1;
    if (a->addr > b->addr) return  1;
    return 0;
@@ -1694,10 +1694,10 @@
    as to facilitate rapidly skipping this SegInfo when looking for an
    address which falls outside that range.
 */
-static Int compare_DiCfSI ( void* va, void* vb )
+static Int compare_DiCfSI ( const void* va, const void* vb )
 {
-   DiCfSI* a = (DiCfSI*)va;
-   DiCfSI* b = (DiCfSI*)vb;
+   const DiCfSI* a = va;
+   const DiCfSI* b = vb;
    if (a->base < b->base) return -1;
    if (a->base > b->base) return  1;
    return 0;
diff --git a/coregrind/m_debuginfo/tytypes.c b/coregrind/m_debuginfo/tytypes.c
index 95b391c..9fcda78 100644
--- a/coregrind/m_debuginfo/tytypes.c
+++ b/coregrind/m_debuginfo/tytypes.c
@@ -198,7 +198,7 @@
 
 /* Print a whole XArray of TyEnts, debug-style */
 
-void ML_(pp_TyEnts)( XArray* tyents, HChar* who )
+void ML_(pp_TyEnts)( XArray* tyents, const HChar* who )
 {
    Word i, n;
    VG_(printf)("------ %s ------\n", who);
@@ -410,7 +410,7 @@
 /* Generates a total ordering on TyEnts based only on their .cuOff
    fields. */
 
-Word ML_(TyEnt__cmp_by_cuOff_only) ( TyEnt* te1, TyEnt* te2 )
+Word ML_(TyEnt__cmp_by_cuOff_only) ( const TyEnt* te1, const TyEnt* te2 )
 {
    if (te1->cuOff < te2->cuOff) return -1;
    if (te1->cuOff > te2->cuOff) return 1;
@@ -477,7 +477,7 @@
    return VG_(strcmp)(a, b);
 }
 
-Word ML_(TyEnt__cmp_by_all_except_cuOff) ( TyEnt* te1, TyEnt* te2 )
+Word ML_(TyEnt__cmp_by_all_except_cuOff) ( const TyEnt* te1, const TyEnt* te2 )
 {
    Word r;
    if (te1->tag < te2->tag) return -1;
diff --git a/coregrind/m_debuglog.c b/coregrind/m_debuglog.c
index 37eb7a5..3c6025e 100644
--- a/coregrind/m_debuglog.c
+++ b/coregrind/m_debuglog.c
@@ -762,14 +762,14 @@
                i++;
                /* %pS, like %s but escaping chars for XML safety */
                /* Note: simplistic; ignores field width and flags */
-               HChar *str = va_arg (vargs, HChar *);
+               const HChar *str = va_arg (vargs, HChar *);
                if (str == NULL)
                   str = "(null)";
                ret += myvprintf_str_XML_simplistic(send, send_arg2, str);
             } else if (format[i+1] == 's') {
                i++;
                /* %ps, synonym for %s with --xml=no / %pS with --xml=yes */
-               HChar *str = va_arg (vargs, HChar *);
+               const HChar *str = va_arg (vargs, HChar *);
                if (str == NULL)
                   str = "(null)";
                if (clo_xml)
@@ -806,7 +806,7 @@
             send(va_arg (vargs, int), send_arg2);
             break;
          case 's': case 'S': { /* %s */
-            HChar *str = va_arg (vargs, HChar *);
+            const HChar *str = va_arg (vargs, HChar *);
             if (str == NULL) str = "(null)";
             ret += myvprintf_str(send, send_arg2, 
                                  flags, width, str, format[i]=='S');
diff --git a/coregrind/m_gdbserver/m_gdbserver.c b/coregrind/m_gdbserver/m_gdbserver.c
index c7b77f3..57aeefe 100644
--- a/coregrind/m_gdbserver/m_gdbserver.c
+++ b/coregrind/m_gdbserver/m_gdbserver.c
@@ -1269,7 +1269,8 @@
    return b.ret;
 }
 
-Int VG_(keyword_id) (HChar* keywords, HChar* input_word, kwd_report_error report)
+Int VG_(keyword_id) (const HChar* keywords, const HChar* input_word,
+                     kwd_report_error report)
 {
    const Int il = (input_word == NULL ? 0 : VG_(strlen) (input_word));
    HChar  iw[il+1];
diff --git a/coregrind/m_gdbserver/regdef.h b/coregrind/m_gdbserver/regdef.h
index e974459..146079c 100644
--- a/coregrind/m_gdbserver/regdef.h
+++ b/coregrind/m_gdbserver/regdef.h
@@ -25,7 +25,7 @@
 struct reg
 {
   /* The name of this register - NULL for pad entries.  */
-  char *name;
+  const char *name;
 
   /* At the moment, both of the following bit counts must be divisible
      by eight (to match the representation as two hex digits) and divisible
diff --git a/coregrind/m_gdbserver/remote-utils.c b/coregrind/m_gdbserver/remote-utils.c
index 2e6efa6..a08aef7 100644
--- a/coregrind/m_gdbserver/remote-utils.c
+++ b/coregrind/m_gdbserver/remote-utils.c
@@ -59,7 +59,7 @@
 static char *shared_mem = NULL;
 
 static
-int open_fifo (char *side, char *path, int flags)
+int open_fifo (const char *side, const char *path, int flags)
 {
   SysRes o;
   int fd;
@@ -91,7 +91,7 @@
 /* Returns 0 if vgdb and connection state looks good,
    otherwise returns an int value telling which check failed. */
 static
-int vgdb_state_looks_bad(char* where)
+int vgdb_state_looks_bad(const char* where)
 {
    if (VG_(kill)(shared->vgdb_pid, 0) != 0)
       return 1; // vgdb process does not exist anymore.
@@ -114,7 +114,7 @@
 {
 #ifdef PR_SET_PTRACER
    SysRes o;
-   char *ptrace_scope_setting_file = "/proc/sys/kernel/yama/ptrace_scope";
+   const char *ptrace_scope_setting_file = "/proc/sys/kernel/yama/ptrace_scope";
    int fd;
    char ptrace_scope;
    int ret;
@@ -362,7 +362,7 @@
 }
 
 static
-char * ppFinishReason (FinishReason reason)
+const char * ppFinishReason (FinishReason reason)
 {
    switch (reason) {
    case orderly_finish:    return "orderly_finish";
@@ -438,7 +438,7 @@
    gives a small value to --vgdb-poll. So, the function avoids
    doing repetitively system calls by rather looking at the
    counter values maintained in shared memory by vgdb. */
-int remote_desc_activity(char *msg)
+int remote_desc_activity(const char *msg)
 {
    int ret;
    const int looking_at = shared->written_by_vgdb;
diff --git a/coregrind/m_gdbserver/server.c b/coregrind/m_gdbserver/server.c
index 1d6ff8a..1e9ee30 100644
--- a/coregrind/m_gdbserver/server.c
+++ b/coregrind/m_gdbserver/server.c
@@ -53,7 +53,7 @@
    or -1 otherwise.  */
 
 static
-int decode_xfer_read (char *buf, char **annex, CORE_ADDR *ofs, unsigned int *len)
+int decode_xfer_read (char *buf, const char **annex, CORE_ADDR *ofs, unsigned int *len)
 {
    /* Extract and NUL-terminate the annex.  */
    *annex = buf;
@@ -95,7 +95,7 @@
 static Bool command_output_to_log = False;
 /* True <=> command output goes to log instead of gdb */
 
-void reset_valgrind_sink(char *info)
+void reset_valgrind_sink(const char *info)
 {
    if (VG_(log_output_sink).fd != initial_valgrind_sink.fd
        && initial_valgrind_sink_saved) {
@@ -106,7 +106,7 @@
 }
 
 static
-void kill_request (char *msg)
+void kill_request (const char *msg)
 {
    VG_(umsg) ("%s", msg);
    remote_close();
@@ -127,7 +127,7 @@
    char s[strlen(mon)+1]; /* copy for strtok_r */
    char* wcmd;
    HChar* ssaveptr;
-   char* endptr;
+   const char* endptr;
    int   kwdid;
    int int_value;
 
@@ -200,7 +200,9 @@
             int_value = 0;
             endptr = "empty"; /* to report an error below */
          } else {
-            int_value = strtol (wcmd, &endptr, 10);
+            HChar *the_end;
+            int_value = strtol (wcmd, &the_end, 10);
+            endptr = the_end;
          }
          if (*endptr != '\0') {
             VG_(gdb_printf) ("missing or malformed integer value\n");
@@ -301,7 +303,7 @@
    case  3: /* v.wait */
       wcmd = strtok_r (NULL, " ", &ssaveptr);
       if (wcmd != NULL) {
-         int_value = strtol (wcmd, &endptr, 10);
+         int_value = strtol (wcmd, NULL, 10);
          VG_(gdb_printf) ("gdbserver: continuing in %d ms ...\n", int_value);
          VG_(poll)(NULL, 0, int_value);
       }
@@ -547,7 +549,7 @@
         && strncmp ("qXfer:features:read:", arg_own_buf, 20) == 0) {
       CORE_ADDR ofs;
       unsigned int len, doc_len;
-      char *annex = NULL;
+      const char *annex = NULL;
       // First, the annex is extracted from the packet received.
       // Then, it is replaced by the corresponding file name.
       int fd;
@@ -611,7 +613,7 @@
       int n;
       CORE_ADDR ofs;
       unsigned int len;
-      char *annex;
+      const char *annex;
 
       /* Reject any annex; grab the offset and length.  */
       if (decode_xfer_read (arg_own_buf + 16, &annex, &ofs, &len) < 0
diff --git a/coregrind/m_gdbserver/server.h b/coregrind/m_gdbserver/server.h
index 6686c19..d0d8a9f 100644
--- a/coregrind/m_gdbserver/server.h
+++ b/coregrind/m_gdbserver/server.h
@@ -76,7 +76,7 @@
    returns 2 if remote_desc_activity detected the connection has been
              lost and should be reopened.
    msg is used for debug logging.*/
-extern int remote_desc_activity(char *msg);
+extern int remote_desc_activity(const char *msg);
 
 /* output some status of gdbserver communication */
 extern void remote_utils_output_status(void);
@@ -92,7 +92,7 @@
 /* If Valgrind sink was changed by gdbserver:
       Resets the valgrind sink to before the changes done by gdbserver,
       and does VG_(umsg). If info != NULL, info added in VG_(usmg). */
-extern void reset_valgrind_sink(char* info);
+extern void reset_valgrind_sink(const char* info);
 
 /* For ARM usage.
    Guesses if pc is a thumb pc.
@@ -312,14 +312,14 @@
 enum target_signal target_signal_from_host (int hostsig);
 int target_signal_to_host_p (enum target_signal oursig);
 int target_signal_to_host (enum target_signal oursig);
-char *target_signal_to_name (enum target_signal);
+const char *target_signal_to_name (enum target_signal);
 
 /* Functions from utils.c */
 
 /* error is like VG_(umsg), then VG_MINIMAL_LONGJMP to gdbserver toplevel. */
 void error (const char *string,...) ATTR_NORETURN ATTR_FORMAT (printf, 1, 2);
 /* first output a description of the error inside sr, then like VG_(umsg). */
-void sr_perror (SysRes sr,char *string,...) ATTR_FORMAT (printf, 2, 3);
+void sr_perror (SysRes sr,const char *string,...) ATTR_FORMAT (printf, 2, 3);
 /* fatal is like VG_(umsg), then exit(1). */
 void fatal (const char *string,...) ATTR_NORETURN ATTR_FORMAT (printf, 1, 2);
 /* warning is like VG_(umsg). */
diff --git a/coregrind/m_gdbserver/signals.c b/coregrind/m_gdbserver/signals.c
index ee60ccd..69aa9b1 100644
--- a/coregrind/m_gdbserver/signals.c
+++ b/coregrind/m_gdbserver/signals.c
@@ -30,15 +30,15 @@
 #endif
 #endif
 
-enum target_signal target_signal_from_name (char *name);
+enum target_signal target_signal_from_name (const char *name);
 enum target_signal target_signal_from_command (int num);
 
 /* This table must match in order and size the signals in enum target_signal
    in gdb/signals.h. */
 /* *INDENT-OFF* */
 static struct {
-   char *name;
-   char *string;
+   const char *name;
+   const char *string;
 } signals [] =
    {
       {"0", "Signal 0"},
@@ -205,7 +205,7 @@
 
 
 /* Return the name for a signal.  */
-char *target_signal_to_name (enum target_signal sig)
+const char *target_signal_to_name (enum target_signal sig)
 {
    if ((sig >= TARGET_SIGNAL_FIRST) && (sig <= TARGET_SIGNAL_LAST)
        && signals[sig].name != NULL)
@@ -217,7 +217,7 @@
 }
 
 /* Given a name, return its signal.  */
-enum target_signal target_signal_from_name (char *name)
+enum target_signal target_signal_from_name (const char *name)
 {
    enum target_signal sig;
 
diff --git a/coregrind/m_gdbserver/target.c b/coregrind/m_gdbserver/target.c
index 62e1b85..7c95ecd 100644
--- a/coregrind/m_gdbserver/target.c
+++ b/coregrind/m_gdbserver/target.c
@@ -102,16 +102,17 @@
 static
 struct reg* build_shadow_arch (struct reg *reg_defs, int n) {
    int i, r;
-   static char *postfix[3] = { "", "s1", "s2" };
+   static const char *postfix[3] = { "", "s1", "s2" };
    struct reg *new_regs = malloc(3 * n * sizeof(reg_defs[0]));
    int reg_set_len = reg_defs[n-1].offset + reg_defs[n-1].size;
 
    for (i = 0; i < 3; i++) {
       for (r = 0; r < n; r++) {
-         new_regs[i*n + r].name = malloc(strlen(reg_defs[r].name) 
-                                         + strlen (postfix[i]) + 1);
-         strcpy (new_regs[i*n + r].name, reg_defs[r].name);
-         strcat (new_regs[i*n + r].name, postfix[i]);
+         char *regname = malloc(strlen(reg_defs[r].name) 
+                                + strlen (postfix[i]) + 1);
+         strcpy (regname, reg_defs[r].name);
+         strcat (regname, postfix[i]);
+         new_regs[i*n + r].name = regname;
          new_regs[i*n + r].offset = i*reg_set_len + reg_defs[r].offset;
          new_regs[i*n + r].size = reg_defs[r].size;
          dlog(1,
@@ -519,7 +520,7 @@
       return 1; /* error or unsupported */
 }
 
-char* valgrind_target_xml (Bool shadow_mode)
+const char* valgrind_target_xml (Bool shadow_mode)
 {
    return (*the_low_target.target_xml) (shadow_mode);
 }
diff --git a/coregrind/m_gdbserver/target.h b/coregrind/m_gdbserver/target.h
index 2cd41fd..2d4949c 100644
--- a/coregrind/m_gdbserver/target.h
+++ b/coregrind/m_gdbserver/target.h
@@ -63,7 +63,7 @@
    with the shadow registers
    else returns the xml target description only for
    the normal registers. */
-extern char* valgrind_target_xml (Bool shadow_mode);
+extern const char* valgrind_target_xml (Bool shadow_mode);
 
 
 /* -------------------------------------------------------------------------- */
diff --git a/coregrind/m_gdbserver/utils.c b/coregrind/m_gdbserver/utils.c
index 57db175..511b1e6 100644
--- a/coregrind/m_gdbserver/utils.c
+++ b/coregrind/m_gdbserver/utils.c
@@ -26,7 +26,7 @@
 
 /* Print the system error message for sr.
    Then print the rest of the args. */
-void sr_perror (SysRes sr,char *string,...)
+void sr_perror (SysRes sr, const char *string,...)
 {
    va_list args;
    if (sr_isError (sr))
diff --git a/coregrind/m_gdbserver/valgrind-low-amd64.c b/coregrind/m_gdbserver/valgrind-low-amd64.c
index 7de55a0..b816451 100644
--- a/coregrind/m_gdbserver/valgrind-low-amd64.c
+++ b/coregrind/m_gdbserver/valgrind-low-amd64.c
@@ -316,7 +316,7 @@
    return (vai.hwcaps & VEX_HWCAPS_AMD64_AVX ? True : False);
 }
 static
-char* target_xml (Bool shadow_mode)
+const char* target_xml (Bool shadow_mode)
 {
    if (shadow_mode) {
 #if defined(VGO_linux)
diff --git a/coregrind/m_gdbserver/valgrind-low-arm.c b/coregrind/m_gdbserver/valgrind-low-arm.c
index e7ac5f0..b14084a 100644
--- a/coregrind/m_gdbserver/valgrind-low-arm.c
+++ b/coregrind/m_gdbserver/valgrind-low-arm.c
@@ -278,7 +278,7 @@
 }
 
 static
-char* target_xml (Bool shadow_mode)
+const char* target_xml (Bool shadow_mode)
 {
    if (shadow_mode) {
       return "arm-with-vfpv3-valgrind.xml";
diff --git a/coregrind/m_gdbserver/valgrind-low-mips32.c b/coregrind/m_gdbserver/valgrind-low-mips32.c
index cf2d603..b6b6491 100644
--- a/coregrind/m_gdbserver/valgrind-low-mips32.c
+++ b/coregrind/m_gdbserver/valgrind-low-mips32.c
@@ -230,7 +230,7 @@
 }
 
 static
-char* target_xml (Bool shadow_mode)
+const char* target_xml (Bool shadow_mode)
 {
    if (shadow_mode) {
       return "mips-linux-valgrind.xml";
diff --git a/coregrind/m_gdbserver/valgrind-low-ppc32.c b/coregrind/m_gdbserver/valgrind-low-ppc32.c
index 9f2f36e..ba4ae8f 100644
--- a/coregrind/m_gdbserver/valgrind-low-ppc32.c
+++ b/coregrind/m_gdbserver/valgrind-low-ppc32.c
@@ -323,7 +323,7 @@
 }
 
 static
-char* target_xml (Bool shadow_mode)
+const char* target_xml (Bool shadow_mode)
 {
    if (shadow_mode) {
       return "powerpc-altivec32l-valgrind.xml";
diff --git a/coregrind/m_gdbserver/valgrind-low-ppc64.c b/coregrind/m_gdbserver/valgrind-low-ppc64.c
index 9b1a358..a516d20 100644
--- a/coregrind/m_gdbserver/valgrind-low-ppc64.c
+++ b/coregrind/m_gdbserver/valgrind-low-ppc64.c
@@ -320,7 +320,7 @@
 }
 
 static
-char* target_xml (Bool shadow_mode)
+const char* target_xml (Bool shadow_mode)
 {
    if (shadow_mode) {
       return "powerpc-altivec64l-valgrind.xml";
diff --git a/coregrind/m_gdbserver/valgrind-low-s390x.c b/coregrind/m_gdbserver/valgrind-low-s390x.c
index 017a402..6909e4c 100644
--- a/coregrind/m_gdbserver/valgrind-low-s390x.c
+++ b/coregrind/m_gdbserver/valgrind-low-s390x.c
@@ -188,7 +188,7 @@
 }
 
 static
-char* target_xml (Bool shadow_mode)
+const char* target_xml (Bool shadow_mode)
 {
    if (shadow_mode) {
       return "s390x-generic-valgrind.xml";
diff --git a/coregrind/m_gdbserver/valgrind-low-x86.c b/coregrind/m_gdbserver/valgrind-low-x86.c
index 50d3193..fc533f7 100644
--- a/coregrind/m_gdbserver/valgrind-low-x86.c
+++ b/coregrind/m_gdbserver/valgrind-low-x86.c
@@ -244,7 +244,7 @@
 }
 
 static
-char* target_xml (Bool shadow_mode)
+const char* target_xml (Bool shadow_mode)
 {
    if (shadow_mode) {
 #if defined(VGO_linux)
diff --git a/coregrind/m_gdbserver/valgrind_low.h b/coregrind/m_gdbserver/valgrind_low.h
index 4a8e1dc..3ff6d19 100644
--- a/coregrind/m_gdbserver/valgrind_low.h
+++ b/coregrind/m_gdbserver/valgrind_low.h
@@ -63,7 +63,7 @@
       including the two shadow registers sets.
       This is mandatory to use the option --vgdb-shadow-registers=yes. 
       Returns NULL if there is no target xml file*/
-   char* (*target_xml) (Bool shadow_mode);
+   const char* (*target_xml) (Bool shadow_mode);
 
 };
 
diff --git a/coregrind/m_libcbase.c b/coregrind/m_libcbase.c
index fc6df6c..3567882 100644
--- a/coregrind/m_libcbase.c
+++ b/coregrind/m_libcbase.c
@@ -672,7 +672,7 @@
       pv = (Char*)&v, v = *(Word*)pm
 
 static Char* bm_med3 ( Char* a, Char* b, Char* c, 
-                       Int (*cmp)(void*,void*) ) {
+                       Int (*cmp)(const void*, const void*) ) {
    return cmp(a, b) < 0
           ? (cmp(b, c) < 0 ? b : cmp(a, c) < 0 ? c : a)
           : (cmp(b, c) > 0 ? b : cmp(a, c) > 0 ? c : a);
@@ -693,7 +693,7 @@
 }
 
 static void bm_qsort ( Char* a, SizeT n, SizeT es,
-                       Int (*cmp)(void*,void*) )
+                       Int (*cmp)(const void*, const void*) )
 {
    Char  *pa, *pb, *pc, *pd, *pl, *pm, *pn, *pv;
    Int   r, swaptype;
@@ -802,7 +802,7 @@
 
 // Generic quick sort.
 void VG_(ssort)( void* base, SizeT nmemb, SizeT size,
-                 Int (*compar)(void*, void*) )
+                 Int (*compar)(const void*, const void*) )
 {
    bm_qsort(base,nmemb,size,compar);
 }
diff --git a/coregrind/m_libcfile.c b/coregrind/m_libcfile.c
index a4f6d1b..2e8ebca 100644
--- a/coregrind/m_libcfile.c
+++ b/coregrind/m_libcfile.c
@@ -1054,7 +1054,7 @@
 }
 
 
-HChar *VG_(basename)(const HChar *path)
+const HChar *VG_(basename)(const HChar *path)
 {
    static HChar buf[VKI_PATH_MAX];
    
@@ -1090,7 +1090,7 @@
 }
 
 
-HChar *VG_(dirname)(const HChar *path)
+const HChar *VG_(dirname)(const HChar *path)
 {
    static HChar buf[VKI_PATH_MAX];
     
diff --git a/coregrind/m_machine.c b/coregrind/m_machine.c
index e1396e2..85f20ef 100644
--- a/coregrind/m_machine.c
+++ b/coregrind/m_machine.c
@@ -198,7 +198,8 @@
 }
 
 
-static void apply_to_GPs_of_tid(ThreadId tid, void (*f)(ThreadId, HChar*, Addr))
+static void apply_to_GPs_of_tid(ThreadId tid, void (*f)(ThreadId,
+                                                        const HChar*, Addr))
 {
    VexGuestArchState* vex = &(VG_(get_ThreadState)(tid)->arch.vex);
 #if defined(VGA_x86)
@@ -333,7 +334,7 @@
 }
 
 
-void VG_(apply_to_GP_regs)(void (*f)(ThreadId, HChar*, UWord))
+void VG_(apply_to_GP_regs)(void (*f)(ThreadId, const HChar*, UWord))
 {
    ThreadId tid;
 
diff --git a/coregrind/m_main.c b/coregrind/m_main.c
index 31e0457..dae9501 100644
--- a/coregrind/m_main.c
+++ b/coregrind/m_main.c
@@ -1161,8 +1161,8 @@
                              const HChar* toolname )
 {
    Int    i;
-   HChar* xpre  = VG_(clo_xml) ? "  <line>" : "";
-   HChar* xpost = VG_(clo_xml) ? "</line>" : "";
+   const HChar* xpre  = VG_(clo_xml) ? "  <line>" : "";
+   const HChar* xpost = VG_(clo_xml) ? "</line>" : "";
    UInt (*umsg_or_xml)( const HChar*, ... )
       = VG_(clo_xml) ? VG_(printf_xml) : VG_(umsg);
 
diff --git a/coregrind/m_mallocfree.c b/coregrind/m_mallocfree.c
index 2ed53b6..7f19e8c 100644
--- a/coregrind/m_mallocfree.c
+++ b/coregrind/m_mallocfree.c
@@ -243,7 +243,7 @@
 
 #define SIZE_T_0x1      ((SizeT)0x1)
 
-static char* probably_your_fault =
+static const char* probably_your_fault =
    "This is probably caused by your program erroneously writing past the\n"
    "end of a heap block and corrupting heap metadata.  If you fix any\n"
    "invalid writes reported by Memcheck, this assertion failure will\n"
@@ -1280,7 +1280,7 @@
 
 static AnCC anCCs[N_AN_CCS];
 
-static Int cmp_AnCC_by_vol ( void* v1, void* v2 ) {
+static Int cmp_AnCC_by_vol ( const void* v1, const void* v2 ) {
    AnCC* ancc1 = (AnCC*)v1;
    AnCC* ancc2 = (AnCC*)v2;
    if (ancc1->nBytes < ancc2->nBytes) return -1;
diff --git a/coregrind/m_redir.c b/coregrind/m_redir.c
index dde527c..81f969e 100644
--- a/coregrind/m_redir.c
+++ b/coregrind/m_redir.c
@@ -801,7 +801,7 @@
    }
    if (sp) {
       const HChar** strp;
-      HChar* v = "valgrind:  ";
+      const HChar* v = "valgrind:  ";
       vg_assert(sp->mark);
       vg_assert(!sp->done);
       vg_assert(sp->mandatory);
@@ -846,7 +846,7 @@
    conflicting bindings. */
 static void maybe_add_active ( Active act )
 {
-   HChar*  what    = NULL;
+   const HChar*  what = NULL;
    Active* old     = NULL;
    Bool    add_act = False;
 
@@ -1129,9 +1129,9 @@
    entry that holds these initial specs. */
 
 __attribute__((unused)) /* not used on all platforms */
-static void add_hardwired_spec ( HChar* sopatt, HChar* fnpatt, 
-                                 Addr   to_addr,
-                                 const HChar** mandatory )
+static void add_hardwired_spec (const  HChar* sopatt, const HChar* fnpatt, 
+                                Addr   to_addr,
+                                const HChar** mandatory )
 {
    Spec* spec = dinfo_zalloc("redir.ahs.1", sizeof(Spec));
    vg_assert(spec);
@@ -1146,8 +1146,8 @@
    vg_assert(topSpecs->next == NULL);
    vg_assert(topSpecs->seginfo == NULL);
    /* FIXED PARTS */
-   spec->from_sopatt = sopatt;
-   spec->from_fnpatt = fnpatt;
+   spec->from_sopatt = (HChar *)sopatt;
+   spec->from_fnpatt = (HChar *)fnpatt;
    spec->to_addr     = to_addr;
    spec->isWrap      = False;
    spec->mandatory   = mandatory;
@@ -1544,7 +1544,7 @@
       }
 
       if (!found) {
-         HChar* v = "valgrind:  ";
+         const HChar* v = "valgrind:  ";
          VG_(printf)("\n");
          VG_(printf)(
          "%sFatal error at when loading library with soname\n", v);
diff --git a/coregrind/m_syswrap/syswrap-xen.c b/coregrind/m_syswrap/syswrap-xen.c
index 4fa9a96..3ec7352 100644
--- a/coregrind/m_syswrap/syswrap-xen.c
+++ b/coregrind/m_syswrap/syswrap-xen.c
@@ -71,7 +71,7 @@
                         /*MOD*/SyscallArgs*   args,
                         /*OUT*/SyscallStatus* status,
                         /*OUT*/UWord*         flags,
-                        const char*           hypercall,
+                        const HChar*           hypercall,
                         UWord                 subop)
 {
    VG_(dmsg)("WARNING: unhandled %s subop: %ld\n",
@@ -107,7 +107,7 @@
    case VKI_XENMEM_populate_physmap: {
       struct xen_memory_reservation *memory_reservation =
          (struct xen_memory_reservation *)ARG2;
-      char *which;
+      const HChar *which;
 
       switch (ARG1) {
       case VKI_XENMEM_increase_reservation:
diff --git a/coregrind/m_transtab.c b/coregrind/m_transtab.c
index 3f84b7f..ed72041 100644
--- a/coregrind/m_transtab.c
+++ b/coregrind/m_transtab.c
@@ -623,10 +623,10 @@
 }
 
 static
-Int HostExtent__cmpOrd ( void* v1, void* v2 )
+Int HostExtent__cmpOrd ( const void* v1, const void* v2 )
 {
-   HostExtent* hx1 = (HostExtent*)v1;
-   HostExtent* hx2 = (HostExtent*)v2;
+   const HostExtent* hx1 = v1;
+   const HostExtent* hx2 = v2;
    if (hx1->start + hx1->len <= hx2->start) return -1;
    if (hx2->start + hx2->len <= hx1->start) return 1;
    return 0; /* partial overlap */
@@ -656,8 +656,7 @@
       Word firstW = -1, lastW = -1;
       Bool found  = VG_(lookupXA_UNSAFE)(
                        host_extents, &key, &firstW, &lastW,
-                       (Int(*)(void*,void*))HostExtent__cmpOrd
-                    );
+                       HostExtent__cmpOrd );
       vg_assert(firstW == lastW); // always true, even if not found
       if (found) {
          HostExtent* hx = VG_(indexXA)(host_extents, firstW);
@@ -1044,7 +1043,7 @@
 {
 #  define BAD(_str) do { whassup = (_str); goto bad; } while (0)
 
-   HChar*   whassup = NULL;
+   const HChar* whassup = NULL;
    Int      i, j, k, n, ec_num, ec_idx;
    TTEntry* tte;
    UShort   tteno;
diff --git a/coregrind/m_xarray.c b/coregrind/m_xarray.c
index c784f90..e110dbd 100644
--- a/coregrind/m_xarray.c
+++ b/coregrind/m_xarray.c
@@ -41,7 +41,7 @@
    void* (*alloc) ( const HChar*, SizeT ); /* alloc fn (nofail) */
    const HChar* cc;                 /* cost centre for alloc */
    void  (*free) ( void* );         /* free fn */
-   Int   (*cmpFn) ( void*, void* ); /* cmp fn (may be NULL) */
+   Int   (*cmpFn) ( const void*, const void* ); /* cmp fn (may be NULL) */
    Word  elemSzB;   /* element size in bytes */
    void* arr;       /* pointer to elements */
    Word  usedsizeE; /* # used elements in arr */
@@ -125,7 +125,7 @@
    xa->free(xa);
 }
 
-void VG_(setCmpFnXA) ( XArray* xao, Int (*compar)(void*,void*) )
+void VG_(setCmpFnXA) ( XArray* xao, XACmpFn_t compar )
 {
    struct _XArray* xa = (struct _XArray*)xao;
    vg_assert(xa);
@@ -178,7 +178,7 @@
    }
 }
 
-Word VG_(addToXA) ( XArray* xao, void* elem )
+Word VG_(addToXA) ( XArray* xao, const void* elem )
 {
    struct _XArray* xa = (struct _XArray*)xao;
    vg_assert(xa);
@@ -195,7 +195,7 @@
    return xa->usedsizeE-1;
 }
 
-Word VG_(addBytesToXA) ( XArray* xao, void* bytesV, Word nbytes )
+Word VG_(addBytesToXA) ( XArray* xao, const void* bytesV, Word nbytes )
 {
    Word r, i;
    struct _XArray* xa = (struct _XArray*)xao;
@@ -225,9 +225,9 @@
    xa->sorted = True;
 }
 
-Bool VG_(lookupXA_UNSAFE) ( XArray* xao, void* key,
+Bool VG_(lookupXA_UNSAFE) ( XArray* xao, const void* key,
                             /*OUT*/Word* first, /*OUT*/Word* last,
-                            Int(*cmpFn)(void*,void*) )
+                            Int(*cmpFn)(const void*, const void*) )
 {
    Word  lo, mid, hi, cres;
    void* midv;
@@ -264,7 +264,7 @@
    }
 }
 
-Bool VG_(lookupXA) ( XArray* xao, void* key,
+Bool VG_(lookupXA) ( XArray* xao, const void* key,
                      /*OUT*/Word* first, /*OUT*/Word* last )
 {
    struct _XArray* xa = (struct _XArray*)xao;
diff --git a/coregrind/pub_core_debuginfo.h b/coregrind/pub_core_debuginfo.h
index 732fbb3..95bcd5b 100644
--- a/coregrind/pub_core_debuginfo.h
+++ b/coregrind/pub_core_debuginfo.h
@@ -153,7 +153,8 @@
    platforms, a symbol is deemed to be found only if it has a nonzero
    TOC pointer.  */
 extern
-Bool VG_(lookup_symbol_SLOW)(HChar* sopatt, HChar* name, Addr* pEnt, Addr* pToc);
+Bool VG_(lookup_symbol_SLOW)(const HChar* sopatt, HChar* name, Addr* pEnt,
+                             Addr* pToc);
 
 #endif   // __PUB_CORE_DEBUGINFO_H
 
diff --git a/coregrind/vgdb.c b/coregrind/vgdb.c
index ed183a6..160b71c 100644
--- a/coregrind/vgdb.c
+++ b/coregrind/vgdb.c
@@ -459,7 +459,7 @@
    If pid is reported as being dead/exited, waitstopped will return False.
 */
 static
-Bool waitstopped (int pid, int signal_expected, char *msg)
+Bool waitstopped (int pid, int signal_expected, const char *msg)
 {
    pid_t p;
    int status = 0;
@@ -505,7 +505,7 @@
    Returns True if succesful, False otherwise.
    msg is used in tracing and error reporting. */
 static
-Bool stop (int pid, char *msg)
+Bool stop (int pid, const char *msg)
 {
    long res;
 
@@ -524,7 +524,7 @@
    Returns True if succesful, False otherwise.
    msg is used in tracing and error reporting. */
 static
-Bool attach (int pid, char *msg)
+Bool attach (int pid, const char *msg)
 {
    long res;
    static Bool output_error = True;
@@ -1267,7 +1267,7 @@
 }
 
 static
-int open_fifo (char* name, int flags, char* desc)
+int open_fifo (const char* name, int flags, const char* desc)
 {
    int fd;
    DEBUG(1, "opening %s %s\n", name, desc);
@@ -1319,7 +1319,7 @@
    Returns the nr of characters read, -1 if error.
    desc is a string used in tracing */
 static
-int read_buf (int fd, char* buf, char* desc)
+int read_buf (int fd, char* buf, const char* desc)
 {
    int nrread;
    DEBUG(2, "reading %s\n", desc);
@@ -1339,7 +1339,7 @@
    valgrind process that there is new data.
    Returns True if write is ok, False if there was a problem. */
 static
-Bool write_buf(int fd, char* buf, int size, char* desc, Bool notify)
+Bool write_buf(int fd, char* buf, int size, const char* desc, Bool notify)
 {
    int nrwritten;
    int nrw;
@@ -1366,7 +1366,7 @@
    TO_PID } ConnectionKind;
 static const int NumConnectionKind = TO_PID+1;
 static 
-char *ppConnectionKind (ConnectionKind con)
+const char *ppConnectionKind (ConnectionKind con)
 {
    switch (con) {
    case FROM_GDB: return "FROM_GDB";
@@ -2033,7 +2033,7 @@
 void ptrace_restrictions_msg(void)
 {
 #  ifdef PR_SET_PTRACER
-   char *ptrace_scope_setting_file = "/proc/sys/kernel/yama/ptrace_scope";
+   const char *ptrace_scope_setting_file = "/proc/sys/kernel/yama/ptrace_scope";
    int fd = -1;
    char ptrace_scope = 'X';
    fd = open (ptrace_scope_setting_file, O_RDONLY, 0);
@@ -2279,7 +2279,7 @@
 
 /* true if arg matches the provided option */
 static
-Bool is_opt(char* arg, char *option)
+Bool is_opt(char* arg, const char *option)
 {
    int option_len = strlen(option);
    if (option[option_len-1] == '=')
diff --git a/drd/tests/unit_bitmap.c b/drd/tests/unit_bitmap.c
index f2474f5..e537e6d 100644
--- a/drd/tests/unit_bitmap.c
+++ b/drd/tests/unit_bitmap.c
@@ -63,7 +63,7 @@
                     const HChar* format, va_list vargs)
 { assert(0); }
 void VG_(ssort)( void* base, SizeT nmemb, SizeT size,
-                 Int (*compar)(void*, void*) )
+                 Int (*compar)(const void*, const void*) )
 { assert(0); }
 
 /* Actual unit test */
diff --git a/exp-sgcheck/sg_main.c b/exp-sgcheck/sg_main.c
index d250d0e..f5a3133 100644
--- a/exp-sgcheck/sg_main.c
+++ b/exp-sgcheck/sg_main.c
@@ -146,7 +146,7 @@
    vectors describe the same set of variables but are not structurally
    identical. */
 
-static inline Bool StackBlock__sane ( StackBlock* fb )
+static inline Bool StackBlock__sane ( const StackBlock* fb )
 {
    if (fb->name[ sizeof(fb->name)-1 ] != 0)
       return False;
@@ -158,7 +158,7 @@
 }
 
 /* Generate an arbitrary total ordering on StackBlocks. */
-static Word StackBlock__cmp ( StackBlock* fb1, StackBlock* fb2 )
+static Word StackBlock__cmp ( const StackBlock* fb1, const StackBlock* fb2 )
 {
    Word r;
    tl_assert(StackBlock__sane(fb1));
@@ -261,7 +261,7 @@
    UWord key, val;
 
    /* First, normalise, as per comments above. */
-   VG_(setCmpFnXA)( orig, (Int(*)(void*,void*))StackBlock__cmp );
+   VG_(setCmpFnXA)( orig, (XACmpFn_t)StackBlock__cmp );
    VG_(sortXA)( orig );
 
    /* Now get rid of any exact duplicates. */
@@ -944,7 +944,7 @@
    messages. */
 static void show_Invar( HChar* buf, Word nBuf, Invar* inv, Word depth )
 {
-   HChar* str;
+   const HChar* str;
    tl_assert(nBuf >= 128);
    buf[0] = 0;
    switch (inv->tag) {
diff --git a/helgrind/hg_errors.c b/helgrind/hg_errors.c
index 8a6c1d4..d218024 100644
--- a/helgrind/hg_errors.c
+++ b/helgrind/hg_errors.c
@@ -641,8 +641,8 @@
                             XE_LockOrder, 0, NULL, &xe );
 }
 
-void HG_(record_error_PthAPIerror) ( Thread* thr, HChar* fnname, 
-                                     Word err, HChar* errstr )
+void HG_(record_error_PthAPIerror) ( Thread* thr, const HChar* fnname, 
+                                     Word err, const HChar* errstr )
 {
    XError xe;
    tl_assert( HG_(is_sane_Thread)(thr) );
@@ -661,8 +661,8 @@
                             XE_PthAPIerror, 0, NULL, &xe );
 }
 
-void HG_(record_error_Misc_w_aux) ( Thread* thr, HChar* errstr,
-                                    HChar* auxstr, ExeContext* auxctx )
+void HG_(record_error_Misc_w_aux) ( Thread* thr, const HChar* errstr,
+                                    const HChar* auxstr, ExeContext* auxctx )
 {
    XError xe;
    tl_assert( HG_(is_sane_Thread)(thr) );
@@ -680,7 +680,7 @@
                             XE_Misc, 0, NULL, &xe );
 }
 
-void HG_(record_error_Misc) ( Thread* thr, HChar* errstr )
+void HG_(record_error_Misc) ( Thread* thr, const HChar* errstr )
 {
    HG_(record_error_Misc_w_aux)(thr, errstr, NULL, NULL);
 }
@@ -848,7 +848,7 @@
 }
 
 
-static void show_LockP_summary_textmode ( Lock** locks, HChar* pre )
+static void show_LockP_summary_textmode ( Lock** locks, const HChar* pre )
 {
    tl_assert(locks);
    UWord i;
diff --git a/helgrind/hg_errors.h b/helgrind/hg_errors.h
index eb22859..79c6fb5 100644
--- a/helgrind/hg_errors.h
+++ b/helgrind/hg_errors.h
@@ -56,16 +56,18 @@
 void HG_(record_error_UnlockUnlocked) ( Thread*, Lock* );
 void HG_(record_error_UnlockForeign)  ( Thread*, Thread*, Lock* );
 void HG_(record_error_UnlockBogus)    ( Thread*, Addr );
-void HG_(record_error_PthAPIerror)    ( Thread*, HChar*, Word, HChar* );
+void HG_(record_error_PthAPIerror)    ( Thread*, const HChar*, Word,
+                                        const HChar* );
 
 /* see the implementation for meaning of these params */
 void HG_(record_error_LockOrder)      ( Thread*, Addr, Addr,
                                         ExeContext*, ExeContext*,
                                         ExeContext* );
 
-void HG_(record_error_Misc_w_aux)     ( Thread*, HChar* errstr,
-                                        HChar* auxstr, ExeContext* auxctx );
-void HG_(record_error_Misc)           ( Thread* thr, HChar* errstr );
+void HG_(record_error_Misc_w_aux)     ( Thread*, const HChar* errstr,
+                                        const HChar* auxstr,
+                                        ExeContext* auxctx );
+void HG_(record_error_Misc)           ( Thread* thr, const HChar* errstr );
 
 
 /* Statistics pertaining to error management. */
diff --git a/helgrind/hg_main.c b/helgrind/hg_main.c
index c5bea8c..f5e3625 100644
--- a/helgrind/hg_main.c
+++ b/helgrind/hg_main.c
@@ -1951,9 +1951,9 @@
          this is a real lock operation (not a speculative "tryLock"
          kind of thing).  Duh.  Deadlock coming up; but at least
          produce an error message. */
-      HChar* errstr = "Attempt to re-lock a "
-                      "non-recursive lock I already hold";
-      HChar* auxstr = "Lock was previously acquired";
+      const HChar* errstr = "Attempt to re-lock a "
+                            "non-recursive lock I already hold";
+      const HChar* auxstr = "Lock was previously acquired";
       if (lk->acquired_at) {
          HG_(record_error_Misc_w_aux)( thr, errstr, auxstr, lk->acquired_at );
       } else {
diff --git a/helgrind/libhb_core.c b/helgrind/libhb_core.c
index 3ae242d..1b71e3f 100644
--- a/helgrind/libhb_core.c
+++ b/helgrind/libhb_core.c
@@ -1832,9 +1832,9 @@
 static XArray* /* of ThrID */ verydead_thread_table = NULL;
 
 /* Arbitrary total ordering on ThrIDs. */
-static Int cmp__ThrID ( void* v1, void* v2 ) {
-   ThrID id1 = *(ThrID*)v1;
-   ThrID id2 = *(ThrID*)v2;
+static Int cmp__ThrID ( const void* v1, const void* v2 ) {
+   ThrID id1 = *(const ThrID*)v1;
+   ThrID id2 = *(const ThrID*)v2;
    if (id1 < id2) return -1;
    if (id1 > id2) return 1;
    return 0;
@@ -1866,17 +1866,17 @@
    VTS;
 
 /* Allocate a VTS capable of storing 'sizeTS' entries. */
-static VTS* VTS__new ( HChar* who, UInt sizeTS );
+static VTS* VTS__new ( const HChar* who, UInt sizeTS );
 
 /* Make a clone of 'vts', sizing the new array to exactly match the
    number of ScalarTSs present. */
-static VTS* VTS__clone ( HChar* who, VTS* vts );
+static VTS* VTS__clone ( const HChar* who, VTS* vts );
 
 /* Make a clone of 'vts' with the thrids in 'thrids' removed.  The new
    array is sized exactly to hold the number of required elements.
    'thridsToDel' is an array of ThrIDs to be omitted in the clone, and
    must be in strictly increasing order. */
-static VTS* VTS__subtract ( HChar* who, VTS* vts, XArray* thridsToDel );
+static VTS* VTS__subtract ( const HChar* who, VTS* vts, XArray* thridsToDel );
 
 /* Delete this VTS in its entirety. */
 static void VTS__delete ( VTS* vts );
@@ -1960,7 +1960,7 @@
 
 /* Create a new, empty VTS.
 */
-static VTS* VTS__new ( HChar* who, UInt sizeTS )
+static VTS* VTS__new ( const HChar* who, UInt sizeTS )
 {
    VTS* vts = HG_(zalloc)(who, sizeof(VTS) + (sizeTS+1) * sizeof(ScalarTS));
    tl_assert(vts->usedTS == 0);
@@ -1971,7 +1971,7 @@
 
 /* Clone this VTS.
 */
-static VTS* VTS__clone ( HChar* who, VTS* vts )
+static VTS* VTS__clone ( const HChar* who, VTS* vts )
 {
    tl_assert(vts);
    tl_assert( *(ULong*)(&vts->ts[vts->sizeTS]) == 0x0ddC0ffeeBadF00dULL);
@@ -1993,7 +1993,7 @@
    must be in strictly increasing order.  We could obviously do this
    much more efficiently (in linear time) if necessary.
 */
-static VTS* VTS__subtract ( HChar* who, VTS* vts, XArray* thridsToDel )
+static VTS* VTS__subtract ( const HChar* who, VTS* vts, XArray* thridsToDel )
 {
    UInt i, j;
    tl_assert(vts);
@@ -2672,7 +2672,7 @@
 }
 
 
-static void show_vts_stats ( HChar* caller )
+static void show_vts_stats ( const HChar* caller )
 {
    UWord nSet, nTab, nLive;
    ULong totrc;
@@ -3333,7 +3333,7 @@
    fast way to do this is simply to stuff in tags which we know are
    not going to match anything, since they're not aligned to the start
    of a line. */
-static void Filter__clear ( Filter* fi, HChar* who )
+static void Filter__clear ( Filter* fi, const HChar* who )
 {
    UWord i;
    if (0) VG_(printf)("  Filter__clear(%p, %s)\n", fi, who);
@@ -3745,7 +3745,8 @@
       VG_(pp_ExeContext)(pair.ec);
 }
 
-static Int cmp__ULong_n_EC__by_ULong ( ULong_n_EC* pair1, ULong_n_EC* pair2 )
+static Int cmp__ULong_n_EC__by_ULong ( const ULong_n_EC* pair1,
+                                       const ULong_n_EC* pair2 )
 {
    if (pair1->ull < pair2->ull) return -1;
    if (pair1->ull > pair2->ull) return 1;
@@ -4897,7 +4898,7 @@
       found = VG_(lookupXA_UNSAFE)(
                  confThr->local_Kws_n_stacks,
                  &key, &firstIx, &lastIx,
-                 (Int(*)(void*,void*))cmp__ULong_n_EC__by_ULong
+                 (XACmpFn_t)cmp__ULong_n_EC__by_ULong
               );
       if (0) VG_(printf)("record_race_info %u %u %u  confThr %p "
                          "confTym %llu found %d (%lu,%lu)\n", 
@@ -6047,7 +6048,7 @@
 //                                                     //
 /////////////////////////////////////////////////////////
 
-static void show_thread_state ( HChar* str, Thr* t ) 
+static void show_thread_state ( const HChar* str, Thr* t ) 
 {
    if (1) return;
    if (t->viR == t->viW) {
@@ -6491,7 +6492,7 @@
    if (XXX2 && a <= XXX2 && XXX2 <= a+szB) return True;
    return False;
 }
-static void trace ( Thr* thr, Addr a, SizeT szB, const HChar* s ) 
+static void trace ( Thr* thr, Addr a, SizeT szB, const const HChar* s ) 
 {
   SVal sv = zsm_sread08(a);
   VG_(printf)("thr %p (%#lx,%lu) %s: 0x%016llx ", thr,a,szB,s,sv);
diff --git a/include/pub_tool_gdbserver.h b/include/pub_tool_gdbserver.h
index d6fe139..03be811 100644
--- a/include/pub_tool_gdbserver.h
+++ b/include/pub_tool_gdbserver.h
@@ -160,7 +160,7 @@
       kwd_report_none,
       kwd_report_all,
       kwd_report_duplicated_matches } kwd_report_error;
-extern Int VG_(keyword_id) (HChar* keywords, HChar* input_word, 
+extern Int VG_(keyword_id) (const HChar* keywords, const HChar* input_word, 
                             kwd_report_error report);
 
 /* Extract an address and (optionally) a size from the string
diff --git a/include/pub_tool_libcbase.h b/include/pub_tool_libcbase.h
index f1b47f5..ba1dd0c 100644
--- a/include/pub_tool_libcbase.h
+++ b/include/pub_tool_libcbase.h
@@ -179,7 +179,7 @@
 /* Like qsort().  The name VG_(ssort) is for historical reasons -- it used
  * to be a shell sort, but is now a quicksort. */
 extern void VG_(ssort)( void* base, SizeT nmemb, SizeT size,
-                        Int (*compar)(void*, void*) );
+                        Int (*compar)(const void*, const void*) );
 
 /* Returns the base-2 logarithm of a 32 bit unsigned number.  Returns
  -1 if it is not a power of two.  Nb: VG_(log2)(1) == 0. */
diff --git a/include/pub_tool_libcfile.h b/include/pub_tool_libcfile.h
index b9acc1c..3b4d7ce 100644
--- a/include/pub_tool_libcfile.h
+++ b/include/pub_tool_libcfile.h
@@ -91,8 +91,8 @@
 extern Int    VG_(readlink)( const HChar* path, HChar* buf, UInt bufsize );
 extern Int    VG_(getdents)( Int fd, struct vki_dirent *dirp, UInt count );
 
-extern HChar* VG_(basename)( const HChar* path );
-extern HChar* VG_(dirname) ( const HChar* path );
+extern const HChar* VG_(basename)( const HChar* path );
+extern const HChar* VG_(dirname) ( const HChar* path );
 
 /* Return the name of a directory for temporary files. */
 extern const HChar* VG_(tmpdir)(void);
diff --git a/include/pub_tool_machine.h b/include/pub_tool_machine.h
index 08ab203..e52e47c 100644
--- a/include/pub_tool_machine.h
+++ b/include/pub_tool_machine.h
@@ -130,7 +130,7 @@
 // This is very Memcheck-specific -- it's used to find the roots when
 // doing leak checking.
 extern void VG_(apply_to_GP_regs)(void (*f)(ThreadId tid,
-                                            HChar* regname, UWord val));
+                                            const HChar* regname, UWord val));
 
 // This iterator lets you inspect each live thread's stack bounds.
 // Returns False at the end.  'tid' is the iterator and you can only
diff --git a/include/pub_tool_xarray.h b/include/pub_tool_xarray.h
index 81e0526..91484e0 100644
--- a/include/pub_tool_xarray.h
+++ b/include/pub_tool_xarray.h
@@ -46,6 +46,8 @@
 /* It's an abstract type.  Bwaha. */
 typedef  struct _XArray  XArray;
 
+typedef Int (*XACmpFn_t)(const void *, const void *);
+
 /* Create new XArray, using given allocation and free function, and
    for elements of the specified size.  Alloc fn must not fail (that
    is, if it returns it must have succeeded.) */
@@ -60,17 +62,17 @@
 /* Set the comparison function for this XArray.  This clears an
    internal 'array is sorted' flag, which means you must call sortXA
    before making further queries with lookupXA. */
-extern void VG_(setCmpFnXA) ( XArray*, Int (*compar)(void*,void*) );
+extern void VG_(setCmpFnXA) ( XArray*, XACmpFn_t);
 
 /* Add an element to an XArray.  Element is copied into the XArray.
    Index at which it was added is returned.  Note this will be
    invalidated if the array is later sortXA'd. */
-extern Word VG_(addToXA) ( XArray*, void* elem );
+extern Word VG_(addToXA) ( XArray*, const 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 Word VG_(addBytesToXA) ( XArray* xao, void* bytesV, Word nbytes );
+extern Word VG_(addBytesToXA) ( XArray* xao, const void* bytesV, Word nbytes );
 
 /* Sort an XArray using its comparison function, if set; else bomb.
    Probably not a stable sort w.r.t. equal elements module cmpFn. */
@@ -81,7 +83,7 @@
    value found.  If any values are found, return True, else return
    False, and don't change *first or *last.  first and/or last may be
    NULL.  Bomb if the array is not sorted. */
-extern Bool VG_(lookupXA) ( XArray*, void* key, 
+extern Bool VG_(lookupXA) ( XArray*, const void* key, 
                             /*OUT*/Word* first, /*OUT*/Word* last );
 
 /* A version of VG_(lookupXA) in which you can specify your own
@@ -92,9 +94,9 @@
    VG_(lookupXA), which refuses to do anything (asserts) unless the
    array has first been sorted using the same comparison function as
    is being used for the lookup. */
-extern Bool VG_(lookupXA_UNSAFE) ( XArray* xao, void* key,
+extern Bool VG_(lookupXA_UNSAFE) ( XArray* xao, const void* key,
                                    /*OUT*/Word* first, /*OUT*/Word* last,
-                                   Int(*cmpFn)(void*,void*) );
+                                   XACmpFn_t cmpFn );
 
 /* How elements are there in this XArray now? */
 extern Word VG_(sizeXA) ( XArray* );
diff --git a/massif/ms_main.c b/massif/ms_main.c
index 32421b1..4374e49 100644
--- a/massif/ms_main.c
+++ b/massif/ms_main.c
@@ -311,7 +311,7 @@
    // Create the list, and add the default elements.
    alloc_fns = VG_(newXA)(VG_(malloc), "ms.main.iaf.1",
                                        VG_(free), sizeof(HChar*));
-   #define DO(x)  { HChar* s = x; VG_(addToXA)(alloc_fns, &s); }
+   #define DO(x)  { const HChar* s = x; VG_(addToXA)(alloc_fns, &s); }
 
    // Ordered roughly according to (presumed) frequency.
    // Nb: The C++ "operator new*" ones are overloadable.  We include them
@@ -361,7 +361,7 @@
 }
 
 // Determines if the named function is a member of the XArray.
-static Bool is_member_fn(XArray* fns, HChar* fnname)
+static Bool is_member_fn(XArray* fns, const HChar* fnname)
 {
    HChar** fn_ptr;
    Int i;
@@ -660,10 +660,10 @@
 }
 
 // Reverse comparison for a reverse sort -- biggest to smallest.
-static Int SXPt_revcmp_szB(void* n1, void* n2)
+static Int SXPt_revcmp_szB(const void* n1, const void* n2)
 {
-   SXPt* sxpt1 = *(SXPt**)n1;
-   SXPt* sxpt2 = *(SXPt**)n2;
+   const SXPt* sxpt1 = *(const SXPt**)n1;
+   const SXPt* sxpt2 = *(const SXPt**)n2;
    return ( sxpt1->szB < sxpt2->szB ?  1
           : sxpt1->szB > sxpt2->szB ? -1
           :                            0);
@@ -2172,7 +2172,7 @@
    // of the stack frame -- this function is recursive.  Obviously this
    // now means its contents are trashed across the recursive call.
    static HChar ip_desc_array[BUF_LEN];
-   HChar* ip_desc = ip_desc_array;
+   const HChar* ip_desc = ip_desc_array;
 
    switch (sxpt->tag) {
     case SigSXPt:
@@ -2186,6 +2186,10 @@
                );
          } else {
             // XXX: --alloc-fns?
+
+            // Nick thinks this case cannot happen. ip_desc_array would be
+            // conceptually uninitialised here. Therefore:
+            tl_assert2(0, "pp_snapshot_SXPt: unexpected");
          }
       } else {
          // If it's main-or-below-main, we (if appropriate) ignore everything
@@ -2198,7 +2202,7 @@
          }
 
          // We need the -1 to get the line number right, But I'm not sure why.
-         ip_desc = VG_(describe_IP)(sxpt->Sig.ip-1, ip_desc, BUF_LEN);
+         ip_desc = VG_(describe_IP)(sxpt->Sig.ip-1, ip_desc_array, BUF_LEN);
       }
       
       // Do the non-ip_desc part first...
diff --git a/memcheck/mc_errors.c b/memcheck/mc_errors.c
index b140b16..d3aed41 100644
--- a/memcheck/mc_errors.c
+++ b/memcheck/mc_errors.c
@@ -297,8 +297,8 @@
 
 static void mc_pp_AddrInfo ( Addr a, AddrInfo* ai, Bool maybe_gcc )
 {
-   HChar* xpre  = VG_(clo_xml) ? "  <auxwhat>" : " ";
-   HChar* xpost = VG_(clo_xml) ? "</auxwhat>"  : "";
+   const HChar* xpre  = VG_(clo_xml) ? "  <auxwhat>" : " ";
+   const HChar* xpost = VG_(clo_xml) ? "</auxwhat>"  : "";
 
    switch (ai->tag) {
       case Addr_Unknown:
diff --git a/memcheck/mc_leakcheck.c b/memcheck/mc_leakcheck.c
index e848291..1df6303 100644
--- a/memcheck/mc_leakcheck.c
+++ b/memcheck/mc_leakcheck.c
@@ -244,10 +244,10 @@
 /*------------------------------------------------------------*/
 
 // Compare the MC_Chunks by 'data' (i.e. the address of the block).
-static Int compare_MC_Chunks(void* n1, void* n2)
+static Int compare_MC_Chunks(const void* n1, const void* n2)
 {
-   MC_Chunk* mc1 = *(MC_Chunk**)n1;
-   MC_Chunk* mc2 = *(MC_Chunk**)n2;
+   const MC_Chunk* mc1 = *(const MC_Chunk**)n1;
+   const MC_Chunk* mc2 = *(const MC_Chunk**)n2;
    if (mc1->data < mc2->data) return -1;
    if (mc1->data > mc2->data) return  1;
    return 0;
@@ -604,7 +604,7 @@
 }
 
 static void
-lc_push_if_a_chunk_ptr_register(ThreadId tid, HChar* regname, Addr ptr)
+lc_push_if_a_chunk_ptr_register(ThreadId tid, const HChar* regname, Addr ptr)
 {
    lc_push_without_clique_if_a_chunk_ptr(ptr, /*is_prior_definite*/True);
 }
@@ -850,10 +850,10 @@
    VG_(tool_panic)("bad LossRecord comparison");
 }
 
-static Int cmp_LossRecords(void* va, void* vb)
+static Int cmp_LossRecords(const void* va, const void* vb)
 {
-   LossRecord* lr_a = *(LossRecord**)va;
-   LossRecord* lr_b = *(LossRecord**)vb;
+   const LossRecord* lr_a = *(const LossRecord**)va;
+   const LossRecord* lr_b = *(const LossRecord**)vb;
    SizeT total_szB_a = lr_a->szB + lr_a->indirect_szB;
    SizeT total_szB_b = lr_b->szB + lr_b->indirect_szB;
 
@@ -1522,7 +1522,7 @@
 static Addr searched_wpa;
 static SizeT searched_szB;
 static void
-search_address_in_GP_reg(ThreadId tid, HChar* regname, Addr addr_in_reg)
+search_address_in_GP_reg(ThreadId tid, const HChar* regname, Addr addr_in_reg)
 {
    if (addr_in_reg >= searched_wpa 
        && addr_in_reg < searched_wpa + searched_szB) {
diff --git a/memcheck/mc_main.c b/memcheck/mc_main.c
index 812c613..2434de1 100644
--- a/memcheck/mc_main.c
+++ b/memcheck/mc_main.c
@@ -5203,14 +5203,16 @@
             lcp.max_loss_records_output = 999999999; break;
          case  9: { /* limited */
             Int int_value;
-            HChar* endptr;
+            const HChar* endptr;
 
             wcmd = VG_(strtok_r) (NULL, " ", &ssaveptr);
             if (wcmd == NULL) {
                int_value = 0;
                endptr = "empty"; /* to report an error below */
             } else {
-               int_value = VG_(strtoll10) (wcmd, &endptr);
+               HChar *the_end;
+               int_value = VG_(strtoll10) (wcmd, &the_end);
+               endptr = the_end;
             }
             if (*endptr != '\0')
                VG_(gdb_printf) ("missing or malformed integer value\n");
@@ -5256,7 +5258,7 @@
       SizeT szB = 1;
       Addr bad_addr;
       UInt okind;
-      HChar* src;
+      const HChar* src;
       UInt otag;
       UInt ecu;
       ExeContext* origin_ec;
diff --git a/memcheck/mc_malloc_wrappers.c b/memcheck/mc_malloc_wrappers.c
index f31fe2a..5b967b0 100644
--- a/memcheck/mc_malloc_wrappers.c
+++ b/memcheck/mc_malloc_wrappers.c
@@ -667,10 +667,10 @@
 }
 
 static Int 
-mp_compar(void* n1, void* n2)
+mp_compar(const void* n1, const void* n2)
 {
-   MC_Chunk* mc1 = *(MC_Chunk**)n1;
-   MC_Chunk* mc2 = *(MC_Chunk**)n2;
+   const MC_Chunk* mc1 = *(const MC_Chunk**)n1;
+   const MC_Chunk* mc2 = *(const MC_Chunk**)n2;
    if (mc1->data < mc2->data) return -1;
    if (mc1->data > mc2->data) return  1;
    return 0;
diff --git a/memcheck/mc_translate.c b/memcheck/mc_translate.c
index 57229f8..91cb80c 100644
--- a/memcheck/mc_translate.c
+++ b/memcheck/mc_translate.c
@@ -1109,7 +1109,7 @@
    IRAtom*  cond;
    IRAtom*  origin;
    void*    fn;
-   HChar*   nm;
+   const HChar* nm;
    IRExpr** args;
    Int      nargs;
 
@@ -5859,7 +5859,7 @@
                             IRAtom* baseaddr, Int offset )
 {
    void*    hFun;
-   HChar*   hName;
+   const HChar* hName;
    IRTemp   bTmp;
    IRDirty* di;
    IRType   aTy   = typeOfIRExpr( mce->sb->tyenv, baseaddr );
@@ -5937,7 +5937,7 @@
                           IRAtom* guard )
 {
    void*    hFun;
-   HChar*   hName;
+   const HChar* hName;
    IRDirty* di;
    IRType   aTy   = typeOfIRExpr( mce->sb->tyenv, baseaddr );
    IROp     opAdd = aTy == Ity_I32 ? Iop_Add32 : Iop_Add64;