1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Assertions and panics.                        m_libcassert.c ---*/
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This file is part of Valgrind, a dynamic binary instrumentation
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   framework.
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
10436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   Copyright (C) 2000-2013 Julian Seward
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      jseward@acm.org
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This program is free software; you can redistribute it and/or
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   modify it under the terms of the GNU General Public License as
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   published by the Free Software Foundation; either version 2 of the
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   License, or (at your option) any later version.
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This program is distributed in the hope that it will be useful, but
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   WITHOUT ANY WARRANTY; without even the implied warranty of
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   General Public License for more details.
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   You should have received a copy of the GNU General Public License
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   along with this program; if not, write to the Free Software
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   02111-1307, USA.
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The GNU General Public License is contained in the file COPYING.
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_basics.h"
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_vki.h"
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_vkiscnums.h"
34b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_libcsetjmp.h"    // to keep threadstate.h happy
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_threadstate.h"
36eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include "pub_core_gdbserver.h"
37eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#include "pub_core_aspacemgr.h"
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcbase.h"
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcassert.h"
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcprint.h"
41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcproc.h"      // For VG_(gettid)()
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_stacktrace.h"
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_syscall.h"
44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_tooliface.h"     // For VG_(details).{name,bug_reports_to}
45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_options.h"       // For VG_(clo_xml)
46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------------------------------------------------------------
48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Assertery.
49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ------------------------------------------------------------------ */
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGP_x86_linux) || defined(VGP_x86_darwin)
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define GET_STARTREGS(srP)                              \
53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { UInt eip, esp, ebp;                               \
54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        __asm__ __volatile__(                             \
55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "call 0f;"                                     \
56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "0: popl %0;"                                  \
57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "movl %%esp, %1;"                              \
58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "movl %%ebp, %2;"                              \
59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : "=r" (eip), "=r" (esp), "=r" (ebp)           \
60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : /* reads none */                             \
61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : "memory"                                     \
62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        );                                                \
63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->r_pc = (ULong)eip;                         \
64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->r_sp = (ULong)esp;                         \
65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->misc.X86.r_ebp = ebp;                      \
66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGP_amd64_linux) || defined(VGP_amd64_darwin)
68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define GET_STARTREGS(srP)                              \
69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ULong rip, rsp, rbp;                              \
70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        __asm__ __volatile__(                             \
71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "leaq 0(%%rip), %0;"                           \
72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "movq %%rsp, %1;"                              \
73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "movq %%rbp, %2;"                              \
74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : "=r" (rip), "=r" (rsp), "=r" (rbp)           \
75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : /* reads none */                             \
76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : "memory"                                     \
77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        );                                                \
78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->r_pc = rip;                                \
79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->r_sp = rsp;                                \
80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->misc.AMD64.r_rbp = rbp;                    \
81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
82b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGP_ppc32_linux)
83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define GET_STARTREGS(srP)                              \
84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { UInt cia, r1, lr;                                 \
85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        __asm__ __volatile__(                             \
86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "mflr 0;"                   /* r0 = lr */      \
87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "bl m_libcassert_get_ip;"   /* lr = pc */      \
88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "m_libcassert_get_ip:\n"                       \
89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "mflr %0;"                  /* %0 = pc */      \
90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "mtlr 0;"                   /* restore lr */   \
91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "mr %1,1;"                  /* %1 = r1 */      \
92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "mr %2,0;"                  /* %2 = lr */      \
93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : "=r" (cia), "=r" (r1), "=r" (lr)             \
94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : /* reads none */                             \
95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : "r0" /* trashed */                           \
96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        );                                                \
97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->r_pc = (ULong)cia;                         \
98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->r_sp = (ULong)r1;                          \
99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->misc.PPC32.r_lr = lr;                      \
100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
101b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGP_ppc64_linux)
102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define GET_STARTREGS(srP)                              \
103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { ULong cia, r1, lr;                                \
104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        __asm__ __volatile__(                             \
105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "mflr 0;"                   /* r0 = lr */      \
106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "bl .m_libcassert_get_ip;"  /* lr = pc */      \
107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           ".m_libcassert_get_ip:\n"                      \
108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "mflr %0;"                  /* %0 = pc */      \
109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "mtlr 0;"                   /* restore lr */   \
110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "mr %1,1;"                  /* %1 = r1 */      \
111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "mr %2,0;"                  /* %2 = lr */      \
112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : "=r" (cia), "=r" (r1), "=r" (lr)             \
113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : /* reads none */                             \
114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : "r0" /* trashed */                           \
115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        );                                                \
116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->r_pc = cia;                                \
117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->r_sp = r1;                                 \
118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->misc.PPC64.r_lr = lr;                      \
119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGP_arm_linux)
121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define GET_STARTREGS(srP)                              \
122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { UInt block[6];                                    \
123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        __asm__ __volatile__(                             \
124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "str r15, [%0, #+0];"                          \
125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "str r14, [%0, #+4];"                          \
126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "str r13, [%0, #+8];"                          \
127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "str r12, [%0, #+12];"                         \
128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "str r11, [%0, #+16];"                         \
129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "str r7,  [%0, #+20];"                         \
130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : /* out */                                    \
131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : /* in */ "r"(&block[0])                      \
132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           : /* trash */ "memory"                         \
133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        );                                                \
134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->r_pc = block[0] - 8;                       \
135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->r_sp = block[1];                           \
136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->misc.ARM.r14 = block[2];                   \
137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->misc.ARM.r12 = block[3];                   \
138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->misc.ARM.r11 = block[4];                   \
139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (srP)->misc.ARM.r7  = block[5];                   \
140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
141436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#elif defined(VGP_arm64_linux)
142436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#  define GET_STARTREGS(srP)                              \
143436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      { ULong block[4];                                   \
144436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        __asm__ __volatile__(                             \
145436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov           "adr x19, 0;"                                  \
146436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov           "str x19, [%0, #+0];"   /* pc */               \
147436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov           "mov x19, sp;"                                 \
148436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov           "str x19, [%0, #+8];"   /* sp */               \
149436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov           "str x29, [%0, #+16];"  /* fp */               \
150436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov           "str x30, [%0, #+24];"  /* lr */               \
151436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov           : /* out */                                    \
152436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov           : /* in */ "r"(&block[0])                      \
153436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov           : /* trash */ "memory","x19"                   \
154436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        );                                                \
155436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        (srP)->r_pc = block[0];                           \
156436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        (srP)->r_sp = block[1];                           \
157436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        (srP)->misc.ARM64.x29 = block[2];                 \
158436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        (srP)->misc.ARM64.x30 = block[3];                 \
159436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      }
160b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGP_s390x_linux)
161b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#  define GET_STARTREGS(srP)                              \
162b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      { ULong ia, sp, fp, lr;                             \
163b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        __asm__ __volatile__(                             \
164b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           "bras %0,0f;"                                  \
165b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           "0: lgr %1,15;"                                \
166b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           "lgr %2,11;"                                   \
167b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           "lgr %3,14;"                                   \
168b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           : "=r" (ia), "=r" (sp),"=r" (fp),"=r" (lr)     \
169b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           /* no read & clobber */                        \
170b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        );                                                \
171b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        (srP)->r_pc = ia;                                 \
172b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        (srP)->r_sp = sp;                                 \
173b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        (srP)->misc.S390X.r_fp = fp;                      \
174b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        (srP)->misc.S390X.r_lr = lr;                      \
175b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
176663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#elif defined(VGP_mips32_linux)
177663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#  define GET_STARTREGS(srP)                              \
178663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      { UInt pc, sp, fp, ra, gp;                          \
179663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      asm("move $8, $31;"             /* t0 = ra */       \
180663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          "bal m_libcassert_get_ip;"  /* ra = pc */       \
181663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          "m_libcassert_get_ip:\n"                        \
182663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          "move %0, $31;"                                 \
183663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          "move $31, $8;"             /* restore lr */    \
184663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          "move %1, $29;"                                 \
185663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          "move %2, $30;"                                 \
186663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          "move %3, $31;"                                 \
187663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          "move %4, $28;"                                 \
188663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          : "=r" (pc),                                    \
189663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            "=r" (sp),                                    \
190663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            "=r" (fp),                                    \
191663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            "=r" (ra),                                    \
192663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            "=r" (gp)                                     \
193663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          : /* reads none */                              \
194663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          : "$8" /* trashed */ );                         \
195663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        (srP)->r_pc = (ULong)pc - 8;                      \
196663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        (srP)->r_sp = (ULong)sp;                          \
197663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        (srP)->misc.MIPS32.r30 = (ULong)fp;               \
198663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        (srP)->misc.MIPS32.r31 = (ULong)ra;               \
199663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        (srP)->misc.MIPS32.r28 = (ULong)gp;               \
200663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      }
201436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#elif defined(VGP_mips64_linux)
202436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#  define GET_STARTREGS(srP)                              \
203436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      { ULong pc, sp, fp, ra, gp;                          \
204436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      asm("move $8, $31;"             /* t0 = ra */       \
205436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov          "bal m_libcassert_get_ip;"  /* ra = pc */       \
206436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov          "m_libcassert_get_ip:\n"                        \
207436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov          "move %0, $31;"                                 \
208436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov          "move $31, $8;"             /* restore lr */    \
209436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov          "move %1, $29;"                                 \
210436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov          "move %2, $30;"                                 \
211436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov          "move %3, $31;"                                 \
212436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov          "move %4, $28;"                                 \
213436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov          : "=r" (pc),                                    \
214436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            "=r" (sp),                                    \
215436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            "=r" (fp),                                    \
216436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            "=r" (ra),                                    \
217436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            "=r" (gp)                                     \
218436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov          : /* reads none */                              \
219436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov          : "$8" /* trashed */ );                         \
220436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        (srP)->r_pc = (ULong)pc - 8;                      \
221436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        (srP)->r_sp = (ULong)sp;                          \
222436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        (srP)->misc.MIPS64.r30 = (ULong)fp;               \
223436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        (srP)->misc.MIPS64.r31 = (ULong)ra;               \
224436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov        (srP)->misc.MIPS64.r28 = (ULong)gp;               \
225436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      }
226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  error Unknown platform
228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define BACKTRACE_DEPTH    100         // nice and deep!
231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
232eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov__attribute__ ((__noreturn__))
233eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovstatic void exit_wrk( Int status, Bool gdbserver_call_allowed)
234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
235eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   static Bool exit_called = False;
236eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   // avoid recursive exit during gdbserver call.
237eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
238eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   if (gdbserver_call_allowed && !exit_called) {
239eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      const ThreadId atid = 1; // Arbitrary tid used to call/terminate gdbsrv.
240eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      exit_called = True;
241eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      if (status != 0 && VG_(gdbserver_stop_at) (VgdbStopAt_ValgrindAbExit)) {
242eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         if (VG_(gdbserver_init_done)()) {
243eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            VG_(umsg)("(action at valgrind abnormal exit) vgdb me ... \n");
244eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            VG_(gdbserver) (atid);
245eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         } else {
246eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            VG_(umsg)("(action at valgrind abnormal exit) "
247eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                      "Early valgrind exit : vgdb not yet usable\n");
248eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         }
249eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      }
250eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      if (VG_(gdbserver_init_done)()) {
251eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         // Always terminate the gdbserver when Valgrind exits, so as
252eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         // to e.g. cleanup the FIFOs.
253eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         VG_(gdbserver_exit) (atid,
254eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                              status == 0 ? VgSrc_ExitProcess : VgSrc_FatalSig);
255eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      }
256eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   }
257eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   exit_called = True;
258eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_linux)
260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (void)VG_(do_syscall1)(__NR_exit_group, status );
261b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGO_darwin)
262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (void)VG_(do_syscall1)(__NR_exit, status );
263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  error Unknown OS
265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*NOTREACHED*/
267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // We really shouldn't reach here.  Just in case we do, use some very crude
268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // methods to force abort
269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   __builtin_trap();
270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *(volatile Int*)0 = 'x';
271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
273eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov/* Pull down the entire world */
274eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovvoid VG_(exit)( Int status )
275eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov{
276eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   exit_wrk (status, True);
277eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov}
278eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
279eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov/* Pull down the entire world */
280eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovvoid VG_(client_exit)( Int status )
281eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov{
282eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   exit_wrk (status, False);
283eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov}
284eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
285eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Print the scheduler status.
287eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovstatic void show_sched_status_wrk ( Bool host_stacktrace,
288eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                                    Bool valgrind_stack_usage,
289eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                                    Bool exited_threads,
290eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                                    UnwindStartRegs* startRegsIN)
291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int i;
293eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   if (host_stacktrace) {
294eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      const Bool save_clo_xml = VG_(clo_xml);
295eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      Addr stacktop;
296eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      Addr ips[BACKTRACE_DEPTH];
297eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      Int  n_ips;
298eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      ThreadState *tst
299eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         = VG_(get_ThreadState)( VG_(lwpid_to_vgtid)( VG_(gettid)() ) );
300eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
301eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      // If necessary, fake up an ExeContext which is of our actual real CPU
302eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      // state.  Could cause problems if we got the panic/exception within the
303eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      // execontext/stack dump/symtab code.  But it's better than nothing.
304eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      UnwindStartRegs startRegs;
305eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      VG_(memset)(&startRegs, 0, sizeof(startRegs));
306eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
307eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      if (startRegsIN == NULL) {
308eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         GET_STARTREGS(&startRegs);
309eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      } else {
310eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         startRegs = *startRegsIN;
311eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      }
312eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
313eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      stacktop = tst->os_state.valgrind_stack_init_SP;
314eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
315eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      n_ips =
316eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         VG_(get_StackTrace_wrk)(
317eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            0/*tid is unknown*/,
318eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            ips, BACKTRACE_DEPTH,
319eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            NULL/*array to dump SP values in*/,
320eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            NULL/*array to dump FP values in*/,
321eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov            &startRegs, stacktop
322eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         );
323eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      VG_(printf)("\nhost stacktrace:\n");
324eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      VG_(clo_xml) = False;
325eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      VG_(pp_StackTrace) (ips, n_ips);
326eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      VG_(clo_xml) = save_clo_xml;
327eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   }
328eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("\nsched status:\n");
330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("  running_tid=%d\n", VG_(get_running_tid)());
331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 1; i < VG_N_THREADS; i++) {
332eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      VgStack* stack
333eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         = (VgStack*)VG_(threads)[i].os_state.valgrind_stack_base;
334eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      /* If a thread slot was never used (yet), valgrind_stack_base is 0.
335eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         If a thread slot is used by a thread or was used by a thread which
336eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         has exited, then valgrind_stack_base points to the stack base. */
337eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      if (VG_(threads)[i].status == VgTs_Empty
338eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov          && (!exited_threads || stack == 0)) continue;
339eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      VG_(printf)("\nThread %d: status = %s\n", i,
340eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                  VG_(name_of_ThreadStatus)(VG_(threads)[i].status) );
341eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      if (VG_(threads)[i].status != VgTs_Empty)
342eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov         VG_(get_and_pp_StackTrace)( i, BACKTRACE_DEPTH );
343eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov      if (valgrind_stack_usage && stack != 0)
344eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov          VG_(printf)("valgrind stack top usage: %ld of %ld\n",
345eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                      VG_STACK_ACTIVE_SZB
346eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                      - VG_(am_get_VgStack_unused_szB)(stack,
347eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                                                       VG_STACK_ACTIVE_SZB),
348eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                      (SizeT) VG_STACK_ACTIVE_SZB);
349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("\n");
351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
353eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovvoid VG_(show_sched_status) ( Bool host_stacktrace,
354eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                              Bool valgrind_stack_usage,
355eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                              Bool exited_threads)
356eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov{
357eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   show_sched_status_wrk (host_stacktrace,
358eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                          valgrind_stack_usage,
359eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                          exited_threads,
360eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                          NULL);
361eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov}
362eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov
363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__ ((noreturn))
364436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic void report_and_quit ( const HChar* report,
365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              UnwindStartRegs* startRegsIN )
366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
367eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   show_sched_status_wrk (True,  // host_stacktrace
368eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                          False, // valgrind_stack_usage
369eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                          False, // exited_threads
370eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                          startRegsIN);
371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)(
372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "\n"
373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "Note: see also the FAQ in the source distribution.\n"
374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "It contains workarounds to several common problems.\n"
375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "In particular, if Valgrind aborted or crashed after\n"
376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "identifying problems in your program, there's a good chance\n"
377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "that fixing those problems will prevent Valgrind aborting or\n"
378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "crashing, especially if it happened in m_mallocfree.c.\n"
379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "\n"
380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "If that doesn't help, please report this bug to: %s\n\n"
381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "In the bug report, send all the above text, the valgrind\n"
382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "version, and what OS and version you are using.  Thanks.\n\n",
383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      report);
384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(exit)(1);
385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
387436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid VG_(assert_fail) ( Bool isCore, const HChar* expr, const HChar* file,
388436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                        Int line, const HChar* fn, const HChar* format, ... )
389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   va_list vargs;
391436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   HChar buf[512];
392436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   const HChar* component;
393436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   const HChar* bugs_to;
394436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   UInt written;
395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   static Bool entered = False;
397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (entered)
398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(exit)(2);
399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   entered = True;
400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   va_start(vargs, format);
402436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   written = VG_(vsnprintf) ( buf, sizeof(buf), format, vargs );
403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   va_end(vargs);
404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
405436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (written >= sizeof(buf)) {
406436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      VG_(printf)("\nvalgrind: %s: buf is too small, sizeof(buf) = %u, "
407436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                  "written = %d\n", __func__, (unsigned)sizeof(buf), written);
408436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
409436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (isCore) {
411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      component = "valgrind";
412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      bugs_to   = VG_BUGS_TO;
413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      component = VG_(details).name;
415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      bugs_to   = VG_(details).bug_reports_to;
416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (VG_(clo_xml))
419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf_xml)("</valgrindoutput>\n");
420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   // Treat vg_assert2(0, "foo") specially, as a panicky abort
422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (VG_STREQ(expr, "0")) {
423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("\n%s: %s:%d (%s): the 'impossible' happened.\n",
424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  component, file, line, fn );
425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("\n%s: %s:%d (%s): Assertion '%s' failed.\n",
427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  component, file, line, fn, expr );
428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!VG_STREQ(buf, ""))
430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("%s: %s\n", component, buf );
431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   report_and_quit(bugs_to, NULL);
433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__ ((noreturn))
436436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic void panic ( const HChar* name, const HChar* report, const HChar* str,
437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    UnwindStartRegs* startRegs )
438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (VG_(clo_xml))
440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf_xml)("</valgrindoutput>\n");
441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("\n%s: the 'impossible' happened:\n   %s\n", name, str);
442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   report_and_quit(report, startRegs);
443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
445436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid VG_(core_panic_at) ( const HChar* str, UnwindStartRegs* startRegs )
446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   panic("valgrind", VG_BUGS_TO, str, startRegs);
448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
450436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid VG_(core_panic) ( const HChar* str )
451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(core_panic_at)(str, NULL);
453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
455436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid VG_(tool_panic) ( const HChar* str )
456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   panic(VG_(details).name, VG_(details).bug_reports_to, str, NULL);
458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Print some helpful-ish text about unimplemented things, and give up. */
461436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid VG_(unimplemented) ( const HChar* msg )
462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (VG_(clo_xml))
464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf_xml)("</valgrindoutput>\n");
465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(umsg)("\n");
466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(umsg)("Valgrind detected that your program requires\n");
467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(umsg)("the following unimplemented functionality:\n");
468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(umsg)("   %s\n", msg);
469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(umsg)("This may be because the functionality is hard to implement,\n");
470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(umsg)("or because no reasonable program would behave this way,\n");
471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(umsg)("or because nobody has yet needed it.  "
472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             "In any case, let us know at\n");
473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(umsg)("%s and/or try to work around the problem, if you can.\n",
474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             VG_BUGS_TO);
475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(umsg)("\n");
476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(umsg)("Valgrind has to exit now.  Sorry.  Bye!\n");
477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(umsg)("\n");
478eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov   VG_(show_sched_status)(False,  // host_stacktrace
479eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                          False,  // valgrind_stack_usage
480eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov                          False); // exited_threads
481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(exit)(1);
482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- end                                                          ---*/
486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
487