blob: a83dcd364afdb35563df39d50b505a64bf536465 [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 */
67 .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,
74
75 .copy_mem_heap = NULL,
76 .copy_mem_remap = NULL,
77 .change_mem_mprotect = NULL,
78
79 .ban_mem_heap = NULL,
80 .ban_mem_stack = NULL,
81
82 .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,
88
89 .bad_free = NULL,
90 .mismatched_free = NULL,
91
92 .pre_mem_read = NULL,
93 .pre_mem_read_asciiz = NULL,
94 .pre_mem_write = NULL,
95 .post_mem_write = NULL,
96
97 /* Scheduler events */
98 .thread_run = NULL,
99
100 /* Mutex events */
101 .post_mutex_lock = NULL,
102 .post_mutex_unlock = NULL,
103};
104
105/* static */
106void VG_(sanity_check_needs) ( void)
107{
108#define CHECK_NOT(var, value) \
109 if ((var)==(value)) { \
110 VG_(printf)("\nSkin error: `%s' not initialised\n", \
111 VG__STRING(var)); \
njn120281f2003-02-03 12:20:07 +0000112 VG_(skin_panic)("Uninitialised details field\n"); \
njn810086f2002-11-14 12:42:47 +0000113 }
114
njn120281f2003-02-03 12:20:07 +0000115 /* Ones that must be set */
njn810086f2002-11-14 12:42:47 +0000116 CHECK_NOT(VG_(details).name, NULL);
117 /* Nb: .version can be NULL */
118 CHECK_NOT(VG_(details).description, NULL);
119 CHECK_NOT(VG_(details).copyright_author, NULL);
120 CHECK_NOT(VG_(details).bug_reports_to, NULL);
121
122#undef CHECK_NOT
123#undef INVALID_Bool
124}
125
126/*--------------------------------------------------------------------*/
127/* Setting details */
128
129/* Use macro because they're so repetitive */
sewardjc0d8f682002-11-30 00:49:43 +0000130#define DETAILS(type, detail) \
131 extern void VG_(details_##detail)(type detail) \
132 { \
133 VG_(details).detail = detail; \
njn810086f2002-11-14 12:42:47 +0000134 }
135
sewardjc0d8f682002-11-30 00:49:43 +0000136DETAILS(Char*, name)
137DETAILS(Char*, version)
138DETAILS(Char*, description)
139DETAILS(Char*, copyright_author)
140DETAILS(Char*, bug_reports_to)
njn120281f2003-02-03 12:20:07 +0000141DETAILS(UInt, avg_translation_sizeB)
njn810086f2002-11-14 12:42:47 +0000142
143/*--------------------------------------------------------------------*/
144/* Setting needs */
145
146/* Use macro because they're so repetitive */
147#define NEEDS(need) \
148 extern void VG_(needs_##need)(void) \
149 { \
150 VG_(needs).need = True; \
151 }
152
153NEEDS(libc_freeres)
154NEEDS(core_errors)
155NEEDS(skin_errors)
156NEEDS(basic_block_discards)
157NEEDS(shadow_regs)
158NEEDS(command_line_options)
159NEEDS(client_requests)
160NEEDS(extended_UCode)
161NEEDS(syscall_wrapper)
162
163extern void VG_(needs_sizeof_shadow_block)(Int size)
164{
165 VG_(needs).sizeof_shadow_block = size;
166}
167
168NEEDS(alternative_free)
169NEEDS(sanity_checks)
170NEEDS(data_syms)
171
172/*--------------------------------------------------------------------*/
173#define TRACK(event, args...) \
174 void VG_(track_##event)(void (*f)(args)) \
175 { \
176 VG_(track_events).event = f; \
177 }
178
179TRACK(new_mem_startup, Addr a, UInt len, Bool rr, Bool ww, Bool xx)
180TRACK(new_mem_heap, Addr a, UInt len, Bool is_inited)
181TRACK(new_mem_stack, Addr a, UInt len)
182TRACK(new_mem_stack_aligned, Addr a, UInt len)
183TRACK(new_mem_stack_signal, Addr a, UInt len)
184TRACK(new_mem_brk, Addr a, UInt len)
185TRACK(new_mem_mmap, Addr a, UInt len, Bool rr, Bool ww, Bool xx)
186
187TRACK(copy_mem_heap, Addr from, Addr to, UInt len)
188TRACK(copy_mem_remap, Addr from, Addr to, UInt len)
189TRACK(change_mem_mprotect, Addr a, UInt len, Bool rr, Bool ww, Bool xx)
190
191TRACK(ban_mem_heap, Addr a, UInt len)
192TRACK(ban_mem_stack, Addr a, UInt len)
193
194TRACK(die_mem_heap, Addr a, UInt len)
195TRACK(die_mem_stack, Addr a, UInt len)
196TRACK(die_mem_stack_aligned, Addr a, UInt len)
197TRACK(die_mem_stack_signal, Addr a, UInt len)
198TRACK(die_mem_brk, Addr a, UInt len)
199TRACK(die_mem_munmap, Addr a, UInt len)
200
201TRACK(bad_free, ThreadState* tst, Addr a)
202TRACK(mismatched_free, ThreadState* tst, Addr a)
203
204TRACK(pre_mem_read, CorePart part, ThreadState* tst, Char* s, Addr a,
205 UInt size)
206TRACK(pre_mem_read_asciiz, CorePart part, ThreadState* tst, Char* s, Addr a)
207TRACK(pre_mem_write, CorePart part, ThreadState* tst, Char* s, Addr a,
208 UInt size)
209TRACK(post_mem_write, Addr a, UInt size)
210
211TRACK(thread_run, ThreadId tid)
212
213TRACK(post_thread_create, ThreadId tid, ThreadId child)
214TRACK(post_thread_join, ThreadId joiner, ThreadId joinee)
215
216TRACK( pre_mutex_lock, ThreadId tid, void* /*pthread_mutex_t* */ mutex)
217TRACK(post_mutex_lock, ThreadId tid, void* /*pthread_mutex_t* */ mutex)
218TRACK(post_mutex_unlock, ThreadId tid, void* /*pthread_mutex_t* */ mutex)
219
220/*--------------------------------------------------------------------*/
221/* UCodeBlocks */
222
223Int VG_(get_num_instrs) ( UCodeBlock* cb )
224{
225 return cb->used;
226}
227
228Int VG_(get_num_temps) ( UCodeBlock* cb )
229{
230 return cb->nextTemp;
231}
232
233UInstr* VG_(get_instr) ( UCodeBlock* cb, Int i )
234{
235 return & cb->instrs[i];
236}
237
238UInstr* VG_(get_last_instr) ( UCodeBlock* cb )
239{
240 return & cb->instrs[cb->used-1];
241}
242
243/*--------------------------------------------------------------------*/
244/* Suppressions */
245
246SuppKind VG_(get_supp_kind) ( Supp* su )
247{
248 return su->skind;
249}
250
251Char* VG_(get_supp_string) ( Supp* su )
252{
253 return su->string;
254}
255
256void* VG_(get_supp_extra) ( Supp* su )
257{
258 return su->extra;
259}
260
261
262void VG_(set_supp_kind) ( Supp* su, SuppKind skind )
263{
264 su->skind = skind;
265}
266
267void VG_(set_supp_string) ( Supp* su, Char* string )
268{
269 su->string = string;
270}
271
272void VG_(set_supp_extra) ( Supp* su, void* extra )
273{
274 su->extra = extra;
275}
276
277/*--------------------------------------------------------------------*/
278/* Errors */
279
njnae17bec2003-01-28 19:59:38 +0000280ExeContext* VG_(get_error_where) ( Error* err )
281{
282 return err->ekind;
283}
284
njn810086f2002-11-14 12:42:47 +0000285ErrorKind VG_(get_error_kind) ( Error* err )
286{
287 return err->ekind;
288}
289
290Addr VG_(get_error_address) ( Error* err )
291{
292 return err->addr;
293}
294
295Char* VG_(get_error_string) ( Error* err )
296{
297 return err->string;
298}
299
300void* VG_(get_error_extra) ( Error* err )
301{
302 return err->extra;
303}
304
305/*--------------------------------------------------------------------*/
306/* ShadowChunks */
307
308UInt VG_(get_sc_size) ( ShadowChunk* sc )
309{
310 return sc->size;
311}
312
313Addr VG_(get_sc_data) ( ShadowChunk* sc )
314{
315 return sc->data;
316}
317
318UInt VG_(get_sc_extra) ( ShadowChunk* sc, UInt i )
319{
320 vg_assert(i < VG_(needs).sizeof_shadow_block);
321 return sc->extra[i];
322}
323
324ShadowChunk* VG_(get_sc_next) ( ShadowChunk* sc )
325{
326 return sc->next;
327}
328
329void VG_(set_sc_extra) ( ShadowChunk* sc, UInt i, UInt word )
330{
331 vg_assert(i < VG_(needs).sizeof_shadow_block);
332 sc->extra[i] = word;
333}
334
335void VG_(set_sc_next) ( ShadowChunk* sc, ShadowChunk* next )
336{
337 sc->next = next;
338}
339
340
341/*--------------------------------------------------------------------*/
342/*--- end vg_needs.c ---*/
343/*--------------------------------------------------------------------*/
344
345