blob: 293a02c32d68ac6ad493deba6a912b65750d6cdc [file] [log] [blame]
njn810086f2002-11-14 12:42:47 +00001
2/*--------------------------------------------------------------------*/
3/*--- Stuff relating to skin data structures. ---*/
4/*--- vg_needs.c ---*/
5/*--------------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, an extensible x86 protected-mode
9 emulator for monitoring program execution on x86-Unixes.
10
11 Copyright (C) 2000-2002 Nicholas Nethercote
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 "vg_include.h"
33
34
35/* ---------------------------------------------------------------------
36 Skin data structure initialisation
37 ------------------------------------------------------------------ */
38
39/* Init with default values. */
40VgDetails VG_(details) = {
sewardjc0d8f682002-11-30 00:49:43 +000041 .name = NULL,
42 .version = NULL,
43 .description = NULL,
44 .copyright_author = NULL,
45 .bug_reports_to = NULL,
njn120281f2003-02-03 12:20:07 +000046 .avg_translation_sizeB = VG_DEFAULT_TRANS_SIZEB,
njn810086f2002-11-14 12:42:47 +000047};
48
49VgNeeds VG_(needs) = {
50 .core_errors = False,
51 .skin_errors = False,
52 .libc_freeres = False,
53 .sizeof_shadow_block = 0,
54 .basic_block_discards = False,
55 .shadow_regs = False,
56 .command_line_options = False,
57 .client_requests = False,
58 .extended_UCode = False,
59 .syscall_wrapper = False,
60 .alternative_free = False,
61 .sanity_checks = False,
62 .data_syms = False,
63};
64
65VgTrackEvents VG_(track_events) = {
66 /* Memory events */
njnfdc28af2003-02-24 10:36:48 +000067 .new_mem_startup = NULL,
68 .new_mem_heap = NULL,
69 .new_mem_stack = NULL,
70 .new_mem_stack_aligned = NULL,
71 .new_mem_stack_signal = NULL,
72 .new_mem_brk = NULL,
73 .new_mem_mmap = NULL,
njn810086f2002-11-14 12:42:47 +000074
njnfdc28af2003-02-24 10:36:48 +000075 .copy_mem_heap = NULL,
76 .copy_mem_remap = NULL,
77 .change_mem_mprotect = NULL,
njn810086f2002-11-14 12:42:47 +000078
njnfdc28af2003-02-24 10:36:48 +000079 .ban_mem_heap = NULL,
80 .ban_mem_stack = NULL,
njn810086f2002-11-14 12:42:47 +000081
njnfdc28af2003-02-24 10:36:48 +000082 .die_mem_heap = NULL,
83 .die_mem_stack = NULL,
84 .die_mem_stack_aligned = NULL,
85 .die_mem_stack_signal = NULL,
86 .die_mem_brk = NULL,
87 .die_mem_munmap = NULL,
njn810086f2002-11-14 12:42:47 +000088
njnfdc28af2003-02-24 10:36:48 +000089 .bad_free = NULL,
90 .mismatched_free = NULL,
njn810086f2002-11-14 12:42:47 +000091
njnfdc28af2003-02-24 10:36:48 +000092 .pre_mem_read = NULL,
93 .pre_mem_read_asciiz = NULL,
94 .pre_mem_write = NULL,
95 .post_mem_write = NULL,
njn810086f2002-11-14 12:42:47 +000096
97 /* Scheduler events */
njnfdc28af2003-02-24 10:36:48 +000098 .thread_run = NULL,
njn810086f2002-11-14 12:42:47 +000099
100 /* Mutex events */
njnfdc28af2003-02-24 10:36:48 +0000101 .post_mutex_lock = NULL,
102 .post_mutex_unlock = NULL,
103
104 /* Signal events */
105 .pre_deliver_signal = NULL,
106 .post_deliver_signal = NULL,
njn810086f2002-11-14 12:42:47 +0000107};
108
109/* static */
110void VG_(sanity_check_needs) ( void)
111{
112#define CHECK_NOT(var, value) \
113 if ((var)==(value)) { \
114 VG_(printf)("\nSkin error: `%s' not initialised\n", \
115 VG__STRING(var)); \
njn120281f2003-02-03 12:20:07 +0000116 VG_(skin_panic)("Uninitialised details field\n"); \
njn810086f2002-11-14 12:42:47 +0000117 }
118
njn120281f2003-02-03 12:20:07 +0000119 /* Ones that must be set */
njn810086f2002-11-14 12:42:47 +0000120 CHECK_NOT(VG_(details).name, NULL);
121 /* Nb: .version can be NULL */
122 CHECK_NOT(VG_(details).description, NULL);
123 CHECK_NOT(VG_(details).copyright_author, NULL);
124 CHECK_NOT(VG_(details).bug_reports_to, NULL);
125
126#undef CHECK_NOT
127#undef INVALID_Bool
128}
129
130/*--------------------------------------------------------------------*/
131/* Setting details */
132
133/* Use macro because they're so repetitive */
sewardjc0d8f682002-11-30 00:49:43 +0000134#define DETAILS(type, detail) \
135 extern void VG_(details_##detail)(type detail) \
136 { \
137 VG_(details).detail = detail; \
njn810086f2002-11-14 12:42:47 +0000138 }
139
sewardjc0d8f682002-11-30 00:49:43 +0000140DETAILS(Char*, name)
141DETAILS(Char*, version)
142DETAILS(Char*, description)
143DETAILS(Char*, copyright_author)
144DETAILS(Char*, bug_reports_to)
njn120281f2003-02-03 12:20:07 +0000145DETAILS(UInt, avg_translation_sizeB)
njn810086f2002-11-14 12:42:47 +0000146
147/*--------------------------------------------------------------------*/
148/* Setting needs */
149
150/* Use macro because they're so repetitive */
151#define NEEDS(need) \
152 extern void VG_(needs_##need)(void) \
153 { \
154 VG_(needs).need = True; \
155 }
156
157NEEDS(libc_freeres)
158NEEDS(core_errors)
159NEEDS(skin_errors)
160NEEDS(basic_block_discards)
161NEEDS(shadow_regs)
162NEEDS(command_line_options)
163NEEDS(client_requests)
164NEEDS(extended_UCode)
165NEEDS(syscall_wrapper)
166
167extern void VG_(needs_sizeof_shadow_block)(Int size)
168{
169 VG_(needs).sizeof_shadow_block = size;
170}
171
172NEEDS(alternative_free)
173NEEDS(sanity_checks)
174NEEDS(data_syms)
175
176/*--------------------------------------------------------------------*/
177#define TRACK(event, args...) \
178 void VG_(track_##event)(void (*f)(args)) \
179 { \
180 VG_(track_events).event = f; \
181 }
182
183TRACK(new_mem_startup, Addr a, UInt len, Bool rr, Bool ww, Bool xx)
184TRACK(new_mem_heap, Addr a, UInt len, Bool is_inited)
185TRACK(new_mem_stack, Addr a, UInt len)
186TRACK(new_mem_stack_aligned, Addr a, UInt len)
187TRACK(new_mem_stack_signal, Addr a, UInt len)
188TRACK(new_mem_brk, Addr a, UInt len)
189TRACK(new_mem_mmap, Addr a, UInt len, Bool rr, Bool ww, Bool xx)
190
191TRACK(copy_mem_heap, Addr from, Addr to, UInt len)
192TRACK(copy_mem_remap, Addr from, Addr to, UInt len)
193TRACK(change_mem_mprotect, Addr a, UInt len, Bool rr, Bool ww, Bool xx)
194
195TRACK(ban_mem_heap, Addr a, UInt len)
196TRACK(ban_mem_stack, Addr a, UInt len)
197
198TRACK(die_mem_heap, Addr a, UInt len)
199TRACK(die_mem_stack, Addr a, UInt len)
200TRACK(die_mem_stack_aligned, Addr a, UInt len)
201TRACK(die_mem_stack_signal, Addr a, UInt len)
202TRACK(die_mem_brk, Addr a, UInt len)
203TRACK(die_mem_munmap, Addr a, UInt len)
204
205TRACK(bad_free, ThreadState* tst, Addr a)
206TRACK(mismatched_free, ThreadState* tst, Addr a)
207
208TRACK(pre_mem_read, CorePart part, ThreadState* tst, Char* s, Addr a,
209 UInt size)
210TRACK(pre_mem_read_asciiz, CorePart part, ThreadState* tst, Char* s, Addr a)
211TRACK(pre_mem_write, CorePart part, ThreadState* tst, Char* s, Addr a,
212 UInt size)
213TRACK(post_mem_write, Addr a, UInt size)
214
215TRACK(thread_run, ThreadId tid)
216
217TRACK(post_thread_create, ThreadId tid, ThreadId child)
218TRACK(post_thread_join, ThreadId joiner, ThreadId joinee)
219
220TRACK( pre_mutex_lock, ThreadId tid, void* /*pthread_mutex_t* */ mutex)
221TRACK(post_mutex_lock, ThreadId tid, void* /*pthread_mutex_t* */ mutex)
222TRACK(post_mutex_unlock, ThreadId tid, void* /*pthread_mutex_t* */ mutex)
223
njnfdc28af2003-02-24 10:36:48 +0000224TRACK(pre_deliver_signal, ThreadId tid, Int sigNum, Bool alt_stack)
225TRACK(post_deliver_signal, ThreadId tid, Int sigNum)
226
njn810086f2002-11-14 12:42:47 +0000227/*--------------------------------------------------------------------*/
228/* UCodeBlocks */
229
230Int VG_(get_num_instrs) ( UCodeBlock* cb )
231{
232 return cb->used;
233}
234
235Int VG_(get_num_temps) ( UCodeBlock* cb )
236{
237 return cb->nextTemp;
238}
239
240UInstr* VG_(get_instr) ( UCodeBlock* cb, Int i )
241{
242 return & cb->instrs[i];
243}
244
245UInstr* VG_(get_last_instr) ( UCodeBlock* cb )
246{
247 return & cb->instrs[cb->used-1];
248}
249
250/*--------------------------------------------------------------------*/
251/* Suppressions */
252
253SuppKind VG_(get_supp_kind) ( Supp* su )
254{
255 return su->skind;
256}
257
258Char* VG_(get_supp_string) ( Supp* su )
259{
260 return su->string;
261}
262
263void* VG_(get_supp_extra) ( Supp* su )
264{
265 return su->extra;
266}
267
268
269void VG_(set_supp_kind) ( Supp* su, SuppKind skind )
270{
271 su->skind = skind;
272}
273
274void VG_(set_supp_string) ( Supp* su, Char* string )
275{
276 su->string = string;
277}
278
279void VG_(set_supp_extra) ( Supp* su, void* extra )
280{
281 su->extra = extra;
282}
283
284/*--------------------------------------------------------------------*/
285/* Errors */
286
njnae17bec2003-01-28 19:59:38 +0000287ExeContext* VG_(get_error_where) ( Error* err )
288{
njn6d57f7d2003-02-06 08:17:08 +0000289 return err->where;
njnae17bec2003-01-28 19:59:38 +0000290}
291
njn810086f2002-11-14 12:42:47 +0000292ErrorKind VG_(get_error_kind) ( Error* err )
293{
294 return err->ekind;
295}
296
297Addr VG_(get_error_address) ( Error* err )
298{
299 return err->addr;
300}
301
302Char* VG_(get_error_string) ( Error* err )
303{
304 return err->string;
305}
306
307void* VG_(get_error_extra) ( Error* err )
308{
309 return err->extra;
310}
311
312/*--------------------------------------------------------------------*/
313/* ShadowChunks */
314
315UInt VG_(get_sc_size) ( ShadowChunk* sc )
316{
317 return sc->size;
318}
319
320Addr VG_(get_sc_data) ( ShadowChunk* sc )
321{
322 return sc->data;
323}
324
325UInt VG_(get_sc_extra) ( ShadowChunk* sc, UInt i )
326{
327 vg_assert(i < VG_(needs).sizeof_shadow_block);
328 return sc->extra[i];
329}
330
331ShadowChunk* VG_(get_sc_next) ( ShadowChunk* sc )
332{
333 return sc->next;
334}
335
336void VG_(set_sc_extra) ( ShadowChunk* sc, UInt i, UInt word )
337{
338 vg_assert(i < VG_(needs).sizeof_shadow_block);
339 sc->extra[i] = word;
340}
341
342void VG_(set_sc_next) ( ShadowChunk* sc, ShadowChunk* next )
343{
344 sc->next = next;
345}
346
347
348/*--------------------------------------------------------------------*/
349/*--- end vg_needs.c ---*/
350/*--------------------------------------------------------------------*/
351
352