blob: bc080d9019bba8e66d9d1dad2a7ff8e7904e4063 [file] [log] [blame]
njn5c004e42002-11-18 11:04:50 +00001
2/*--------------------------------------------------------------------*/
njn51d827b2005-05-09 01:02:08 +00003/*--- Declarations shared between Memcheck and Addrcheck. ---*/
njn43c799e2003-04-08 00:08:52 +00004/*--- mac_shared.h ---*/
njn5c004e42002-11-18 11:04:50 +00005/*--------------------------------------------------------------------*/
6
7/*
nethercote137bc552003-11-14 17:47:54 +00008 This file is part of MemCheck, a heavyweight Valgrind tool for
9 detecting memory errors, and AddrCheck, a lightweight Valgrind tool
njn5c004e42002-11-18 11:04:50 +000010 for detecting memory errors.
11
njn53612422005-03-12 16:22:54 +000012 Copyright (C) 2000-2005 Julian Seward
njn5c004e42002-11-18 11:04:50 +000013 jseward@acm.org
14
15 This program is free software; you can redistribute it and/or
16 modify it under the terms of the GNU General Public License as
17 published by the Free Software Foundation; either version 2 of the
18 License, or (at your option) any later version.
19
20 This program is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 02111-1307, USA.
29
30 The GNU General Public License is contained in the file COPYING.
31*/
32
njn43c799e2003-04-08 00:08:52 +000033/* Note: This header contains the declarations shared between
34 Addrcheck and Memcheck, and is #included by both. */
35
36#ifndef __MAC_SHARED_H
37#define __MAC_SHARED_H
njn5c004e42002-11-18 11:04:50 +000038
njn43c799e2003-04-08 00:08:52 +000039#define MAC_(str) VGAPPEND(vgMAC_,str)
njn5c004e42002-11-18 11:04:50 +000040
njn9b007f62003-04-07 14:40:25 +000041/*------------------------------------------------------------*/
42/*--- Errors and suppressions ---*/
43/*------------------------------------------------------------*/
44
njn5c004e42002-11-18 11:04:50 +000045/* The classification of a faulting address. */
46typedef
njn43c799e2003-04-08 00:08:52 +000047 enum {
nethercote8b76fe52004-11-08 19:20:09 +000048 Undescribed, // as-yet unclassified
njn43c799e2003-04-08 00:08:52 +000049 Stack,
nethercote8b76fe52004-11-08 19:20:09 +000050 Unknown, // classification yielded nothing useful
njn43c799e2003-04-08 00:08:52 +000051 Freed, Mallocd,
nethercote8b76fe52004-11-08 19:20:09 +000052 UserG, // in a user-defined block
53 Mempool, // in a mempool
54 Register, // in a register; for Param errors only
njn5c004e42002-11-18 11:04:50 +000055 }
56 AddrKind;
57
58/* Records info about a faulting address. */
59typedef
nethercote05675c82004-08-04 10:37:49 +000060 struct { // Used by:
61 AddrKind akind; // ALL
nethercote928a5f72004-11-03 18:10:37 +000062 SizeT blksize; // Freed, Mallocd
nethercote8b76fe52004-11-08 19:20:09 +000063 OffT rwoffset; // Freed, Mallocd
nethercote05675c82004-08-04 10:37:49 +000064 ExeContext* lastchange; // Freed, Mallocd
65 ThreadId stack_tid; // Stack
sewardjb5f6f512005-03-10 23:59:00 +000066 const Char *desc; // UserG
nethercote05675c82004-08-04 10:37:49 +000067 Bool maybe_gcc; // True if just below %esp -- could be a gcc bug.
njn5c004e42002-11-18 11:04:50 +000068 }
69 AddrInfo;
70
71typedef
72 enum {
nethercote05675c82004-08-04 10:37:49 +000073 ParamSupp, // Bad syscall params
74 CoreMemSupp, // Memory errors in core (pthread ops, signal handling)
75
76 // Use of invalid values of given size (MemCheck only)
njnc0616662003-06-12 09:58:41 +000077 Value0Supp, Value1Supp, Value2Supp, Value4Supp, Value8Supp, Value16Supp,
nethercote05675c82004-08-04 10:37:49 +000078
79 // Invalid read/write attempt at given size
njnc0616662003-06-12 09:58:41 +000080 Addr1Supp, Addr2Supp, Addr4Supp, Addr8Supp, Addr16Supp,
nethercote05675c82004-08-04 10:37:49 +000081
82 FreeSupp, // Invalid or mismatching free
83 OverlapSupp, // Overlapping blocks in memcpy(), strcpy(), etc
84 LeakSupp, // Something to be suppressed in a leak check.
85 MempoolSupp, // Memory pool suppression.
njn5c004e42002-11-18 11:04:50 +000086 }
njn43c799e2003-04-08 00:08:52 +000087 MAC_SuppKind;
njn5c004e42002-11-18 11:04:50 +000088
89/* What kind of error it is. */
90typedef
91 enum { ValueErr, /* Memcheck only */
92 CoreMemErr,
93 AddrErr,
94 ParamErr, UserErr, /* behaves like an anonymous ParamErr */
njn43c799e2003-04-08 00:08:52 +000095 FreeErr, FreeMismatchErr,
njn7201b2a2003-08-19 12:16:05 +000096 OverlapErr,
rjwalshbc0bb832004-06-19 18:12:36 +000097 LeakErr,
98 IllegalMempoolErr,
njn5c004e42002-11-18 11:04:50 +000099 }
njn43c799e2003-04-08 00:08:52 +0000100 MAC_ErrorKind;
njn5c004e42002-11-18 11:04:50 +0000101
102/* What kind of memory access is involved in the error? */
103typedef
104 enum { ReadAxs, WriteAxs, ExecAxs }
105 AxsKind;
106
107/* Extra context for memory errors */
108typedef
nethercote05675c82004-08-04 10:37:49 +0000109 struct { // Used by:
110 AxsKind axskind; // AddrErr
111 Int size; // AddrErr, ValueErr
112 AddrInfo addrinfo; // {Addr,Free,FreeMismatch,Param,User}Err
nethercote8b76fe52004-11-08 19:20:09 +0000113 Bool isUnaddr; // {CoreMem,Param,User}Err
njn5c004e42002-11-18 11:04:50 +0000114 }
njn43c799e2003-04-08 00:08:52 +0000115 MAC_Error;
njn5c004e42002-11-18 11:04:50 +0000116
njnb6cae9f2003-09-04 20:50:47 +0000117/* Extra info for overlap errors */
118typedef
119 struct {
120 Addr src;
121 Addr dst;
122 Int len; // -1 if unused
123 }
124 OverlapExtra;
125
njn3e884182003-04-15 13:03:23 +0000126/* For malloc()/new/new[] vs. free()/delete/delete[] mismatch checking. */
127typedef
128 enum {
129 MAC_AllocMalloc = 0,
130 MAC_AllocNew = 1,
njn10785452003-05-20 16:38:24 +0000131 MAC_AllocNewVec = 2,
132 MAC_AllocCustom = 3
njn3e884182003-04-15 13:03:23 +0000133 }
134 MAC_AllocKind;
135
136/* Nb: first two fields must match core's VgHashNode. */
137typedef
138 struct _MAC_Chunk {
139 struct _MAC_Chunk* next;
nethercote05675c82004-08-04 10:37:49 +0000140 Addr data; // ptr to actual block
njnb729e0d2004-12-01 00:19:38 +0000141 SizeT size : (sizeof(UWord)*8)-2; // size requested; 30 or 62 bits
nethercote05675c82004-08-04 10:37:49 +0000142 MAC_AllocKind allockind : 2; // which wrapper did the allocation
143 ExeContext* where; // where it was allocated
njn3e884182003-04-15 13:03:23 +0000144 }
145 MAC_Chunk;
146
rjwalshbc0bb832004-06-19 18:12:36 +0000147/* Memory pool. Nb: first two fields must match core's VgHashNode. */
148typedef
149 struct _MAC_Mempool {
150 struct _MAC_Mempool* next;
nethercote05675c82004-08-04 10:37:49 +0000151 Addr pool; // pool identifier
njnb729e0d2004-12-01 00:19:38 +0000152 SizeT rzB; // pool red-zone size
nethercote05675c82004-08-04 10:37:49 +0000153 Bool is_zeroed; // allocations from this pool are zeroed
154 VgHashTable chunks; // chunks associated with this pool
rjwalshbc0bb832004-06-19 18:12:36 +0000155 }
156 MAC_Mempool;
157
158
njn9b007f62003-04-07 14:40:25 +0000159/*------------------------------------------------------------*/
njn13a49262005-12-19 22:48:06 +0000160/*--- Profiling of memory events ---*/
njn9b007f62003-04-07 14:40:25 +0000161/*------------------------------------------------------------*/
162
njn9b007f62003-04-07 14:40:25 +0000163/* Define to collect detailed performance info. */
sewardj23eb2fd2005-04-22 16:29:19 +0000164/* #define MAC_PROFILE_MEMORY */
njn5c004e42002-11-18 11:04:50 +0000165
njn43c799e2003-04-08 00:08:52 +0000166#ifdef MAC_PROFILE_MEMORY
sewardjc1a2cda2005-04-21 17:34:00 +0000167# define N_PROF_EVENTS 500
njn5c004e42002-11-18 11:04:50 +0000168
sewardjc1a2cda2005-04-21 17:34:00 +0000169extern UInt MAC_(event_ctr)[N_PROF_EVENTS];
170extern HChar* MAC_(event_ctr_name)[N_PROF_EVENTS];
njn9b007f62003-04-07 14:40:25 +0000171
sewardjc1a2cda2005-04-21 17:34:00 +0000172# define PROF_EVENT(ev, name) \
173 do { tl_assert((ev) >= 0 && (ev) < N_PROF_EVENTS); \
174 /* crude and inaccurate check to ensure the same */ \
175 /* event isn't being used with > 1 name */ \
176 if (MAC_(event_ctr_name)[ev]) \
177 tl_assert(name == MAC_(event_ctr_name)[ev]); \
178 MAC_(event_ctr)[ev]++; \
179 MAC_(event_ctr_name)[ev] = (name); \
njn5c004e42002-11-18 11:04:50 +0000180 } while (False);
181
182#else
183
sewardjc1a2cda2005-04-21 17:34:00 +0000184# define PROF_EVENT(ev, name) /* */
njn5c004e42002-11-18 11:04:50 +0000185
njn43c799e2003-04-08 00:08:52 +0000186#endif /* MAC_PROFILE_MEMORY */
njn5c004e42002-11-18 11:04:50 +0000187
njn9b007f62003-04-07 14:40:25 +0000188
sewardj23eb2fd2005-04-22 16:29:19 +0000189/*------------------------------------------------------------*/
190/*--- V and A bits (Victoria & Albert ?) ---*/
191/*------------------------------------------------------------*/
192
193/* expand 1 bit -> 8 */
194#define BIT_TO_BYTE(b) ((~(((UChar)(b) & 1) - 1)) & 0xFF)
195
sewardj05fe85e2005-04-27 22:46:36 +0000196/* The number of entries in the primary map can be altered. However
197 we hardwire the assumption that each secondary map covers precisely
198 64k of address space. */
199#define SECONDARY_SIZE 65536 /* DO NOT CHANGE */
200#define SECONDARY_MASK (SECONDARY_SIZE-1) /* DO NOT CHANGE */
201
sewardj45d94cc2005-04-20 14:44:11 +0000202//zz #define SECONDARY_SHIFT 16
203//zz #define SECONDARY_SIZE (1 << SECONDARY_SHIFT)
204//zz #define SECONDARY_MASK (SECONDARY_SIZE - 1)
205//zz
206//zz #define PRIMARY_SIZE (1 << (32 - SECONDARY_SHIFT))
207//zz
208//zz #define SM_OFF(addr) ((addr) & SECONDARY_MASK)
209//zz #define PM_IDX(addr) ((addr) >> SECONDARY_SHIFT)
210/*
sewardjb5f6f512005-03-10 23:59:00 +0000211#define IS_DISTINGUISHED_SM(smap) \
212 ((smap) >= &distinguished_secondary_maps[0] && \
213 (smap) < &distinguished_secondary_maps[N_SECONDARY_MAPS])
214
215#define IS_DISTINGUISHED(addr) (IS_DISTINGUISHED_SM(primary_map[PM_IDX(addr)]))
njn5c004e42002-11-18 11:04:50 +0000216
njn43c799e2003-04-08 00:08:52 +0000217#define ENSURE_MAPPABLE(addr,caller) \
218 do { \
sewardjb5f6f512005-03-10 23:59:00 +0000219 if (IS_DISTINGUISHED(addr)) { \
220 primary_map[PM_IDX(addr)] = alloc_secondary_map(caller, primary_map[PM_IDX(addr)]); \
sewardj45d94cc2005-04-20 14:44:11 +0000221 if (0) VG_(printf)("new 2map because of %p\n", addr); \
njn43c799e2003-04-08 00:08:52 +0000222 } \
sewardj45d94cc2005-04-20 14:44:11 +0000223 } while(0)
224*/
njn5c004e42002-11-18 11:04:50 +0000225
226#define BITARR_SET(aaa_p,iii_p) \
227 do { \
sewardj45d94cc2005-04-20 14:44:11 +0000228 UWord iii = (UWord)iii_p; \
229 UChar* aaa = (UChar*)aaa_p; \
njn5c004e42002-11-18 11:04:50 +0000230 aaa[iii >> 3] |= (1 << (iii & 7)); \
231 } while (0)
232
233#define BITARR_CLEAR(aaa_p,iii_p) \
234 do { \
sewardj45d94cc2005-04-20 14:44:11 +0000235 UWord iii = (UWord)iii_p; \
236 UChar* aaa = (UChar*)aaa_p; \
njn5c004e42002-11-18 11:04:50 +0000237 aaa[iii >> 3] &= ~(1 << (iii & 7)); \
238 } while (0)
239
240#define BITARR_TEST(aaa_p,iii_p) \
sewardj45d94cc2005-04-20 14:44:11 +0000241 (0 != (((UChar*)aaa_p)[ ((UWord)iii_p) >> 3 ] \
242 & (1 << (((UWord)iii_p) & 7)))) \
243
244static inline
245void write_bit_array ( UChar* arr, UWord idx, UWord bit )
246{
247 UWord shift = idx & 7;
248 idx >>= 3;
249 bit &= 1;
250 arr[idx] = (arr[idx] & ~(1<<shift)) | (bit << shift);
251}
252
253static inline
254UWord read_bit_array ( UChar* arr, UWord idx )
255{
256 UWord shift = idx & 7;
257 idx >>= 3;
258 return 1 & (arr[idx] >> shift);
259}
njn5c004e42002-11-18 11:04:50 +0000260
261
sewardj45d94cc2005-04-20 14:44:11 +0000262#define VGM_BIT_VALID 0
263#define VGM_BIT_INVALID 1
njn5c004e42002-11-18 11:04:50 +0000264
sewardj45d94cc2005-04-20 14:44:11 +0000265#define VGM_NIBBLE_VALID 0
266#define VGM_NIBBLE_INVALID 0xF
njn5c004e42002-11-18 11:04:50 +0000267
sewardj45d94cc2005-04-20 14:44:11 +0000268#define VGM_BYTE_VALID 0
269#define VGM_BYTE_INVALID 0xFF
njn5c004e42002-11-18 11:04:50 +0000270
sewardj45d94cc2005-04-20 14:44:11 +0000271#define VGM_WORD32_VALID 0
272#define VGM_WORD32_INVALID 0xFFFFFFFF
njn5c004e42002-11-18 11:04:50 +0000273
sewardj45d94cc2005-04-20 14:44:11 +0000274#define VGM_WORD64_VALID 0ULL
275#define VGM_WORD64_INVALID 0xFFFFFFFFFFFFFFFFULL
276
njn5c004e42002-11-18 11:04:50 +0000277
278/*------------------------------------------------------------*/
279/*--- Command line options + defaults ---*/
280/*------------------------------------------------------------*/
281
njn43c799e2003-04-08 00:08:52 +0000282/* Memcheck defines a couple more. */
njn5c004e42002-11-18 11:04:50 +0000283
284/* Allow loads from partially-valid addresses? default: YES */
njn43c799e2003-04-08 00:08:52 +0000285extern Bool MAC_(clo_partial_loads_ok);
njn5c004e42002-11-18 11:04:50 +0000286
287/* Max volume of the freed blocks queue. */
njn43c799e2003-04-08 00:08:52 +0000288extern Int MAC_(clo_freelist_vol);
njn5c004e42002-11-18 11:04:50 +0000289
290/* Do leak check at exit? default: NO */
sewardjb5f6f512005-03-10 23:59:00 +0000291typedef
292 enum {
293 LC_Off,
294 LC_Summary,
295 LC_Full,
296 }
297 LeakCheckMode;
298
299extern LeakCheckMode MAC_(clo_leak_check);
njn5c004e42002-11-18 11:04:50 +0000300
301/* How closely should we compare ExeContexts in leak records? default: 2 */
njn43c799e2003-04-08 00:08:52 +0000302extern VgRes MAC_(clo_leak_resolution);
njn5c004e42002-11-18 11:04:50 +0000303
304/* In leak check, show reachable-but-not-freed blocks? default: NO */
njn43c799e2003-04-08 00:08:52 +0000305extern Bool MAC_(clo_show_reachable);
njn5c004e42002-11-18 11:04:50 +0000306
307/* Assume accesses immediately below %esp are due to gcc-2.96 bugs.
308 * default: NO*/
njn43c799e2003-04-08 00:08:52 +0000309extern Bool MAC_(clo_workaround_gcc296_bugs);
njn5c004e42002-11-18 11:04:50 +0000310
njn3e884182003-04-15 13:03:23 +0000311extern Bool MAC_(process_common_cmd_line_option) ( Char* arg );
312extern void MAC_(print_common_usage) ( void );
313extern void MAC_(print_common_debug_usage) ( void );
314
njn8a97c6d2005-03-31 04:37:24 +0000315/* We want a 16B redzone on heap blocks for Addrcheck and Memcheck */
njn51d827b2005-05-09 01:02:08 +0000316#define MAC_MALLOC_REDZONE_SZB 16
njn3e884182003-04-15 13:03:23 +0000317
318/*------------------------------------------------------------*/
319/*--- Variables ---*/
320/*------------------------------------------------------------*/
321
322/* For tracking malloc'd blocks */
323extern VgHashTable MAC_(malloc_list);
324
rjwalshbc0bb832004-06-19 18:12:36 +0000325/* For tracking memory pools. */
326extern VgHashTable MAC_(mempool_list);
327
nethercote7cc9c232004-01-21 15:08:04 +0000328/* Function pointers for the two tools to track interesting events. */
nethercote451eae92004-11-02 13:06:32 +0000329extern void (*MAC_(new_mem_heap)) ( Addr a, SizeT len, Bool is_inited );
330extern void (*MAC_(ban_mem_heap)) ( Addr a, SizeT len );
331extern void (*MAC_(die_mem_heap)) ( Addr a, SizeT len );
332extern void (*MAC_(copy_mem_heap))( Addr from, Addr to, SizeT len );
njn3e884182003-04-15 13:03:23 +0000333
sewardjecf8e102003-07-12 12:11:39 +0000334/* Function pointers for internal sanity checking. */
nethercote451eae92004-11-02 13:06:32 +0000335extern Bool (*MAC_(check_noaccess))( Addr a, SizeT len, Addr* bad_addr );
sewardjecf8e102003-07-12 12:11:39 +0000336
njn3e884182003-04-15 13:03:23 +0000337/* Used in describe_addr() */
338extern Bool (*MAC_(describe_addr_supp)) ( Addr a, AddrInfo* ai );
njn5c004e42002-11-18 11:04:50 +0000339
njn47363ab2003-04-21 13:24:40 +0000340/* For VALGRIND_COUNT_LEAKS client request */
njn0fd92f42005-10-06 03:32:42 +0000341extern SizeT MAC_(bytes_leaked);
342extern SizeT MAC_(bytes_indirect);
343extern SizeT MAC_(bytes_dubious);
344extern SizeT MAC_(bytes_reachable);
345extern SizeT MAC_(bytes_suppressed);
sewardj99aac972002-12-26 01:53:45 +0000346
njn5c004e42002-11-18 11:04:50 +0000347/*------------------------------------------------------------*/
348/*--- Functions ---*/
349/*------------------------------------------------------------*/
350
njn43c799e2003-04-08 00:08:52 +0000351extern void MAC_(pp_AddrInfo) ( Addr a, AddrInfo* ai );
njn5c004e42002-11-18 11:04:50 +0000352
njn43c799e2003-04-08 00:08:52 +0000353extern void MAC_(clear_MAC_Error) ( MAC_Error* err_extra );
njn5c004e42002-11-18 11:04:50 +0000354
njn51d827b2005-05-09 01:02:08 +0000355extern Bool MAC_(eq_Error) ( VgRes res, Error* e1, Error* e2 );
356extern UInt MAC_(update_extra)( Error* err );
357extern Bool MAC_(read_extra_suppression_info) ( Int fd, Char* buf, Int nBuf, Supp *su );
358extern Bool MAC_(error_matches_suppression)(Error* err, Supp* su);
359extern Char* MAC_(get_error_name) ( Error* err );
360extern void MAC_(print_extra_suppression_info) ( Error* err );
361
362extern Bool MAC_(shared_recognised_suppression) ( Char* name, Supp* su );
njn5c004e42002-11-18 11:04:50 +0000363
sewardj2a99cf62004-11-24 10:44:19 +0000364extern void* MAC_(new_block) ( ThreadId tid,
365 Addr p, SizeT size, SizeT align, UInt rzB,
nethercote57e36b32004-07-10 14:56:28 +0000366 Bool is_zeroed, MAC_AllocKind kind,
367 VgHashTable table);
sewardj2a99cf62004-11-24 10:44:19 +0000368
369extern void MAC_(handle_free) ( ThreadId tid,
370 Addr p, UInt rzB, MAC_AllocKind kind );
njn10785452003-05-20 16:38:24 +0000371
rjwalshbc0bb832004-06-19 18:12:36 +0000372extern void MAC_(create_mempool)(Addr pool, UInt rzB, Bool is_zeroed);
sewardj2a99cf62004-11-24 10:44:19 +0000373
rjwalshbc0bb832004-06-19 18:12:36 +0000374extern void MAC_(destroy_mempool)(Addr pool);
sewardj2a99cf62004-11-24 10:44:19 +0000375
376extern void MAC_(mempool_alloc)(ThreadId tid,
377 Addr pool, Addr addr, SizeT size);
378
rjwalshbc0bb832004-06-19 18:12:36 +0000379extern void MAC_(mempool_free)(Addr pool, Addr addr);
380
njn72718642003-07-24 08:45:32 +0000381extern void MAC_(record_address_error) ( ThreadId tid, Addr a,
sewardjaf48a602003-07-06 00:54:47 +0000382 Int size, Bool isWrite );
nethercote8b76fe52004-11-08 19:20:09 +0000383extern void MAC_(record_core_mem_error) ( ThreadId tid, Bool isUnaddr,
njn43c799e2003-04-08 00:08:52 +0000384 Char* s );
nethercote8b76fe52004-11-08 19:20:09 +0000385extern void MAC_(record_param_error) ( ThreadId tid, Addr a, Bool isReg,
386 Bool isUnaddr, Char* msg );
njn72718642003-07-24 08:45:32 +0000387extern void MAC_(record_jump_error) ( ThreadId tid, Addr a );
388extern void MAC_(record_free_error) ( ThreadId tid, Addr a );
njn4bd67b52005-08-11 00:47:10 +0000389extern void MAC_(record_freemismatch_error)( ThreadId tid, Addr a,
390 MAC_Chunk* mc);
sewardj2a99cf62004-11-24 10:44:19 +0000391extern void MAC_(record_overlap_error) ( ThreadId tid,
392 Char* function, OverlapExtra* oe );
rjwalshbc0bb832004-06-19 18:12:36 +0000393extern void MAC_(record_illegal_mempool_error) ( ThreadId tid, Addr pool );
njn5c004e42002-11-18 11:04:50 +0000394
njnb126f732004-11-22 17:57:07 +0000395extern void MAC_(pp_shared_Error) ( Error* err);
njn43c799e2003-04-08 00:08:52 +0000396
njn1d0cb0d2005-08-15 01:52:02 +0000397extern MAC_Chunk* MAC_(get_freed_list_head)( void );
njn43c799e2003-04-08 00:08:52 +0000398
njn3e884182003-04-15 13:03:23 +0000399extern void MAC_(common_pre_clo_init) ( void );
njnb8dca862005-03-14 02:42:44 +0000400extern void MAC_(common_fini) ( void (*leak_check)(ThreadId tid,
401 LeakCheckMode mode) );
njn3e884182003-04-15 13:03:23 +0000402
njn72718642003-07-24 08:45:32 +0000403extern Bool MAC_(handle_common_client_requests) ( ThreadId tid,
nethercoted1b64b22004-11-04 18:22:28 +0000404 UWord* arg_block, UWord* ret );
njn47363ab2003-04-21 13:24:40 +0000405
njn43c799e2003-04-08 00:08:52 +0000406/* For leak checking */
njn02977032005-05-17 04:00:11 +0000407extern void MAC_(pp_LeakError)(void* extra);
njn43c799e2003-04-08 00:08:52 +0000408
njn86f12dc2005-03-14 01:16:05 +0000409extern void MAC_(print_malloc_stats) ( void );
410
njn43c799e2003-04-08 00:08:52 +0000411extern void MAC_(do_detect_memory_leaks) (
njnb8dca862005-03-14 02:42:44 +0000412 ThreadId tid, LeakCheckMode mode,
sewardj05fe85e2005-04-27 22:46:36 +0000413 Bool (*is_within_valid_secondary) ( Addr ),
414 Bool (*is_valid_aligned_word) ( Addr )
njn43c799e2003-04-08 00:08:52 +0000415 );
416
njnaf839f52005-06-23 03:27:57 +0000417extern VG_REGPARM(1) void MAC_(new_mem_stack_4) ( Addr old_ESP );
418extern VG_REGPARM(1) void MAC_(die_mem_stack_4) ( Addr old_ESP );
419extern VG_REGPARM(1) void MAC_(new_mem_stack_8) ( Addr old_ESP );
420extern VG_REGPARM(1) void MAC_(die_mem_stack_8) ( Addr old_ESP );
421extern VG_REGPARM(1) void MAC_(new_mem_stack_12) ( Addr old_ESP );
422extern VG_REGPARM(1) void MAC_(die_mem_stack_12) ( Addr old_ESP );
423extern VG_REGPARM(1) void MAC_(new_mem_stack_16) ( Addr old_ESP );
424extern VG_REGPARM(1) void MAC_(die_mem_stack_16) ( Addr old_ESP );
425extern VG_REGPARM(1) void MAC_(new_mem_stack_32) ( Addr old_ESP );
426extern VG_REGPARM(1) void MAC_(die_mem_stack_32) ( Addr old_ESP );
427extern void MAC_(die_mem_stack) ( Addr a, SizeT len);
428extern void MAC_(new_mem_stack) ( Addr a, SizeT len);
njn9b007f62003-04-07 14:40:25 +0000429
njn51d827b2005-05-09 01:02:08 +0000430extern void* MAC_(malloc) ( ThreadId tid, SizeT n );
431extern void* MAC_(__builtin_new) ( ThreadId tid, SizeT n );
432extern void* MAC_(__builtin_vec_new) ( ThreadId tid, SizeT n );
433extern void* MAC_(memalign) ( ThreadId tid, SizeT align, SizeT n );
434extern void* MAC_(calloc) ( ThreadId tid, SizeT nmemb, SizeT size1 );
435extern void MAC_(free) ( ThreadId tid, void* p );
436extern void MAC_(__builtin_delete) ( ThreadId tid, void* p );
437extern void MAC_(__builtin_vec_delete) ( ThreadId tid, void* p );
438extern void* MAC_(realloc) ( ThreadId tid, void* p, SizeT new_size );
njn9b007f62003-04-07 14:40:25 +0000439
440/*------------------------------------------------------------*/
441/*--- Stack pointer adjustment ---*/
442/*------------------------------------------------------------*/
443
444/* Some noble preprocessor abuse, to enable Memcheck and Addrcheck to
njn3e884182003-04-15 13:03:23 +0000445 share this code, but call different functions.
njn9b007f62003-04-07 14:40:25 +0000446
447 Note that this code is executed very frequently and must be highly
448 optimised, which is why I resort to the preprocessor to achieve the
sewardj45d94cc2005-04-20 14:44:11 +0000449 factoring, rather than eg. using function pointers.
njn9b007f62003-04-07 14:40:25 +0000450*/
451
sewardj045a4052005-04-23 22:42:27 +0000452#define SP_UPDATE_HANDLERS(ALIGNED4_NEW, ALIGNED4_DIE, \
453 ALIGNED8_NEW, ALIGNED8_DIE, \
454 UNALIGNED_NEW, UNALIGNED_DIE) \
455 \
njnaf839f52005-06-23 03:27:57 +0000456void VG_REGPARM(1) MAC_(new_mem_stack_4)(Addr new_SP) \
sewardj045a4052005-04-23 22:42:27 +0000457{ \
458 PROF_EVENT(110, "new_mem_stack_4"); \
459 if (VG_IS_4_ALIGNED(new_SP)) { \
njnaf839f52005-06-23 03:27:57 +0000460 ALIGNED4_NEW ( -VG_STACK_REDZONE_SZB + new_SP ); \
sewardj045a4052005-04-23 22:42:27 +0000461 } else { \
njnaf839f52005-06-23 03:27:57 +0000462 UNALIGNED_NEW ( -VG_STACK_REDZONE_SZB + new_SP, 4 ); \
sewardj045a4052005-04-23 22:42:27 +0000463 } \
464} \
465 \
njnaf839f52005-06-23 03:27:57 +0000466void VG_REGPARM(1) MAC_(die_mem_stack_4)(Addr new_SP) \
sewardj045a4052005-04-23 22:42:27 +0000467{ \
468 PROF_EVENT(120, "die_mem_stack_4"); \
469 if (VG_IS_4_ALIGNED(new_SP)) { \
njnaf839f52005-06-23 03:27:57 +0000470 ALIGNED4_DIE ( -VG_STACK_REDZONE_SZB + new_SP-4 ); \
sewardj045a4052005-04-23 22:42:27 +0000471 } else { \
njnaf839f52005-06-23 03:27:57 +0000472 UNALIGNED_DIE ( -VG_STACK_REDZONE_SZB + new_SP-4, 4 ); \
sewardj045a4052005-04-23 22:42:27 +0000473 } \
474} \
475 \
njnaf839f52005-06-23 03:27:57 +0000476void VG_REGPARM(1) MAC_(new_mem_stack_8)(Addr new_SP) \
sewardj045a4052005-04-23 22:42:27 +0000477{ \
478 PROF_EVENT(111, "new_mem_stack_8"); \
479 if (VG_IS_8_ALIGNED(new_SP)) { \
njnaf839f52005-06-23 03:27:57 +0000480 ALIGNED8_NEW ( -VG_STACK_REDZONE_SZB + new_SP ); \
sewardj045a4052005-04-23 22:42:27 +0000481 } else if (VG_IS_4_ALIGNED(new_SP)) { \
njnaf839f52005-06-23 03:27:57 +0000482 ALIGNED4_NEW ( -VG_STACK_REDZONE_SZB + new_SP ); \
483 ALIGNED4_NEW ( -VG_STACK_REDZONE_SZB + new_SP+4 ); \
sewardj045a4052005-04-23 22:42:27 +0000484 } else { \
njnaf839f52005-06-23 03:27:57 +0000485 UNALIGNED_NEW ( -VG_STACK_REDZONE_SZB + new_SP, 8 ); \
sewardj045a4052005-04-23 22:42:27 +0000486 } \
487} \
488 \
njnaf839f52005-06-23 03:27:57 +0000489void VG_REGPARM(1) MAC_(die_mem_stack_8)(Addr new_SP) \
sewardj045a4052005-04-23 22:42:27 +0000490{ \
491 PROF_EVENT(121, "die_mem_stack_8"); \
492 if (VG_IS_8_ALIGNED(new_SP)) { \
njnaf839f52005-06-23 03:27:57 +0000493 ALIGNED8_DIE ( -VG_STACK_REDZONE_SZB + new_SP-8 ); \
sewardj045a4052005-04-23 22:42:27 +0000494 } else if (VG_IS_4_ALIGNED(new_SP)) { \
njnaf839f52005-06-23 03:27:57 +0000495 ALIGNED4_DIE ( -VG_STACK_REDZONE_SZB + new_SP-8 ); \
496 ALIGNED4_DIE ( -VG_STACK_REDZONE_SZB + new_SP-4 ); \
sewardj045a4052005-04-23 22:42:27 +0000497 } else { \
njnaf839f52005-06-23 03:27:57 +0000498 UNALIGNED_DIE ( -VG_STACK_REDZONE_SZB + new_SP-8, 8 ); \
sewardj045a4052005-04-23 22:42:27 +0000499 } \
500} \
501 \
njnaf839f52005-06-23 03:27:57 +0000502void VG_REGPARM(1) MAC_(new_mem_stack_12)(Addr new_SP) \
sewardj045a4052005-04-23 22:42:27 +0000503{ \
504 PROF_EVENT(112, "new_mem_stack_12"); \
505 if (VG_IS_8_ALIGNED(new_SP)) { \
njnaf839f52005-06-23 03:27:57 +0000506 ALIGNED8_NEW ( -VG_STACK_REDZONE_SZB + new_SP ); \
507 ALIGNED4_NEW ( -VG_STACK_REDZONE_SZB + new_SP+8 ); \
sewardj045a4052005-04-23 22:42:27 +0000508 } else if (VG_IS_4_ALIGNED(new_SP)) { \
njnaf839f52005-06-23 03:27:57 +0000509 ALIGNED4_NEW ( -VG_STACK_REDZONE_SZB + new_SP ); \
510 ALIGNED8_NEW ( -VG_STACK_REDZONE_SZB + new_SP+4 ); \
sewardj045a4052005-04-23 22:42:27 +0000511 } else { \
njnaf839f52005-06-23 03:27:57 +0000512 UNALIGNED_NEW ( -VG_STACK_REDZONE_SZB + new_SP, 12 ); \
sewardj045a4052005-04-23 22:42:27 +0000513 } \
514} \
515 \
njnaf839f52005-06-23 03:27:57 +0000516void VG_REGPARM(1) MAC_(die_mem_stack_12)(Addr new_SP) \
sewardj045a4052005-04-23 22:42:27 +0000517{ \
518 PROF_EVENT(122, "die_mem_stack_12"); \
519 /* Note the -12 in the test */ \
520 if (VG_IS_8_ALIGNED(new_SP-12)) { \
njnaf839f52005-06-23 03:27:57 +0000521 ALIGNED8_DIE ( -VG_STACK_REDZONE_SZB + new_SP-12 ); \
522 ALIGNED4_DIE ( -VG_STACK_REDZONE_SZB + new_SP-4 ); \
sewardj045a4052005-04-23 22:42:27 +0000523 } else if (VG_IS_4_ALIGNED(new_SP)) { \
njnaf839f52005-06-23 03:27:57 +0000524 ALIGNED4_DIE ( -VG_STACK_REDZONE_SZB + new_SP-12 ); \
525 ALIGNED8_DIE ( -VG_STACK_REDZONE_SZB + new_SP-8 ); \
sewardj045a4052005-04-23 22:42:27 +0000526 } else { \
njnaf839f52005-06-23 03:27:57 +0000527 UNALIGNED_DIE ( -VG_STACK_REDZONE_SZB + new_SP-12, 12 ); \
sewardj045a4052005-04-23 22:42:27 +0000528 } \
529} \
530 \
njnaf839f52005-06-23 03:27:57 +0000531void VG_REGPARM(1) MAC_(new_mem_stack_16)(Addr new_SP) \
sewardj045a4052005-04-23 22:42:27 +0000532{ \
533 PROF_EVENT(113, "new_mem_stack_16"); \
534 if (VG_IS_8_ALIGNED(new_SP)) { \
njnaf839f52005-06-23 03:27:57 +0000535 ALIGNED8_NEW ( -VG_STACK_REDZONE_SZB + new_SP ); \
536 ALIGNED8_NEW ( -VG_STACK_REDZONE_SZB + new_SP+8 ); \
sewardj045a4052005-04-23 22:42:27 +0000537 } else if (VG_IS_4_ALIGNED(new_SP)) { \
njnaf839f52005-06-23 03:27:57 +0000538 ALIGNED4_NEW ( -VG_STACK_REDZONE_SZB + new_SP ); \
539 ALIGNED8_NEW ( -VG_STACK_REDZONE_SZB + new_SP+4 ); \
540 ALIGNED4_NEW ( -VG_STACK_REDZONE_SZB + new_SP+12 ); \
sewardj045a4052005-04-23 22:42:27 +0000541 } else { \
njnaf839f52005-06-23 03:27:57 +0000542 UNALIGNED_NEW ( -VG_STACK_REDZONE_SZB + new_SP, 16 ); \
sewardj045a4052005-04-23 22:42:27 +0000543 } \
544} \
545 \
njnaf839f52005-06-23 03:27:57 +0000546void VG_REGPARM(1) MAC_(die_mem_stack_16)(Addr new_SP) \
sewardj045a4052005-04-23 22:42:27 +0000547{ \
548 PROF_EVENT(123, "die_mem_stack_16"); \
549 if (VG_IS_8_ALIGNED(new_SP)) { \
njnaf839f52005-06-23 03:27:57 +0000550 ALIGNED8_DIE ( -VG_STACK_REDZONE_SZB + new_SP-16 ); \
551 ALIGNED8_DIE ( -VG_STACK_REDZONE_SZB + new_SP-8 ); \
sewardj045a4052005-04-23 22:42:27 +0000552 } else if (VG_IS_4_ALIGNED(new_SP)) { \
njnaf839f52005-06-23 03:27:57 +0000553 ALIGNED4_DIE ( -VG_STACK_REDZONE_SZB + new_SP-16 ); \
554 ALIGNED8_DIE ( -VG_STACK_REDZONE_SZB + new_SP-12 ); \
555 ALIGNED4_DIE ( -VG_STACK_REDZONE_SZB + new_SP-4 ); \
sewardj045a4052005-04-23 22:42:27 +0000556 } else { \
njnaf839f52005-06-23 03:27:57 +0000557 UNALIGNED_DIE ( -VG_STACK_REDZONE_SZB + new_SP-16, 16 ); \
sewardj045a4052005-04-23 22:42:27 +0000558 } \
559} \
560 \
njnaf839f52005-06-23 03:27:57 +0000561void VG_REGPARM(1) MAC_(new_mem_stack_32)(Addr new_SP) \
sewardj045a4052005-04-23 22:42:27 +0000562{ \
563 PROF_EVENT(114, "new_mem_stack_32"); \
564 if (VG_IS_8_ALIGNED(new_SP)) { \
njnaf839f52005-06-23 03:27:57 +0000565 ALIGNED8_NEW ( -VG_STACK_REDZONE_SZB + new_SP ); \
566 ALIGNED8_NEW ( -VG_STACK_REDZONE_SZB + new_SP+8 ); \
567 ALIGNED8_NEW ( -VG_STACK_REDZONE_SZB + new_SP+16 ); \
568 ALIGNED8_NEW ( -VG_STACK_REDZONE_SZB + new_SP+24 ); \
sewardj045a4052005-04-23 22:42:27 +0000569 } else if (VG_IS_4_ALIGNED(new_SP)) { \
njnaf839f52005-06-23 03:27:57 +0000570 ALIGNED4_NEW ( -VG_STACK_REDZONE_SZB + new_SP ); \
571 ALIGNED8_NEW ( -VG_STACK_REDZONE_SZB + new_SP+4 ); \
572 ALIGNED8_NEW ( -VG_STACK_REDZONE_SZB + new_SP+12 ); \
573 ALIGNED8_NEW ( -VG_STACK_REDZONE_SZB + new_SP+20 ); \
574 ALIGNED4_NEW ( -VG_STACK_REDZONE_SZB + new_SP+28 ); \
sewardj045a4052005-04-23 22:42:27 +0000575 } else { \
njnaf839f52005-06-23 03:27:57 +0000576 UNALIGNED_NEW ( -VG_STACK_REDZONE_SZB + new_SP, 32 ); \
sewardj045a4052005-04-23 22:42:27 +0000577 } \
578} \
579 \
njnaf839f52005-06-23 03:27:57 +0000580void VG_REGPARM(1) MAC_(die_mem_stack_32)(Addr new_SP) \
sewardj045a4052005-04-23 22:42:27 +0000581{ \
582 PROF_EVENT(124, "die_mem_stack_32"); \
583 if (VG_IS_8_ALIGNED(new_SP)) { \
njnaf839f52005-06-23 03:27:57 +0000584 ALIGNED8_DIE ( -VG_STACK_REDZONE_SZB + new_SP-32 ); \
585 ALIGNED8_DIE ( -VG_STACK_REDZONE_SZB + new_SP-24 ); \
586 ALIGNED8_DIE ( -VG_STACK_REDZONE_SZB + new_SP-16 ); \
587 ALIGNED8_DIE ( -VG_STACK_REDZONE_SZB + new_SP- 8 ); \
sewardj045a4052005-04-23 22:42:27 +0000588 } else if (VG_IS_4_ALIGNED(new_SP)) { \
njnaf839f52005-06-23 03:27:57 +0000589 ALIGNED4_DIE ( -VG_STACK_REDZONE_SZB + new_SP-32 ); \
590 ALIGNED8_DIE ( -VG_STACK_REDZONE_SZB + new_SP-28 ); \
591 ALIGNED8_DIE ( -VG_STACK_REDZONE_SZB + new_SP-20 ); \
592 ALIGNED8_DIE ( -VG_STACK_REDZONE_SZB + new_SP-12 ); \
593 ALIGNED4_DIE ( -VG_STACK_REDZONE_SZB + new_SP-4 ); \
sewardj045a4052005-04-23 22:42:27 +0000594 } else { \
njnaf839f52005-06-23 03:27:57 +0000595 UNALIGNED_DIE ( -VG_STACK_REDZONE_SZB + new_SP-32, 32 ); \
sewardj045a4052005-04-23 22:42:27 +0000596 } \
597} \
598 \
599void MAC_(new_mem_stack) ( Addr a, SizeT len ) \
600{ \
601 PROF_EVENT(115, "new_mem_stack"); \
njnaf839f52005-06-23 03:27:57 +0000602 UNALIGNED_NEW ( -VG_STACK_REDZONE_SZB + a, len ); \
sewardj045a4052005-04-23 22:42:27 +0000603} \
604 \
605void MAC_(die_mem_stack) ( Addr a, SizeT len ) \
606{ \
607 PROF_EVENT(125, "die_mem_stack"); \
njnaf839f52005-06-23 03:27:57 +0000608 UNALIGNED_DIE ( -VG_STACK_REDZONE_SZB + a, len ); \
njn9b007f62003-04-07 14:40:25 +0000609}
610
njn43c799e2003-04-08 00:08:52 +0000611#endif /* __MAC_SHARED_H */
njn5c004e42002-11-18 11:04:50 +0000612
613/*--------------------------------------------------------------------*/
njnc7561b92005-06-19 01:24:32 +0000614/*--- end ---*/
njn5c004e42002-11-18 11:04:50 +0000615/*--------------------------------------------------------------------*/