mc_errors.c revision f0cb39bc6abe181a0abdd1f6c778521ae8497277
1
2/*--------------------------------------------------------------------*/
3/*--- Management, printing, etc, of errors and suppressions.       ---*/
4/*---                                                  mc_errors.c ---*/
5/*--------------------------------------------------------------------*/
6
7/*
8   This file is part of MemCheck, a heavyweight Valgrind tool for
9   detecting memory errors.
10
11   Copyright (C) 2000-2010 Julian Seward
12      jseward@acm.org
13
14   This program is free software; you can redistribute it and/or
15   modify it under the terms of the GNU General Public License as
16   published by the Free Software Foundation; either version 2 of the
17   License, or (at your option) any later version.
18
19   This program is distributed in the hope that it will be useful, but
20   WITHOUT ANY WARRANTY; without even the implied warranty of
21   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22   General Public License for more details.
23
24   You should have received a copy of the GNU General Public License
25   along with this program; if not, write to the Free Software
26   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27   02111-1307, USA.
28
29   The GNU General Public License is contained in the file COPYING.
30*/
31
32#include "pub_tool_basics.h"
33#include "pub_tool_hashtable.h"     // For mc_include.h
34#include "pub_tool_libcbase.h"
35#include "pub_tool_libcassert.h"
36#include "pub_tool_libcprint.h"
37#include "pub_tool_machine.h"
38#include "pub_tool_mallocfree.h"
39#include "pub_tool_options.h"
40#include "pub_tool_replacemalloc.h"
41#include "pub_tool_tooliface.h"
42#include "pub_tool_threadstate.h"
43#include "pub_tool_debuginfo.h"     // VG_(get_dataname_and_offset)
44#include "pub_tool_xarray.h"
45#include "pub_tool_vki.h"
46#include "pub_tool_libcfile.h"
47
48#include "mc_include.h"
49
50
51/*------------------------------------------------------------*/
52/*--- Error types                                          ---*/
53/*------------------------------------------------------------*/
54
55/* See comment in mc_include.h */
56Bool MC_(any_value_errors) = False;
57
58
59// Different kinds of blocks.
60typedef enum {
61   Block_Mallocd = 111,
62   Block_Freed,
63   Block_Mempool,
64   Block_MempoolChunk,
65   Block_UserG
66} BlockKind;
67
68/* ------------------ Addresses -------------------- */
69
70/* The classification of a faulting address. */
71typedef
72   enum {
73      Addr_Undescribed, // as-yet unclassified
74      Addr_Unknown,     // classification yielded nothing useful
75      Addr_Block,       // in malloc'd/free'd block
76      Addr_Stack,       // on a thread's stack
77      Addr_DataSym,     // in a global data sym
78      Addr_Variable,    // variable described by the debug info
79      Addr_SectKind     // last-ditch classification attempt
80   }
81   AddrTag;
82
83typedef
84   struct _AddrInfo
85   AddrInfo;
86
87struct _AddrInfo {
88   AddrTag tag;
89   union {
90      // As-yet unclassified.
91      struct { } Undescribed;
92
93      // On a stack.
94      struct {
95         ThreadId tid;        // Which thread's stack?
96      } Stack;
97
98      // This covers heap blocks (normal and from mempools) and user-defined
99      // blocks.
100      struct {
101         BlockKind   block_kind;
102         Char*       block_desc;    // "block", "mempool" or user-defined
103         SizeT       block_szB;
104         PtrdiffT    rwoffset;
105         ExeContext* lastchange;
106      } Block;
107
108      // In a global .data symbol.  This holds the first 127 chars of
109      // the variable's name (zero terminated), plus a (memory) offset.
110      struct {
111         Char     name[128];
112         PtrdiffT offset;
113      } DataSym;
114
115      // Is described by Dwarf debug info.  XArray*s of HChar.
116      struct {
117         XArray* /* of HChar */ descr1;
118         XArray* /* of HChar */ descr2;
119      } Variable;
120
121      // Could only narrow it down to be the PLT/GOT/etc of a given
122      // object.  Better than nothing, perhaps.
123      struct {
124         Char       objname[128];
125         VgSectKind kind;
126      } SectKind;
127
128      // Classification yielded nothing useful.
129      struct { } Unknown;
130
131   } Addr;
132};
133
134/* ------------------ Errors ----------------------- */
135
136/* What kind of error it is. */
137typedef
138   enum {
139      Err_Value,
140      Err_Cond,
141      Err_CoreMem,
142      Err_Addr,
143      Err_Jump,
144      Err_RegParam,
145      Err_MemParam,
146      Err_User,
147      Err_Free,
148      Err_FreeMismatch,
149      Err_Overlap,
150      Err_Leak,
151      Err_IllegalMempool,
152   }
153   MC_ErrorTag;
154
155
156typedef struct _MC_Error MC_Error;
157
158struct _MC_Error {
159   // Nb: we don't need the tag here, as it's stored in the Error type! Yuk.
160   //MC_ErrorTag tag;
161
162   union {
163      // Use of an undefined value:
164      // - as a pointer in a load or store
165      // - as a jump target
166      struct {
167         SizeT szB;   // size of value in bytes
168         // Origin info
169         UInt        otag;      // origin tag
170         ExeContext* origin_ec; // filled in later
171      } Value;
172
173      // Use of an undefined value in a conditional branch or move.
174      struct {
175         // Origin info
176         UInt        otag;      // origin tag
177         ExeContext* origin_ec; // filled in later
178      } Cond;
179
180      // Addressability error in core (signal-handling) operation.
181      // It would be good to get rid of this error kind, merge it with
182      // another one somehow.
183      struct {
184      } CoreMem;
185
186      // Use of an unaddressable memory location in a load or store.
187      struct {
188         Bool     isWrite;    // read or write?
189         SizeT    szB;        // not used for exec (jump) errors
190         Bool     maybe_gcc;  // True if just below %esp -- could be a gcc bug
191         AddrInfo ai;
192      } Addr;
193
194      // Jump to an unaddressable memory location.
195      struct {
196         AddrInfo ai;
197      } Jump;
198
199      // System call register input contains undefined bytes.
200      struct {
201         // Origin info
202         UInt        otag;      // origin tag
203         ExeContext* origin_ec; // filled in later
204      } RegParam;
205
206      // System call memory input contains undefined/unaddressable bytes
207      struct {
208         Bool     isAddrErr;  // Addressability or definedness error?
209         AddrInfo ai;
210         // Origin info
211         UInt        otag;      // origin tag
212         ExeContext* origin_ec; // filled in later
213      } MemParam;
214
215      // Problem found from a client request like CHECK_MEM_IS_ADDRESSABLE.
216      struct {
217         Bool     isAddrErr;  // Addressability or definedness error?
218         AddrInfo ai;
219         // Origin info
220         UInt        otag;      // origin tag
221         ExeContext* origin_ec; // filled in later
222      } User;
223
224      // Program tried to free() something that's not a heap block (this
225      // covers double-frees). */
226      struct {
227         AddrInfo ai;
228      } Free;
229
230      // Program allocates heap block with one function
231      // (malloc/new/new[]/custom) and deallocates with not the matching one.
232      struct {
233         AddrInfo ai;
234      } FreeMismatch;
235
236      // Call to strcpy, memcpy, etc, with overlapping blocks.
237      struct {
238         Addr src;   // Source block
239         Addr dst;   // Destination block
240         Int  szB;   // Size in bytes;  0 if unused.
241      } Overlap;
242
243      // A memory leak.
244      struct {
245         UInt        n_this_record;
246         UInt        n_total_records;
247         LossRecord* lr;
248      } Leak;
249
250      // A memory pool error.
251      struct {
252         AddrInfo ai;
253      } IllegalMempool;
254
255   } Err;
256};
257
258
259/*------------------------------------------------------------*/
260/*--- Printing errors                                      ---*/
261/*------------------------------------------------------------*/
262
263/* This is the "this error is due to be printed shortly; so have a
264   look at it any print any preamble you want" function.  Which, in
265   Memcheck, we don't use.  Hence a no-op.
266*/
267void MC_(before_pp_Error) ( Error* err ) {
268}
269
270/* Do a printf-style operation on either the XML or normal output
271   channel, depending on the setting of VG_(clo_xml).
272*/
273static void emit_WRK ( HChar* format, va_list vargs )
274{
275   if (VG_(clo_xml)) {
276      VG_(vprintf_xml)(format, vargs);
277   } else {
278      VG_(vmessage)(Vg_UserMsg, format, vargs);
279   }
280}
281static void emit ( HChar* format, ... ) PRINTF_CHECK(1, 2);
282static void emit ( HChar* format, ... )
283{
284   va_list vargs;
285   va_start(vargs, format);
286   emit_WRK(format, vargs);
287   va_end(vargs);
288}
289static void emiN ( HChar* format, ... ) /* NO FORMAT CHECK */
290{
291   va_list vargs;
292   va_start(vargs, format);
293   emit_WRK(format, vargs);
294   va_end(vargs);
295}
296
297
298static void mc_pp_AddrInfo ( Addr a, AddrInfo* ai, Bool maybe_gcc )
299{
300   HChar* xpre  = VG_(clo_xml) ? "  <auxwhat>" : " ";
301   HChar* xpost = VG_(clo_xml) ? "</auxwhat>"  : "";
302
303   switch (ai->tag) {
304      case Addr_Unknown:
305         if (maybe_gcc) {
306            emit( "%sAddress 0x%llx is just below the stack ptr.  "
307                  "To suppress, use: --workaround-gcc296-bugs=yes%s\n",
308                  xpre, (ULong)a, xpost );
309	 } else {
310            emit( "%sAddress 0x%llx "
311                  "is not stack'd, malloc'd or (recently) free'd%s\n",
312                  xpre, (ULong)a, xpost );
313         }
314         break;
315
316      case Addr_Stack:
317         emit( "%sAddress 0x%llx is on thread %d's stack%s\n",
318               xpre, (ULong)a, ai->Addr.Stack.tid, xpost );
319         break;
320
321      case Addr_Block: {
322         SizeT    block_szB = ai->Addr.Block.block_szB;
323         PtrdiffT rwoffset  = ai->Addr.Block.rwoffset;
324         SizeT    delta;
325         const    Char* relative;
326
327         if (rwoffset < 0) {
328            delta    = (SizeT)(-rwoffset);
329            relative = "before";
330         } else if (rwoffset >= block_szB) {
331            delta    = rwoffset - block_szB;
332            relative = "after";
333         } else {
334            delta    = rwoffset;
335            relative = "inside";
336         }
337         emit(
338            "%sAddress 0x%lx is %'lu bytes %s a %s of size %'lu %s%s\n",
339            xpre,
340            a, delta, relative, ai->Addr.Block.block_desc,
341            block_szB,
342            ai->Addr.Block.block_kind==Block_Mallocd ? "alloc'd"
343            : ai->Addr.Block.block_kind==Block_Freed ? "free'd"
344                                                     : "client-defined",
345            xpost
346         );
347         VG_(pp_ExeContext)(ai->Addr.Block.lastchange);
348         break;
349      }
350
351      case Addr_DataSym:
352         emiN( "%sAddress 0x%llx is %llu bytes "
353               "inside data symbol \"%t\"%s\n",
354               xpre,
355               (ULong)a,
356               (ULong)ai->Addr.DataSym.offset,
357               ai->Addr.DataSym.name,
358               xpost );
359         break;
360
361      case Addr_Variable:
362         /* Note, no need for XML tags here, because descr1/2 will
363            already have <auxwhat> or <xauxwhat>s on them, in XML
364            mode. */
365         if (ai->Addr.Variable.descr1)
366            emit( "%s%s\n",
367                  VG_(clo_xml) ? "  " : " ",
368                  (HChar*)VG_(indexXA)(ai->Addr.Variable.descr1, 0) );
369         if (ai->Addr.Variable.descr2)
370            emit( "%s%s\n",
371                  VG_(clo_xml) ? "  " : " ",
372                  (HChar*)VG_(indexXA)(ai->Addr.Variable.descr2, 0) );
373         break;
374
375      case Addr_SectKind:
376         emiN( "%sAddress 0x%llx is in the %t segment of %t%s\n",
377               xpre,
378               (ULong)a,
379               VG_(pp_SectKind)(ai->Addr.SectKind.kind),
380               ai->Addr.SectKind.objname,
381               xpost );
382         break;
383
384      default:
385         VG_(tool_panic)("mc_pp_AddrInfo");
386   }
387}
388
389static const HChar* str_leak_lossmode ( Reachedness lossmode )
390{
391   const HChar *loss = "?";
392   switch (lossmode) {
393      case Unreached:    loss = "definitely lost"; break;
394      case IndirectLeak: loss = "indirectly lost"; break;
395      case Possible:     loss = "possibly lost"; break;
396      case Reachable:    loss = "still reachable"; break;
397   }
398   return loss;
399}
400
401static const HChar* xml_leak_kind ( Reachedness lossmode )
402{
403   const HChar *loss = "?";
404   switch (lossmode) {
405      case Unreached:    loss = "Leak_DefinitelyLost"; break;
406      case IndirectLeak: loss = "Leak_IndirectlyLost"; break;
407      case Possible:     loss = "Leak_PossiblyLost"; break;
408      case Reachable:    loss = "Leak_StillReachable"; break;
409   }
410   return loss;
411}
412
413static void mc_pp_origin ( ExeContext* ec, UInt okind )
414{
415   HChar* src = NULL;
416   tl_assert(ec);
417
418   switch (okind) {
419      case MC_OKIND_STACK:   src = " by a stack allocation"; break;
420      case MC_OKIND_HEAP:    src = " by a heap allocation"; break;
421      case MC_OKIND_USER:    src = " by a client request"; break;
422      case MC_OKIND_UNKNOWN: src = ""; break;
423   }
424   tl_assert(src); /* guards against invalid 'okind' */
425
426   if (VG_(clo_xml)) {
427      emit( "  <auxwhat>Uninitialised value was created%s</auxwhat>\n",
428            src);
429      VG_(pp_ExeContext)( ec );
430   } else {
431      emit( " Uninitialised value was created%s\n", src);
432      VG_(pp_ExeContext)( ec );
433   }
434}
435
436void MC_(pp_Error) ( Error* err )
437{
438   const Bool xml  = VG_(clo_xml); /* a shorthand */
439   MC_Error* extra = VG_(get_error_extra)(err);
440
441   switch (VG_(get_error_kind)(err)) {
442      case Err_CoreMem:
443         /* What the hell *is* a CoreMemError? jrs 2005-May-18 */
444         /* As of 2006-Dec-14, it's caused by unaddressable bytes in a
445            signal handler frame.  --njn */
446         // JRS 17 May 09: None of our regtests exercise this; hence AFAIK
447         // the following code is untested.  Bad.
448         if (xml) {
449            emit( "  <kind>CoreMemError</kind>\n" );
450            emiN( "  <what>%t contains unaddressable byte(s)</what>\n",
451                  VG_(get_error_string)(err));
452            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
453         } else {
454            emit( "%s contains unaddressable byte(s)\n",
455                  VG_(get_error_string)(err));
456            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
457         }
458         break;
459
460      case Err_Value:
461         MC_(any_value_errors) = True;
462         if (xml) {
463            emit( "  <kind>UninitValue</kind>\n" );
464            emit( "  <what>Use of uninitialised value of size %ld</what>\n",
465                  extra->Err.Value.szB );
466            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
467            if (extra->Err.Value.origin_ec)
468               mc_pp_origin( extra->Err.Value.origin_ec,
469                            extra->Err.Value.otag & 3 );
470         } else {
471            /* Could also show extra->Err.Cond.otag if debugging origin
472               tracking */
473            emit( "Use of uninitialised value of size %ld\n",
474                  extra->Err.Value.szB );
475            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
476            if (extra->Err.Value.origin_ec)
477               mc_pp_origin( extra->Err.Value.origin_ec,
478                            extra->Err.Value.otag & 3 );
479         }
480         break;
481
482      case Err_Cond:
483         MC_(any_value_errors) = True;
484         if (xml) {
485            emit( "  <kind>UninitCondition</kind>\n" );
486            emit( "  <what>Conditional jump or move depends"
487                  " on uninitialised value(s)</what>\n" );
488            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
489            if (extra->Err.Cond.origin_ec)
490               mc_pp_origin( extra->Err.Cond.origin_ec,
491                             extra->Err.Cond.otag & 3 );
492         } else {
493            /* Could also show extra->Err.Cond.otag if debugging origin
494               tracking */
495            emit( "Conditional jump or move depends"
496                  " on uninitialised value(s)\n" );
497            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
498            if (extra->Err.Cond.origin_ec)
499               mc_pp_origin( extra->Err.Cond.origin_ec,
500                             extra->Err.Cond.otag & 3 );
501         }
502         break;
503
504      case Err_RegParam:
505         MC_(any_value_errors) = True;
506         if (xml) {
507            emit( "  <kind>SyscallParam</kind>\n" );
508            emiN( "  <what>Syscall param %t contains "
509                  "uninitialised byte(s)</what>\n",
510                  VG_(get_error_string)(err) );
511            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
512            if (extra->Err.RegParam.origin_ec)
513               mc_pp_origin( extra->Err.RegParam.origin_ec,
514                             extra->Err.RegParam.otag & 3 );
515         } else {
516            emit( "Syscall param %s contains uninitialised byte(s)\n",
517                  VG_(get_error_string)(err) );
518            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
519            if (extra->Err.RegParam.origin_ec)
520               mc_pp_origin( extra->Err.RegParam.origin_ec,
521                             extra->Err.RegParam.otag & 3 );
522         }
523         break;
524
525      case Err_MemParam:
526         if (!extra->Err.MemParam.isAddrErr)
527            MC_(any_value_errors) = True;
528         if (xml) {
529            emit( "  <kind>SyscallParam</kind>\n" );
530            emiN( "  <what>Syscall param %t points to %s byte(s)</what>\n",
531                  VG_(get_error_string)(err),
532                  extra->Err.MemParam.isAddrErr
533                     ? "unaddressable" : "uninitialised" );
534            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
535            mc_pp_AddrInfo(VG_(get_error_address)(err),
536                           &extra->Err.MemParam.ai, False);
537            if (extra->Err.MemParam.origin_ec
538                && !extra->Err.MemParam.isAddrErr)
539               mc_pp_origin( extra->Err.MemParam.origin_ec,
540                             extra->Err.MemParam.otag & 3 );
541         } else {
542            emit( "Syscall param %s points to %s byte(s)\n",
543                  VG_(get_error_string)(err),
544                  extra->Err.MemParam.isAddrErr
545                     ? "unaddressable" : "uninitialised" );
546            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
547            mc_pp_AddrInfo(VG_(get_error_address)(err),
548                           &extra->Err.MemParam.ai, False);
549            if (extra->Err.MemParam.origin_ec
550                && !extra->Err.MemParam.isAddrErr)
551               mc_pp_origin( extra->Err.MemParam.origin_ec,
552                             extra->Err.MemParam.otag & 3 );
553         }
554         break;
555
556      case Err_User:
557         if (!extra->Err.User.isAddrErr)
558            MC_(any_value_errors) = True;
559         if (xml) {
560            emit( "  <kind>ClientCheck</kind>\n" );
561            emit( "  <what>%s byte(s) found "
562                  "during client check request</what>\n",
563                   extra->Err.User.isAddrErr
564                      ? "Unaddressable" : "Uninitialised" );
565            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
566            mc_pp_AddrInfo(VG_(get_error_address)(err), &extra->Err.User.ai,
567                           False);
568            if (extra->Err.User.origin_ec && !extra->Err.User.isAddrErr)
569               mc_pp_origin( extra->Err.User.origin_ec,
570                             extra->Err.User.otag & 3 );
571         } else {
572            emit( "%s byte(s) found during client check request\n",
573                   extra->Err.User.isAddrErr
574                      ? "Unaddressable" : "Uninitialised" );
575            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
576            mc_pp_AddrInfo(VG_(get_error_address)(err), &extra->Err.User.ai,
577                           False);
578            if (extra->Err.User.origin_ec && !extra->Err.User.isAddrErr)
579               mc_pp_origin( extra->Err.User.origin_ec,
580                             extra->Err.User.otag & 3 );
581         }
582         break;
583
584      case Err_Free:
585         if (xml) {
586            emit( "  <kind>InvalidFree</kind>\n" );
587            emit( "  <what>Invalid free() / delete / delete[]</what>\n" );
588            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
589            mc_pp_AddrInfo( VG_(get_error_address)(err),
590                            &extra->Err.Free.ai, False );
591         } else {
592            emit( "Invalid free() / delete / delete[]\n" );
593            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
594            mc_pp_AddrInfo( VG_(get_error_address)(err),
595                            &extra->Err.Free.ai, False );
596         }
597         break;
598
599      case Err_FreeMismatch:
600         if (xml) {
601            emit( "  <kind>MismatchedFree</kind>\n" );
602            emit( "  <what>Mismatched free() / delete / delete []</what>\n" );
603            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
604            mc_pp_AddrInfo(VG_(get_error_address)(err),
605                           &extra->Err.FreeMismatch.ai, False);
606         } else {
607            emit( "Mismatched free() / delete / delete []\n" );
608            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
609            mc_pp_AddrInfo(VG_(get_error_address)(err),
610                           &extra->Err.FreeMismatch.ai, False);
611         }
612         break;
613
614      case Err_Addr:
615         if (xml) {
616            emit( "  <kind>Invalid%s</kind>\n",
617                  extra->Err.Addr.isWrite ? "Write" : "Read"  );
618            emit( "  <what>Invalid %s of size %ld</what>\n",
619                  extra->Err.Addr.isWrite ? "write" : "read",
620                  extra->Err.Addr.szB );
621            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
622            mc_pp_AddrInfo( VG_(get_error_address)(err),
623                            &extra->Err.Addr.ai,
624                            extra->Err.Addr.maybe_gcc );
625         } else {
626            emit( "Invalid %s of size %ld\n",
627                  extra->Err.Addr.isWrite ? "write" : "read",
628                  extra->Err.Addr.szB );
629            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
630
631            mc_pp_AddrInfo( VG_(get_error_address)(err),
632                            &extra->Err.Addr.ai,
633                            extra->Err.Addr.maybe_gcc );
634         }
635         break;
636
637      case Err_Jump:
638         if (xml) {
639            emit( "  <kind>InvalidJump</kind>\n" );
640            emit( "  <what>Jump to the invalid address stated "
641                  "on the next line</what>\n" );
642            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
643            mc_pp_AddrInfo( VG_(get_error_address)(err), &extra->Err.Jump.ai,
644                            False );
645         } else {
646            emit( "Jump to the invalid address stated on the next line\n" );
647            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
648            mc_pp_AddrInfo( VG_(get_error_address)(err), &extra->Err.Jump.ai,
649                            False );
650         }
651         break;
652
653      case Err_Overlap:
654         if (xml) {
655            emit( "  <kind>Overlap</kind>\n" );
656            if (extra->Err.Overlap.szB == 0) {
657               emiN( "  <what>Source and destination overlap "
658                     "in %t(%#lx, %#lx)\n</what>\n",
659                     VG_(get_error_string)(err),
660                     extra->Err.Overlap.dst, extra->Err.Overlap.src );
661            } else {
662               emit( "  <what>Source and destination overlap "
663                     "in %s(%#lx, %#lx, %d)</what>\n",
664                     VG_(get_error_string)(err),
665                     extra->Err.Overlap.dst, extra->Err.Overlap.src,
666                     extra->Err.Overlap.szB );
667            }
668            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
669         } else {
670            if (extra->Err.Overlap.szB == 0) {
671               emiN( "Source and destination overlap in %t(%#lx, %#lx)\n",
672                     VG_(get_error_string)(err),
673                     extra->Err.Overlap.dst, extra->Err.Overlap.src );
674            } else {
675               emit( "Source and destination overlap in %s(%#lx, %#lx, %d)\n",
676                     VG_(get_error_string)(err),
677                     extra->Err.Overlap.dst, extra->Err.Overlap.src,
678                     extra->Err.Overlap.szB );
679            }
680            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
681         }
682         break;
683
684      case Err_IllegalMempool:
685         // JRS 17 May 09: None of our regtests exercise this; hence AFAIK
686         // the following code is untested.  Bad.
687         if (xml) {
688            emit( "  <kind>InvalidMemPool</kind>\n" );
689            emit( "  <what>Illegal memory pool address</what>\n" );
690            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
691            mc_pp_AddrInfo( VG_(get_error_address)(err),
692                            &extra->Err.IllegalMempool.ai, False );
693         } else {
694            emit( "Illegal memory pool address\n" );
695            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
696            mc_pp_AddrInfo( VG_(get_error_address)(err),
697                            &extra->Err.IllegalMempool.ai, False );
698         }
699         break;
700
701      case Err_Leak: {
702         UInt        n_this_record   = extra->Err.Leak.n_this_record;
703         UInt        n_total_records = extra->Err.Leak.n_total_records;
704         LossRecord* lr              = extra->Err.Leak.lr;
705         if (xml) {
706            emit("  <kind>%s</kind>\n", xml_leak_kind(lr->key.state));
707            if (lr->indirect_szB > 0) {
708               emit( "  <xwhat>\n" );
709               emit( "    <text>%'lu (%'lu direct, %'lu indirect) bytes "
710                     "in %'u blocks"
711                     " are %s in loss record %'u of %'u</text>\n",
712                     lr->szB + lr->indirect_szB, lr->szB, lr->indirect_szB,
713                     lr->num_blocks,
714                     str_leak_lossmode(lr->key.state),
715                     n_this_record, n_total_records );
716               // Nb: don't put commas in these XML numbers
717               emit( "    <leakedbytes>%lu</leakedbytes>\n",
718                     lr->szB + lr->indirect_szB );
719               emit( "    <leakedblocks>%u</leakedblocks>\n", lr->num_blocks );
720               emit( "  </xwhat>\n" );
721            } else {
722               emit( "  <xwhat>\n" );
723               emit( "    <text>%'lu bytes in %'u blocks"
724                     " are %s in loss record %'u of %'u</text>\n",
725                     lr->szB, lr->num_blocks,
726                     str_leak_lossmode(lr->key.state),
727                     n_this_record, n_total_records );
728               emit( "    <leakedbytes>%ld</leakedbytes>\n", lr->szB);
729               emit( "    <leakedblocks>%d</leakedblocks>\n", lr->num_blocks);
730               emit( "  </xwhat>\n" );
731            }
732            VG_(pp_ExeContext)(lr->key.allocated_at);
733         } else { /* ! if (xml) */
734            if (lr->indirect_szB > 0) {
735               emit(
736                  "%'lu (%'lu direct, %'lu indirect) bytes in %'u blocks"
737                  " are %s in loss record %'u of %'u\n",
738                  lr->szB + lr->indirect_szB, lr->szB, lr->indirect_szB,
739                  lr->num_blocks, str_leak_lossmode(lr->key.state),
740                  n_this_record, n_total_records
741               );
742            } else {
743               emit(
744                  "%'lu bytes in %'u blocks are %s in loss record %'u of %'u\n",
745                  lr->szB, lr->num_blocks, str_leak_lossmode(lr->key.state),
746                  n_this_record, n_total_records
747               );
748            }
749            VG_(pp_ExeContext)(lr->key.allocated_at);
750         } /* if (xml) */
751         break;
752      }
753
754      default:
755         VG_(printf)("Error:\n  unknown Memcheck error code %d\n",
756                     VG_(get_error_kind)(err));
757         VG_(tool_panic)("unknown error code in mc_pp_Error)");
758   }
759
760   if (MC_(clo_summary_file)) {
761      /* Each time we report a warning, we replace the contents of the summary
762       * file with one line indicating the number of reported warnings.
763       * This way, at the end of memcheck execution we will have a file with
764       * one line saying
765       *   Memcheck: XX warnings reported
766       * If there were no warnings, the file will not be changed.
767       * If memcheck crashes, the file will still contain the last summary.
768       * */
769      static int n_warnings = 0;
770      char buf[100];
771      SysRes sres = VG_(open)(MC_(clo_summary_file),
772                              VKI_O_WRONLY|VKI_O_CREAT|VKI_O_TRUNC,
773                              VKI_S_IRUSR|VKI_S_IWUSR);
774      if (sr_isError(sres)) {
775         VG_(tool_panic)("can not open the summary file");
776      }
777      n_warnings++;
778      VG_(snprintf)(buf, sizeof(buf), "Memcheck: %d warning(s) reported\n",
779                    n_warnings);
780      VG_(write)(sr_Res(sres), buf, VG_(strlen)(buf));
781      VG_(close)(sr_Res(sres));
782   }
783}
784
785/*------------------------------------------------------------*/
786/*--- Recording errors                                     ---*/
787/*------------------------------------------------------------*/
788
789/* These many bytes below %ESP are considered addressible if we're
790   doing the --workaround-gcc296-bugs hack. */
791#define VG_GCC296_BUG_STACK_SLOP 1024
792
793/* Is this address within some small distance below %ESP?  Used only
794   for the --workaround-gcc296-bugs kludge. */
795static Bool is_just_below_ESP( Addr esp, Addr aa )
796{
797   esp -= VG_STACK_REDZONE_SZB;
798   if (esp > aa && (esp - aa) <= VG_GCC296_BUG_STACK_SLOP)
799      return True;
800   else
801      return False;
802}
803
804/* --- Called from generated and non-generated code --- */
805
806void MC_(record_address_error) ( ThreadId tid, Addr a, Int szB,
807                                 Bool isWrite )
808{
809   MC_Error extra;
810   Bool     just_below_esp;
811
812   if (MC_(in_ignored_range)(a))
813      return;
814
815#  if defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
816   /* AIX zero-page handling.  On AIX, reads from page zero are,
817      bizarrely enough, legitimate.  Writes to page zero aren't,
818      though.  Since memcheck can't distinguish reads from writes, the
819      best we can do is to 'act normal' and mark the A bits in the
820      normal way as noaccess, but then hide any reads from that page
821      that get reported here. */
822   if ((!isWrite) && a >= 0 && a < 4096 && a+szB <= 4096)
823      return;
824
825   /* Appalling AIX hack.  It suppresses reads done by glink
826      fragments.  Getting rid of this would require figuring out
827      somehow where the referenced data areas are (and their
828      sizes). */
829   if ((!isWrite) && szB == sizeof(Word)) {
830      UInt i1, i2;
831      UInt* pc = (UInt*)VG_(get_IP)(tid);
832      if (sizeof(Word) == 4) {
833         i1 = 0x800c0000; /* lwz r0,0(r12) */
834         i2 = 0x804c0004; /* lwz r2,4(r12) */
835      } else {
836         i1 = 0xe80c0000; /* ld  r0,0(r12) */
837         i2 = 0xe84c0008; /* ld  r2,8(r12) */
838      }
839      if (pc[0] == i1 && pc[1] == i2) return;
840      if (pc[0] == i2 && pc[-1] == i1) return;
841   }
842#  endif
843
844   just_below_esp = is_just_below_ESP( VG_(get_SP)(tid), a );
845
846   /* If this is caused by an access immediately below %ESP, and the
847      user asks nicely, we just ignore it. */
848   if (MC_(clo_workaround_gcc296_bugs) && just_below_esp)
849      return;
850
851   extra.Err.Addr.isWrite   = isWrite;
852   extra.Err.Addr.szB       = szB;
853   extra.Err.Addr.maybe_gcc = just_below_esp;
854   extra.Err.Addr.ai.tag    = Addr_Undescribed;
855   VG_(maybe_record_error)( tid, Err_Addr, a, /*s*/NULL, &extra );
856}
857
858void MC_(record_value_error) ( ThreadId tid, Int szB, UInt otag )
859{
860   MC_Error extra;
861   tl_assert( MC_(clo_mc_level) >= 2 );
862   if (otag > 0)
863      tl_assert( MC_(clo_mc_level) == 3 );
864   extra.Err.Value.szB       = szB;
865   extra.Err.Value.otag      = otag;
866   extra.Err.Value.origin_ec = NULL;  /* Filled in later */
867   VG_(maybe_record_error)( tid, Err_Value, /*addr*/0, /*s*/NULL, &extra );
868}
869
870void MC_(record_cond_error) ( ThreadId tid, UInt otag )
871{
872   MC_Error extra;
873   tl_assert( MC_(clo_mc_level) >= 2 );
874   if (otag > 0)
875      tl_assert( MC_(clo_mc_level) == 3 );
876   extra.Err.Cond.otag      = otag;
877   extra.Err.Cond.origin_ec = NULL;  /* Filled in later */
878   VG_(maybe_record_error)( tid, Err_Cond, /*addr*/0, /*s*/NULL, &extra );
879}
880
881/* --- Called from non-generated code --- */
882
883/* This is for memory errors in signal-related memory. */
884void MC_(record_core_mem_error) ( ThreadId tid, Char* msg )
885{
886   VG_(maybe_record_error)( tid, Err_CoreMem, /*addr*/0, msg, /*extra*/NULL );
887}
888
889void MC_(record_regparam_error) ( ThreadId tid, Char* msg, UInt otag )
890{
891   MC_Error extra;
892   tl_assert(VG_INVALID_THREADID != tid);
893   if (otag > 0)
894      tl_assert( MC_(clo_mc_level) == 3 );
895   extra.Err.RegParam.otag      = otag;
896   extra.Err.RegParam.origin_ec = NULL;  /* Filled in later */
897   VG_(maybe_record_error)( tid, Err_RegParam, /*addr*/0, msg, &extra );
898}
899
900void MC_(record_memparam_error) ( ThreadId tid, Addr a,
901                                  Bool isAddrErr, Char* msg, UInt otag )
902{
903   MC_Error extra;
904   tl_assert(VG_INVALID_THREADID != tid);
905   if (!isAddrErr)
906      tl_assert( MC_(clo_mc_level) >= 2 );
907   if (otag != 0) {
908      tl_assert( MC_(clo_mc_level) == 3 );
909      tl_assert( !isAddrErr );
910   }
911   extra.Err.MemParam.isAddrErr = isAddrErr;
912   extra.Err.MemParam.ai.tag    = Addr_Undescribed;
913   extra.Err.MemParam.otag      = otag;
914   extra.Err.MemParam.origin_ec = NULL;  /* Filled in later */
915   VG_(maybe_record_error)( tid, Err_MemParam, a, msg, &extra );
916}
917
918void MC_(record_jump_error) ( ThreadId tid, Addr a )
919{
920   MC_Error extra;
921   tl_assert(VG_INVALID_THREADID != tid);
922   extra.Err.Jump.ai.tag = Addr_Undescribed;
923   VG_(maybe_record_error)( tid, Err_Jump, a, /*s*/NULL, &extra );
924}
925
926void MC_(record_free_error) ( ThreadId tid, Addr a )
927{
928   MC_Error extra;
929   tl_assert(VG_INVALID_THREADID != tid);
930   extra.Err.Free.ai.tag = Addr_Undescribed;
931   VG_(maybe_record_error)( tid, Err_Free, a, /*s*/NULL, &extra );
932}
933
934void MC_(record_freemismatch_error) ( ThreadId tid, MC_Chunk* mc )
935{
936   MC_Error extra;
937   AddrInfo* ai = &extra.Err.FreeMismatch.ai;
938   tl_assert(VG_INVALID_THREADID != tid);
939   ai->tag = Addr_Block;
940   ai->Addr.Block.block_kind = Block_Mallocd;  // Nb: Not 'Block_Freed'
941   ai->Addr.Block.block_desc = "block";
942   ai->Addr.Block.block_szB  = mc->szB;
943   ai->Addr.Block.rwoffset   = 0;
944   ai->Addr.Block.lastchange = mc->where;
945   VG_(maybe_record_error)( tid, Err_FreeMismatch, mc->data, /*s*/NULL,
946                            &extra );
947}
948
949void MC_(record_illegal_mempool_error) ( ThreadId tid, Addr a )
950{
951   MC_Error extra;
952   tl_assert(VG_INVALID_THREADID != tid);
953   extra.Err.IllegalMempool.ai.tag = Addr_Undescribed;
954   VG_(maybe_record_error)( tid, Err_IllegalMempool, a, /*s*/NULL, &extra );
955}
956
957void MC_(record_overlap_error) ( ThreadId tid, Char* function,
958                                 Addr src, Addr dst, SizeT szB )
959{
960   MC_Error extra;
961   tl_assert(VG_INVALID_THREADID != tid);
962   extra.Err.Overlap.src = src;
963   extra.Err.Overlap.dst = dst;
964   extra.Err.Overlap.szB = szB;
965   VG_(maybe_record_error)(
966      tid, Err_Overlap, /*addr*/0, /*s*/function, &extra );
967}
968
969Bool MC_(record_leak_error) ( ThreadId tid, UInt n_this_record,
970                              UInt n_total_records, LossRecord* lr,
971                              Bool print_record, Bool count_error )
972{
973   MC_Error extra;
974   extra.Err.Leak.n_this_record   = n_this_record;
975   extra.Err.Leak.n_total_records = n_total_records;
976   extra.Err.Leak.lr              = lr;
977   return
978   VG_(unique_error) ( tid, Err_Leak, /*Addr*/0, /*s*/NULL, &extra,
979                       lr->key.allocated_at, print_record,
980                       /*allow_GDB_attach*/False, count_error );
981}
982
983void MC_(record_user_error) ( ThreadId tid, Addr a,
984                              Bool isAddrErr, UInt otag )
985{
986   MC_Error extra;
987   if (otag != 0) {
988      tl_assert(!isAddrErr);
989      tl_assert( MC_(clo_mc_level) == 3 );
990   }
991   if (!isAddrErr) {
992      tl_assert( MC_(clo_mc_level) >= 2 );
993   }
994   tl_assert(VG_INVALID_THREADID != tid);
995   extra.Err.User.isAddrErr = isAddrErr;
996   extra.Err.User.ai.tag    = Addr_Undescribed;
997   extra.Err.User.otag      = otag;
998   extra.Err.User.origin_ec = NULL;  /* Filled in later */
999   VG_(maybe_record_error)( tid, Err_User, a, /*s*/NULL, &extra );
1000}
1001
1002/*------------------------------------------------------------*/
1003/*--- Other error operations                               ---*/
1004/*------------------------------------------------------------*/
1005
1006/* Compare error contexts, to detect duplicates.  Note that if they
1007   are otherwise the same, the faulting addrs and associated rwoffsets
1008   are allowed to be different.  */
1009Bool MC_(eq_Error) ( VgRes res, Error* e1, Error* e2 )
1010{
1011   MC_Error* extra1 = VG_(get_error_extra)(e1);
1012   MC_Error* extra2 = VG_(get_error_extra)(e2);
1013
1014   /* Guaranteed by calling function */
1015   tl_assert(VG_(get_error_kind)(e1) == VG_(get_error_kind)(e2));
1016
1017   switch (VG_(get_error_kind)(e1)) {
1018      case Err_CoreMem: {
1019         Char *e1s, *e2s;
1020         e1s = VG_(get_error_string)(e1);
1021         e2s = VG_(get_error_string)(e2);
1022         if (e1s == e2s)                   return True;
1023         if (VG_STREQ(e1s, e2s))           return True;
1024         return False;
1025      }
1026
1027      case Err_RegParam:
1028         return VG_STREQ(VG_(get_error_string)(e1), VG_(get_error_string)(e2));
1029
1030      // Perhaps we should also check the addrinfo.akinds for equality.
1031      // That would result in more error reports, but only in cases where
1032      // a register contains uninitialised bytes and points to memory
1033      // containing uninitialised bytes.  Currently, the 2nd of those to be
1034      // detected won't be reported.  That is (nearly?) always the memory
1035      // error, which is good.
1036      case Err_MemParam:
1037         if (!VG_STREQ(VG_(get_error_string)(e1),
1038                       VG_(get_error_string)(e2))) return False;
1039         // fall through
1040      case Err_User:
1041         return ( extra1->Err.User.isAddrErr == extra2->Err.User.isAddrErr
1042                ? True : False );
1043
1044      case Err_Free:
1045      case Err_FreeMismatch:
1046      case Err_Jump:
1047      case Err_IllegalMempool:
1048      case Err_Overlap:
1049      case Err_Cond:
1050         return True;
1051
1052      case Err_Addr:
1053         return ( extra1->Err.Addr.szB == extra2->Err.Addr.szB
1054                ? True : False );
1055
1056      case Err_Value:
1057         return ( extra1->Err.Value.szB == extra2->Err.Value.szB
1058                ? True : False );
1059
1060      case Err_Leak:
1061         VG_(tool_panic)("Shouldn't get Err_Leak in mc_eq_Error,\n"
1062                         "since it's handled with VG_(unique_error)()!");
1063
1064      default:
1065         VG_(printf)("Error:\n  unknown error code %d\n",
1066                     VG_(get_error_kind)(e1));
1067         VG_(tool_panic)("unknown error code in mc_eq_Error");
1068   }
1069}
1070
1071/* Functions used when searching MC_Chunk lists */
1072static
1073Bool addr_is_in_MC_Chunk_default_REDZONE_SZB(MC_Chunk* mc, Addr a)
1074{
1075   return VG_(addr_is_in_block)( a, mc->data, mc->szB,
1076                                 MC_MALLOC_REDZONE_SZB );
1077}
1078static
1079Bool addr_is_in_MC_Chunk_with_REDZONE_SZB(MC_Chunk* mc, Addr a, SizeT rzB)
1080{
1081   return VG_(addr_is_in_block)( a, mc->data, mc->szB,
1082                                 rzB );
1083}
1084
1085// Forward declarations
1086static Bool client_block_maybe_describe( Addr a, AddrInfo* ai );
1087static Bool mempool_block_maybe_describe( Addr a, AddrInfo* ai );
1088
1089
1090/* Describe an address as best you can, for error messages,
1091   putting the result in ai. */
1092static void describe_addr ( Addr a, /*OUT*/AddrInfo* ai )
1093{
1094   MC_Chunk*  mc;
1095   ThreadId   tid;
1096   Addr       stack_min, stack_max;
1097   VgSectKind sect;
1098
1099   tl_assert(Addr_Undescribed == ai->tag);
1100
1101   /* -- Perhaps it's a user-named block? -- */
1102   if (client_block_maybe_describe( a, ai )) {
1103      return;
1104   }
1105   /* -- Perhaps it's in mempool block? -- */
1106   if (mempool_block_maybe_describe( a, ai )) {
1107      return;
1108   }
1109   /* -- Search for a recently freed block which might bracket it. -- */
1110   mc = MC_(get_freed_list_head)();
1111   while (mc) {
1112      if (addr_is_in_MC_Chunk_default_REDZONE_SZB(mc, a)) {
1113         ai->tag = Addr_Block;
1114         ai->Addr.Block.block_kind = Block_Freed;
1115         ai->Addr.Block.block_desc = "block";
1116         ai->Addr.Block.block_szB  = mc->szB;
1117         ai->Addr.Block.rwoffset   = (Word)a - (Word)mc->data;
1118         ai->Addr.Block.lastchange = mc->where;
1119         return;
1120      }
1121      mc = mc->next;
1122   }
1123   /* -- Search for a currently malloc'd block which might bracket it. -- */
1124   VG_(HT_ResetIter)(MC_(malloc_list));
1125   while ( (mc = VG_(HT_Next)(MC_(malloc_list))) ) {
1126      if (addr_is_in_MC_Chunk_default_REDZONE_SZB(mc, a)) {
1127         ai->tag = Addr_Block;
1128         ai->Addr.Block.block_kind = Block_Mallocd;
1129         ai->Addr.Block.block_desc = "block";
1130         ai->Addr.Block.block_szB  = mc->szB;
1131         ai->Addr.Block.rwoffset   = (Word)a - (Word)mc->data;
1132         ai->Addr.Block.lastchange = mc->where;
1133         return;
1134      }
1135   }
1136   /* -- Perhaps the variable type/location data describes it? -- */
1137   ai->Addr.Variable.descr1
1138      = VG_(newXA)( VG_(malloc), "mc.da.descr1",
1139                    VG_(free), sizeof(HChar) );
1140   ai->Addr.Variable.descr2
1141      = VG_(newXA)( VG_(malloc), "mc.da.descr2",
1142                    VG_(free), sizeof(HChar) );
1143
1144   (void) VG_(get_data_description)( ai->Addr.Variable.descr1,
1145                                     ai->Addr.Variable.descr2, a );
1146   /* If there's nothing in descr1/2, free them.  Why is it safe to to
1147      VG_(indexXA) at zero here?  Because VG_(get_data_description)
1148      guarantees to zero terminate descr1/2 regardless of the outcome
1149      of the call.  So there's always at least one element in each XA
1150      after the call.
1151   */
1152   if (0 == VG_(strlen)( VG_(indexXA)( ai->Addr.Variable.descr1, 0 ))) {
1153      VG_(deleteXA)( ai->Addr.Variable.descr1 );
1154      ai->Addr.Variable.descr1 = NULL;
1155   }
1156   if (0 == VG_(strlen)( VG_(indexXA)( ai->Addr.Variable.descr2, 0 ))) {
1157      VG_(deleteXA)( ai->Addr.Variable.descr2 );
1158      ai->Addr.Variable.descr2 = NULL;
1159   }
1160   /* Assume (assert) that VG_(get_data_description) fills in descr1
1161      before it fills in descr2 */
1162   if (ai->Addr.Variable.descr1 == NULL)
1163      tl_assert(ai->Addr.Variable.descr2 == NULL);
1164   /* So did we get lucky? */
1165   if (ai->Addr.Variable.descr1 != NULL) {
1166      ai->tag = Addr_Variable;
1167      return;
1168   }
1169   /* -- Have a look at the low level data symbols - perhaps it's in
1170      there. -- */
1171   VG_(memset)( &ai->Addr.DataSym.name,
1172                0, sizeof(ai->Addr.DataSym.name));
1173   if (VG_(get_datasym_and_offset)(
1174             a, &ai->Addr.DataSym.name[0],
1175             sizeof(ai->Addr.DataSym.name)-1,
1176             &ai->Addr.DataSym.offset )) {
1177      ai->tag = Addr_DataSym;
1178      tl_assert( ai->Addr.DataSym.name
1179                    [ sizeof(ai->Addr.DataSym.name)-1 ] == 0);
1180      return;
1181   }
1182   /* -- Perhaps it's on a thread's stack? -- */
1183   VG_(thread_stack_reset_iter)(&tid);
1184   while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) {
1185      if (stack_min - VG_STACK_REDZONE_SZB <= a && a <= stack_max) {
1186         ai->tag            = Addr_Stack;
1187         ai->Addr.Stack.tid = tid;
1188         return;
1189      }
1190   }
1191   /* -- last ditch attempt at classification -- */
1192   tl_assert( sizeof(ai->Addr.SectKind.objname) > 4 );
1193   VG_(memset)( &ai->Addr.SectKind.objname,
1194                0, sizeof(ai->Addr.SectKind.objname));
1195   VG_(strcpy)( ai->Addr.SectKind.objname, "???" );
1196   sect = VG_(DebugInfo_sect_kind)( &ai->Addr.SectKind.objname[0],
1197                                    sizeof(ai->Addr.SectKind.objname)-1, a);
1198   if (sect != Vg_SectUnknown) {
1199      ai->tag = Addr_SectKind;
1200      ai->Addr.SectKind.kind = sect;
1201      tl_assert( ai->Addr.SectKind.objname
1202                    [ sizeof(ai->Addr.SectKind.objname)-1 ] == 0);
1203      return;
1204   }
1205   /* -- Clueless ... -- */
1206   ai->tag = Addr_Unknown;
1207   return;
1208}
1209
1210/* Fill in *origin_ec as specified by otag, or NULL it out if otag
1211   does not refer to a known origin. */
1212static void update_origin ( /*OUT*/ExeContext** origin_ec,
1213                            UInt otag )
1214{
1215   UInt ecu = otag & ~3;
1216   *origin_ec = NULL;
1217   if (VG_(is_plausible_ECU)(ecu)) {
1218      *origin_ec = VG_(get_ExeContext_from_ECU)( ecu );
1219   }
1220}
1221
1222/* Updates the copy with address info if necessary (but not for all errors). */
1223UInt MC_(update_Error_extra)( Error* err )
1224{
1225   MC_Error* extra = VG_(get_error_extra)(err);
1226
1227   switch (VG_(get_error_kind)(err)) {
1228   // These ones don't have addresses associated with them, and so don't
1229   // need any updating.
1230   case Err_CoreMem:
1231   //case Err_Value:
1232   //case Err_Cond:
1233   case Err_Overlap:
1234   // For Err_Leaks the returned size does not matter -- they are always
1235   // shown with VG_(unique_error)() so they 'extra' not copied.  But
1236   // we make it consistent with the others.
1237   case Err_Leak:
1238      return sizeof(MC_Error);
1239
1240   // For value errors, get the ExeContext corresponding to the
1241   // origin tag.  Note that it is a kludge to assume that
1242   // a length-1 trace indicates a stack origin.  FIXME.
1243   case Err_Value:
1244      update_origin( &extra->Err.Value.origin_ec,
1245                     extra->Err.Value.otag );
1246      return sizeof(MC_Error);
1247   case Err_Cond:
1248      update_origin( &extra->Err.Cond.origin_ec,
1249                     extra->Err.Cond.otag );
1250      return sizeof(MC_Error);
1251   case Err_RegParam:
1252      update_origin( &extra->Err.RegParam.origin_ec,
1253                     extra->Err.RegParam.otag );
1254      return sizeof(MC_Error);
1255
1256   // These ones always involve a memory address.
1257   case Err_Addr:
1258      describe_addr ( VG_(get_error_address)(err),
1259                      &extra->Err.Addr.ai );
1260      return sizeof(MC_Error);
1261   case Err_MemParam:
1262      describe_addr ( VG_(get_error_address)(err),
1263                      &extra->Err.MemParam.ai );
1264      update_origin( &extra->Err.MemParam.origin_ec,
1265                     extra->Err.MemParam.otag );
1266      return sizeof(MC_Error);
1267   case Err_Jump:
1268      describe_addr ( VG_(get_error_address)(err),
1269                      &extra->Err.Jump.ai );
1270      return sizeof(MC_Error);
1271   case Err_User:
1272      describe_addr ( VG_(get_error_address)(err),
1273                      &extra->Err.User.ai );
1274      update_origin( &extra->Err.User.origin_ec,
1275                     extra->Err.User.otag );
1276      return sizeof(MC_Error);
1277   case Err_Free:
1278      describe_addr ( VG_(get_error_address)(err),
1279                      &extra->Err.Free.ai );
1280      return sizeof(MC_Error);
1281   case Err_IllegalMempool:
1282      describe_addr ( VG_(get_error_address)(err),
1283                      &extra->Err.IllegalMempool.ai );
1284      return sizeof(MC_Error);
1285
1286   // Err_FreeMismatches have already had their address described;  this is
1287   // possible because we have the MC_Chunk on hand when the error is
1288   // detected.  However, the address may be part of a user block, and if so
1289   // we override the pre-determined description with a user block one.
1290   case Err_FreeMismatch: {
1291      tl_assert(extra && Block_Mallocd ==
1292                extra->Err.FreeMismatch.ai.Addr.Block.block_kind);
1293      (void)client_block_maybe_describe( VG_(get_error_address)(err),
1294                                        &extra->Err.FreeMismatch.ai );
1295      return sizeof(MC_Error);
1296   }
1297
1298   default: VG_(tool_panic)("mc_update_extra: bad errkind");
1299   }
1300}
1301
1302
1303static Bool client_block_maybe_describe( Addr a,
1304                                         /*OUT*/AddrInfo* ai )
1305{
1306   UWord      i;
1307   CGenBlock* cgbs = NULL;
1308   UWord      cgb_used = 0;
1309
1310   MC_(get_ClientBlock_array)( &cgbs, &cgb_used );
1311   if (cgbs == NULL)
1312      tl_assert(cgb_used == 0);
1313
1314   /* Perhaps it's a general block ? */
1315   for (i = 0; i < cgb_used; i++) {
1316      if (cgbs[i].start == 0 && cgbs[i].size == 0)
1317         continue;
1318      // Use zero as the redzone for client blocks.
1319      if (VG_(addr_is_in_block)(a, cgbs[i].start, cgbs[i].size, 0)) {
1320         ai->tag = Addr_Block;
1321         ai->Addr.Block.block_kind = Block_UserG;
1322         ai->Addr.Block.block_desc = cgbs[i].desc;
1323         ai->Addr.Block.block_szB  = cgbs[i].size;
1324         ai->Addr.Block.rwoffset   = (Word)(a) - (Word)(cgbs[i].start);
1325         ai->Addr.Block.lastchange = cgbs[i].where;
1326         return True;
1327      }
1328   }
1329   return False;
1330}
1331
1332
1333static Bool mempool_block_maybe_describe( Addr a,
1334                                          /*OUT*/AddrInfo* ai )
1335{
1336   MC_Mempool* mp;
1337   tl_assert( MC_(mempool_list) );
1338
1339   VG_(HT_ResetIter)( MC_(mempool_list) );
1340   while ( (mp = VG_(HT_Next)(MC_(mempool_list))) ) {
1341      if (mp->chunks != NULL) {
1342         MC_Chunk* mc;
1343         VG_(HT_ResetIter)(mp->chunks);
1344         while ( (mc = VG_(HT_Next)(mp->chunks)) ) {
1345            if (addr_is_in_MC_Chunk_with_REDZONE_SZB(mc, a, mp->rzB)) {
1346               ai->tag = Addr_Block;
1347               ai->Addr.Block.block_kind = Block_MempoolChunk;
1348               ai->Addr.Block.block_desc = "block";
1349               ai->Addr.Block.block_szB  = mc->szB;
1350               ai->Addr.Block.rwoffset   = (Word)a - (Word)mc->data;
1351               ai->Addr.Block.lastchange = mc->where;
1352               return True;
1353            }
1354         }
1355      }
1356   }
1357   return False;
1358}
1359
1360
1361/*------------------------------------------------------------*/
1362/*--- Suppressions                                         ---*/
1363/*------------------------------------------------------------*/
1364
1365typedef
1366   enum {
1367      ParamSupp,     // Bad syscall params
1368      UserSupp,      // Errors arising from client-request checks
1369      CoreMemSupp,   // Memory errors in core (pthread ops, signal handling)
1370
1371      // Undefined value errors of given size
1372      Value1Supp, Value2Supp, Value4Supp, Value8Supp, Value16Supp,
1373
1374      // Undefined value error in conditional.
1375      CondSupp,
1376
1377      // Unaddressable read/write attempt at given size
1378      Addr1Supp, Addr2Supp, Addr4Supp, Addr8Supp, Addr16Supp,
1379
1380      JumpSupp,      // Jump to unaddressable target
1381      FreeSupp,      // Invalid or mismatching free
1382      OverlapSupp,   // Overlapping blocks in memcpy(), strcpy(), etc
1383      LeakSupp,      // Something to be suppressed in a leak check.
1384      MempoolSupp,   // Memory pool suppression.
1385   }
1386   MC_SuppKind;
1387
1388Bool MC_(is_recognised_suppression) ( Char* name, Supp* su )
1389{
1390   SuppKind skind;
1391
1392   if      (VG_STREQ(name, "Param"))   skind = ParamSupp;
1393   else if (VG_STREQ(name, "User"))    skind = UserSupp;
1394   else if (VG_STREQ(name, "CoreMem")) skind = CoreMemSupp;
1395   else if (VG_STREQ(name, "Addr1"))   skind = Addr1Supp;
1396   else if (VG_STREQ(name, "Addr2"))   skind = Addr2Supp;
1397   else if (VG_STREQ(name, "Addr4"))   skind = Addr4Supp;
1398   else if (VG_STREQ(name, "Addr8"))   skind = Addr8Supp;
1399   else if (VG_STREQ(name, "Addr16"))  skind = Addr16Supp;
1400   else if (VG_STREQ(name, "Jump"))    skind = JumpSupp;
1401   else if (VG_STREQ(name, "Free"))    skind = FreeSupp;
1402   else if (VG_STREQ(name, "Leak"))    skind = LeakSupp;
1403   else if (VG_STREQ(name, "Overlap")) skind = OverlapSupp;
1404   else if (VG_STREQ(name, "Mempool")) skind = MempoolSupp;
1405   else if (VG_STREQ(name, "Cond"))    skind = CondSupp;
1406   else if (VG_STREQ(name, "Value0"))  skind = CondSupp; /* backwards compat */
1407   else if (VG_STREQ(name, "Value1"))  skind = Value1Supp;
1408   else if (VG_STREQ(name, "Value2"))  skind = Value2Supp;
1409   else if (VG_STREQ(name, "Value4"))  skind = Value4Supp;
1410   else if (VG_STREQ(name, "Value8"))  skind = Value8Supp;
1411   else if (VG_STREQ(name, "Value16")) skind = Value16Supp;
1412   else
1413      return False;
1414
1415   VG_(set_supp_kind)(su, skind);
1416   return True;
1417}
1418
1419Bool MC_(read_extra_suppression_info) ( Int fd, Char** bufpp,
1420                                        SizeT* nBufp, Supp *su )
1421{
1422   Bool eof;
1423
1424   if (VG_(get_supp_kind)(su) == ParamSupp) {
1425      eof = VG_(get_line) ( fd, bufpp, nBufp, NULL );
1426      if (eof) return False;
1427      VG_(set_supp_string)(su, VG_(strdup)("mc.resi.1", *bufpp));
1428   }
1429   return True;
1430}
1431
1432Bool MC_(error_matches_suppression) ( Error* err, Supp* su )
1433{
1434   Int       su_szB;
1435   MC_Error* extra = VG_(get_error_extra)(err);
1436   ErrorKind ekind = VG_(get_error_kind )(err);
1437
1438   switch (VG_(get_supp_kind)(su)) {
1439      case ParamSupp:
1440         return ((ekind == Err_RegParam || ekind == Err_MemParam)
1441              && VG_STREQ(VG_(get_error_string)(err),
1442                          VG_(get_supp_string)(su)));
1443
1444      case UserSupp:
1445         return (ekind == Err_User);
1446
1447      case CoreMemSupp:
1448         return (ekind == Err_CoreMem
1449              && VG_STREQ(VG_(get_error_string)(err),
1450                          VG_(get_supp_string)(su)));
1451
1452      case Value1Supp: su_szB = 1; goto value_case;
1453      case Value2Supp: su_szB = 2; goto value_case;
1454      case Value4Supp: su_szB = 4; goto value_case;
1455      case Value8Supp: su_szB = 8; goto value_case;
1456      case Value16Supp:su_szB =16; goto value_case;
1457      value_case:
1458         return (ekind == Err_Value && extra->Err.Value.szB == su_szB);
1459
1460      case CondSupp:
1461         return (ekind == Err_Cond);
1462
1463      case Addr1Supp: su_szB = 1; goto addr_case;
1464      case Addr2Supp: su_szB = 2; goto addr_case;
1465      case Addr4Supp: su_szB = 4; goto addr_case;
1466      case Addr8Supp: su_szB = 8; goto addr_case;
1467      case Addr16Supp:su_szB =16; goto addr_case;
1468      addr_case:
1469         return (ekind == Err_Addr && extra->Err.Addr.szB == su_szB);
1470
1471      case JumpSupp:
1472         return (ekind == Err_Jump);
1473
1474      case FreeSupp:
1475         return (ekind == Err_Free || ekind == Err_FreeMismatch);
1476
1477      case OverlapSupp:
1478         return (ekind == Err_Overlap);
1479
1480      case LeakSupp:
1481         return (ekind == Err_Leak);
1482
1483      case MempoolSupp:
1484         return (ekind == Err_IllegalMempool);
1485
1486      default:
1487         VG_(printf)("Error:\n"
1488                     "  unknown suppression type %d\n",
1489                     VG_(get_supp_kind)(su));
1490         VG_(tool_panic)("unknown suppression type in "
1491                         "MC_(error_matches_suppression)");
1492   }
1493}
1494
1495Char* MC_(get_error_name) ( Error* err )
1496{
1497   switch (VG_(get_error_kind)(err)) {
1498   case Err_RegParam:       return "Param";
1499   case Err_MemParam:       return "Param";
1500   case Err_User:           return "User";
1501   case Err_FreeMismatch:   return "Free";
1502   case Err_IllegalMempool: return "Mempool";
1503   case Err_Free:           return "Free";
1504   case Err_Jump:           return "Jump";
1505   case Err_CoreMem:        return "CoreMem";
1506   case Err_Overlap:        return "Overlap";
1507   case Err_Leak:           return "Leak";
1508   case Err_Cond:           return "Cond";
1509   case Err_Addr: {
1510      MC_Error* extra = VG_(get_error_extra)(err);
1511      switch ( extra->Err.Addr.szB ) {
1512      case 1:               return "Addr1";
1513      case 2:               return "Addr2";
1514      case 4:               return "Addr4";
1515      case 8:               return "Addr8";
1516      case 16:              return "Addr16";
1517      default:              VG_(tool_panic)("unexpected size for Addr");
1518      }
1519   }
1520   case Err_Value: {
1521      MC_Error* extra = VG_(get_error_extra)(err);
1522      switch ( extra->Err.Value.szB ) {
1523      case 1:               return "Value1";
1524      case 2:               return "Value2";
1525      case 4:               return "Value4";
1526      case 8:               return "Value8";
1527      case 16:              return "Value16";
1528      default:              VG_(tool_panic)("unexpected size for Value");
1529      }
1530   }
1531   default:                 VG_(tool_panic)("get_error_name: unexpected type");
1532   }
1533}
1534
1535Bool MC_(get_extra_suppression_info) ( Error* err,
1536                                       /*OUT*/Char* buf, Int nBuf )
1537{
1538   ErrorKind ekind = VG_(get_error_kind )(err);
1539   tl_assert(buf);
1540   tl_assert(nBuf >= 16); // stay sane
1541   if (Err_RegParam == ekind || Err_MemParam == ekind) {
1542      Char* errstr = VG_(get_error_string)(err);
1543      tl_assert(errstr);
1544      VG_(snprintf)(buf, nBuf-1, "%s", errstr);
1545      return True;
1546   } else {
1547      return False;
1548   }
1549}
1550
1551
1552/*--------------------------------------------------------------------*/
1553/*--- end                                              mc_errors.c ---*/
1554/*--------------------------------------------------------------------*/
1555