blob: 0947fed8424c5392d70dc862177be75c9dfde728 [file] [log] [blame]
njn5c004e42002-11-18 11:04:50 +00001
2/*--------------------------------------------------------------------*/
njn43c799e2003-04-08 00:08:52 +00003/*--- Declarations shared between MemCheck and AddrCheck. ---*/
4/*--- 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
nethercote46063202004-09-02 08:51:43 +000039#include "tool.h"
njn43c799e2003-04-08 00:08:52 +000040
41#define MAC_(str) VGAPPEND(vgMAC_,str)
njn5c004e42002-11-18 11:04:50 +000042
njn9b007f62003-04-07 14:40:25 +000043/*------------------------------------------------------------*/
44/*--- Errors and suppressions ---*/
45/*------------------------------------------------------------*/
46
njn5c004e42002-11-18 11:04:50 +000047/* The classification of a faulting address. */
48typedef
njn43c799e2003-04-08 00:08:52 +000049 enum {
nethercote8b76fe52004-11-08 19:20:09 +000050 Undescribed, // as-yet unclassified
njn43c799e2003-04-08 00:08:52 +000051 Stack,
nethercote8b76fe52004-11-08 19:20:09 +000052 Unknown, // classification yielded nothing useful
njn43c799e2003-04-08 00:08:52 +000053 Freed, Mallocd,
nethercote8b76fe52004-11-08 19:20:09 +000054 UserG, // in a user-defined block
55 Mempool, // in a mempool
56 Register, // in a register; for Param errors only
njn5c004e42002-11-18 11:04:50 +000057 }
58 AddrKind;
59
60/* Records info about a faulting address. */
61typedef
nethercote05675c82004-08-04 10:37:49 +000062 struct { // Used by:
63 AddrKind akind; // ALL
nethercote928a5f72004-11-03 18:10:37 +000064 SizeT blksize; // Freed, Mallocd
nethercote8b76fe52004-11-08 19:20:09 +000065 OffT rwoffset; // Freed, Mallocd
nethercote05675c82004-08-04 10:37:49 +000066 ExeContext* lastchange; // Freed, Mallocd
67 ThreadId stack_tid; // Stack
sewardjb5f6f512005-03-10 23:59:00 +000068 const Char *desc; // UserG
nethercote05675c82004-08-04 10:37:49 +000069 Bool maybe_gcc; // True if just below %esp -- could be a gcc bug.
njn5c004e42002-11-18 11:04:50 +000070 }
71 AddrInfo;
72
73typedef
74 enum {
nethercote05675c82004-08-04 10:37:49 +000075 ParamSupp, // Bad syscall params
76 CoreMemSupp, // Memory errors in core (pthread ops, signal handling)
77
78 // Use of invalid values of given size (MemCheck only)
njnc0616662003-06-12 09:58:41 +000079 Value0Supp, Value1Supp, Value2Supp, Value4Supp, Value8Supp, Value16Supp,
nethercote05675c82004-08-04 10:37:49 +000080
81 // Invalid read/write attempt at given size
njnc0616662003-06-12 09:58:41 +000082 Addr1Supp, Addr2Supp, Addr4Supp, Addr8Supp, Addr16Supp,
nethercote05675c82004-08-04 10:37:49 +000083
84 FreeSupp, // Invalid or mismatching free
85 OverlapSupp, // Overlapping blocks in memcpy(), strcpy(), etc
86 LeakSupp, // Something to be suppressed in a leak check.
87 MempoolSupp, // Memory pool suppression.
njn5c004e42002-11-18 11:04:50 +000088 }
njn43c799e2003-04-08 00:08:52 +000089 MAC_SuppKind;
njn5c004e42002-11-18 11:04:50 +000090
91/* What kind of error it is. */
92typedef
93 enum { ValueErr, /* Memcheck only */
94 CoreMemErr,
95 AddrErr,
96 ParamErr, UserErr, /* behaves like an anonymous ParamErr */
njn43c799e2003-04-08 00:08:52 +000097 FreeErr, FreeMismatchErr,
njn7201b2a2003-08-19 12:16:05 +000098 OverlapErr,
rjwalshbc0bb832004-06-19 18:12:36 +000099 LeakErr,
100 IllegalMempoolErr,
njn5c004e42002-11-18 11:04:50 +0000101 }
njn43c799e2003-04-08 00:08:52 +0000102 MAC_ErrorKind;
njn5c004e42002-11-18 11:04:50 +0000103
104/* What kind of memory access is involved in the error? */
105typedef
106 enum { ReadAxs, WriteAxs, ExecAxs }
107 AxsKind;
108
109/* Extra context for memory errors */
110typedef
nethercote05675c82004-08-04 10:37:49 +0000111 struct { // Used by:
112 AxsKind axskind; // AddrErr
113 Int size; // AddrErr, ValueErr
114 AddrInfo addrinfo; // {Addr,Free,FreeMismatch,Param,User}Err
nethercote8b76fe52004-11-08 19:20:09 +0000115 Bool isUnaddr; // {CoreMem,Param,User}Err
njn5c004e42002-11-18 11:04:50 +0000116 }
njn43c799e2003-04-08 00:08:52 +0000117 MAC_Error;
njn5c004e42002-11-18 11:04:50 +0000118
njnb6cae9f2003-09-04 20:50:47 +0000119/* Extra info for overlap errors */
120typedef
121 struct {
122 Addr src;
123 Addr dst;
124 Int len; // -1 if unused
125 }
126 OverlapExtra;
127
njn3e884182003-04-15 13:03:23 +0000128/* For malloc()/new/new[] vs. free()/delete/delete[] mismatch checking. */
129typedef
130 enum {
131 MAC_AllocMalloc = 0,
132 MAC_AllocNew = 1,
njn10785452003-05-20 16:38:24 +0000133 MAC_AllocNewVec = 2,
134 MAC_AllocCustom = 3
njn3e884182003-04-15 13:03:23 +0000135 }
136 MAC_AllocKind;
137
138/* Nb: first two fields must match core's VgHashNode. */
139typedef
140 struct _MAC_Chunk {
141 struct _MAC_Chunk* next;
nethercote05675c82004-08-04 10:37:49 +0000142 Addr data; // ptr to actual block
njnb729e0d2004-12-01 00:19:38 +0000143 SizeT size : (sizeof(UWord)*8)-2; // size requested; 30 or 62 bits
nethercote05675c82004-08-04 10:37:49 +0000144 MAC_AllocKind allockind : 2; // which wrapper did the allocation
145 ExeContext* where; // where it was allocated
njn3e884182003-04-15 13:03:23 +0000146 }
147 MAC_Chunk;
148
rjwalshbc0bb832004-06-19 18:12:36 +0000149/* Memory pool. Nb: first two fields must match core's VgHashNode. */
150typedef
151 struct _MAC_Mempool {
152 struct _MAC_Mempool* next;
nethercote05675c82004-08-04 10:37:49 +0000153 Addr pool; // pool identifier
njnb729e0d2004-12-01 00:19:38 +0000154 SizeT rzB; // pool red-zone size
nethercote05675c82004-08-04 10:37:49 +0000155 Bool is_zeroed; // allocations from this pool are zeroed
156 VgHashTable chunks; // chunks associated with this pool
rjwalshbc0bb832004-06-19 18:12:36 +0000157 }
158 MAC_Mempool;
159
160
njn9b007f62003-04-07 14:40:25 +0000161/*------------------------------------------------------------*/
nethercote7cc9c232004-01-21 15:08:04 +0000162/*--- Profiling of tools and memory events ---*/
njn9b007f62003-04-07 14:40:25 +0000163/*------------------------------------------------------------*/
164
165typedef
166 enum {
167 VgpCheckMem = VgpFini+1,
168 VgpSetMem,
169 VgpESPAdj
170 }
nethercote7cc9c232004-01-21 15:08:04 +0000171 VgpToolCC;
njn9b007f62003-04-07 14:40:25 +0000172
173/* Define to collect detailed performance info. */
njn43c799e2003-04-08 00:08:52 +0000174/* #define MAC_PROFILE_MEMORY */
njn5c004e42002-11-18 11:04:50 +0000175
njn43c799e2003-04-08 00:08:52 +0000176#ifdef MAC_PROFILE_MEMORY
njn9b007f62003-04-07 14:40:25 +0000177# define N_PROF_EVENTS 150
njn5c004e42002-11-18 11:04:50 +0000178
njn43c799e2003-04-08 00:08:52 +0000179extern UInt MAC_(event_ctr)[N_PROF_EVENTS];
njn9b007f62003-04-07 14:40:25 +0000180
njn43c799e2003-04-08 00:08:52 +0000181# define PROF_EVENT(ev) \
njnca82cc02004-11-22 17:18:48 +0000182 do { tl_assert((ev) >= 0 && (ev) < N_PROF_EVENTS); \
njn43c799e2003-04-08 00:08:52 +0000183 MAC_(event_ctr)[ev]++; \
njn5c004e42002-11-18 11:04:50 +0000184 } while (False);
185
186#else
187
njn9b007f62003-04-07 14:40:25 +0000188# define PROF_EVENT(ev) /* */
njn5c004e42002-11-18 11:04:50 +0000189
njn43c799e2003-04-08 00:08:52 +0000190#endif /* MAC_PROFILE_MEMORY */
njn5c004e42002-11-18 11:04:50 +0000191
njn9b007f62003-04-07 14:40:25 +0000192/*------------------------------------------------------------*/
193/*--- V and A bits ---*/
194/*------------------------------------------------------------*/
195
sewardjb5f6f512005-03-10 23:59:00 +0000196/* expand 1 bit -> 8 */
197#define BIT_EXPAND(b) ((~(((UChar)(b) & 1) - 1)) & 0xFF)
198
199#define SECONDARY_SHIFT 16
200#define SECONDARY_SIZE (1 << SECONDARY_SHIFT)
201#define SECONDARY_MASK (SECONDARY_SIZE - 1)
202
203#define PRIMARY_SIZE (1 << (32 - SECONDARY_SHIFT))
204
205#define SM_OFF(addr) ((addr) & SECONDARY_MASK)
206#define PM_IDX(addr) ((addr) >> SECONDARY_SHIFT)
207
208#define IS_DISTINGUISHED_SM(smap) \
209 ((smap) >= &distinguished_secondary_maps[0] && \
210 (smap) < &distinguished_secondary_maps[N_SECONDARY_MAPS])
211
212#define IS_DISTINGUISHED(addr) (IS_DISTINGUISHED_SM(primary_map[PM_IDX(addr)]))
njn5c004e42002-11-18 11:04:50 +0000213
njn43c799e2003-04-08 00:08:52 +0000214#define ENSURE_MAPPABLE(addr,caller) \
215 do { \
sewardjb5f6f512005-03-10 23:59:00 +0000216 if (IS_DISTINGUISHED(addr)) { \
217 primary_map[PM_IDX(addr)] = alloc_secondary_map(caller, primary_map[PM_IDX(addr)]); \
njn43c799e2003-04-08 00:08:52 +0000218 /* VG_(printf)("new 2map because of %p\n", addr); */ \
219 } \
njn5c004e42002-11-18 11:04:50 +0000220 } while(0)
221
222#define BITARR_SET(aaa_p,iii_p) \
223 do { \
224 UInt iii = (UInt)iii_p; \
225 UChar* aaa = (UChar*)aaa_p; \
226 aaa[iii >> 3] |= (1 << (iii & 7)); \
227 } while (0)
228
229#define BITARR_CLEAR(aaa_p,iii_p) \
230 do { \
231 UInt iii = (UInt)iii_p; \
232 UChar* aaa = (UChar*)aaa_p; \
233 aaa[iii >> 3] &= ~(1 << (iii & 7)); \
234 } while (0)
235
236#define BITARR_TEST(aaa_p,iii_p) \
237 (0 != (((UChar*)aaa_p)[ ((UInt)iii_p) >> 3 ] \
238 & (1 << (((UInt)iii_p) & 7)))) \
239
240
241#define VGM_BIT_VALID 0
242#define VGM_BIT_INVALID 1
243
244#define VGM_NIBBLE_VALID 0
245#define VGM_NIBBLE_INVALID 0xF
246
247#define VGM_BYTE_VALID 0
248#define VGM_BYTE_INVALID 0xFF
249
250#define VGM_WORD_VALID 0
251#define VGM_WORD_INVALID 0xFFFFFFFF
252
sewardj95448072004-11-22 20:19:51 +0000253#define VGM_WORD64_VALID 0x0ULL
254#define VGM_WORD64_INVALID 0xFFFFFFFFFFFFFFFFULL
njn5c004e42002-11-18 11:04:50 +0000255
256/*------------------------------------------------------------*/
257/*--- Command line options + defaults ---*/
258/*------------------------------------------------------------*/
259
njn43c799e2003-04-08 00:08:52 +0000260/* Memcheck defines a couple more. */
njn5c004e42002-11-18 11:04:50 +0000261
262/* Allow loads from partially-valid addresses? default: YES */
njn43c799e2003-04-08 00:08:52 +0000263extern Bool MAC_(clo_partial_loads_ok);
njn5c004e42002-11-18 11:04:50 +0000264
265/* Max volume of the freed blocks queue. */
njn43c799e2003-04-08 00:08:52 +0000266extern Int MAC_(clo_freelist_vol);
njn5c004e42002-11-18 11:04:50 +0000267
268/* Do leak check at exit? default: NO */
sewardjb5f6f512005-03-10 23:59:00 +0000269typedef
270 enum {
271 LC_Off,
272 LC_Summary,
273 LC_Full,
274 }
275 LeakCheckMode;
276
277extern LeakCheckMode MAC_(clo_leak_check);
njn5c004e42002-11-18 11:04:50 +0000278
279/* How closely should we compare ExeContexts in leak records? default: 2 */
njn43c799e2003-04-08 00:08:52 +0000280extern VgRes MAC_(clo_leak_resolution);
njn5c004e42002-11-18 11:04:50 +0000281
282/* In leak check, show reachable-but-not-freed blocks? default: NO */
njn43c799e2003-04-08 00:08:52 +0000283extern Bool MAC_(clo_show_reachable);
njn5c004e42002-11-18 11:04:50 +0000284
285/* Assume accesses immediately below %esp are due to gcc-2.96 bugs.
286 * default: NO*/
njn43c799e2003-04-08 00:08:52 +0000287extern Bool MAC_(clo_workaround_gcc296_bugs);
njn5c004e42002-11-18 11:04:50 +0000288
njn3e884182003-04-15 13:03:23 +0000289extern Bool MAC_(process_common_cmd_line_option) ( Char* arg );
290extern void MAC_(print_common_usage) ( void );
291extern void MAC_(print_common_debug_usage) ( void );
292
293
294/*------------------------------------------------------------*/
295/*--- Variables ---*/
296/*------------------------------------------------------------*/
297
298/* For tracking malloc'd blocks */
299extern VgHashTable MAC_(malloc_list);
300
rjwalshbc0bb832004-06-19 18:12:36 +0000301/* For tracking memory pools. */
302extern VgHashTable MAC_(mempool_list);
303
nethercote7cc9c232004-01-21 15:08:04 +0000304/* Function pointers for the two tools to track interesting events. */
nethercote451eae92004-11-02 13:06:32 +0000305extern void (*MAC_(new_mem_heap)) ( Addr a, SizeT len, Bool is_inited );
306extern void (*MAC_(ban_mem_heap)) ( Addr a, SizeT len );
307extern void (*MAC_(die_mem_heap)) ( Addr a, SizeT len );
308extern void (*MAC_(copy_mem_heap))( Addr from, Addr to, SizeT len );
njn3e884182003-04-15 13:03:23 +0000309
sewardjecf8e102003-07-12 12:11:39 +0000310/* Function pointers for internal sanity checking. */
nethercote451eae92004-11-02 13:06:32 +0000311extern Bool (*MAC_(check_noaccess))( Addr a, SizeT len, Addr* bad_addr );
sewardjecf8e102003-07-12 12:11:39 +0000312
njn3e884182003-04-15 13:03:23 +0000313/* Used in describe_addr() */
314extern Bool (*MAC_(describe_addr_supp)) ( Addr a, AddrInfo* ai );
njn5c004e42002-11-18 11:04:50 +0000315
njn47363ab2003-04-21 13:24:40 +0000316/* For VALGRIND_COUNT_LEAKS client request */
njne8b5c052003-07-22 22:03:58 +0000317extern Int MAC_(bytes_leaked);
sewardjb5f6f512005-03-10 23:59:00 +0000318extern Int MAC_(bytes_indirect);
njne8b5c052003-07-22 22:03:58 +0000319extern Int MAC_(bytes_dubious);
320extern Int MAC_(bytes_reachable);
321extern Int MAC_(bytes_suppressed);
sewardj99aac972002-12-26 01:53:45 +0000322
njn5c004e42002-11-18 11:04:50 +0000323/*------------------------------------------------------------*/
324/*--- Functions ---*/
325/*------------------------------------------------------------*/
326
njn43c799e2003-04-08 00:08:52 +0000327extern void MAC_(pp_AddrInfo) ( Addr a, AddrInfo* ai );
njn5c004e42002-11-18 11:04:50 +0000328
njn43c799e2003-04-08 00:08:52 +0000329extern void MAC_(clear_MAC_Error) ( MAC_Error* err_extra );
njn5c004e42002-11-18 11:04:50 +0000330
njn43c799e2003-04-08 00:08:52 +0000331extern Bool MAC_(shared_recognised_suppression) ( Char* name, Supp* su );
njn5c004e42002-11-18 11:04:50 +0000332
sewardj2a99cf62004-11-24 10:44:19 +0000333extern void* MAC_(new_block) ( ThreadId tid,
334 Addr p, SizeT size, SizeT align, UInt rzB,
nethercote57e36b32004-07-10 14:56:28 +0000335 Bool is_zeroed, MAC_AllocKind kind,
336 VgHashTable table);
sewardj2a99cf62004-11-24 10:44:19 +0000337
338extern void MAC_(handle_free) ( ThreadId tid,
339 Addr p, UInt rzB, MAC_AllocKind kind );
njn10785452003-05-20 16:38:24 +0000340
rjwalshbc0bb832004-06-19 18:12:36 +0000341extern void MAC_(create_mempool)(Addr pool, UInt rzB, Bool is_zeroed);
sewardj2a99cf62004-11-24 10:44:19 +0000342
rjwalshbc0bb832004-06-19 18:12:36 +0000343extern void MAC_(destroy_mempool)(Addr pool);
sewardj2a99cf62004-11-24 10:44:19 +0000344
345extern void MAC_(mempool_alloc)(ThreadId tid,
346 Addr pool, Addr addr, SizeT size);
347
rjwalshbc0bb832004-06-19 18:12:36 +0000348extern void MAC_(mempool_free)(Addr pool, Addr addr);
349
njn72718642003-07-24 08:45:32 +0000350extern void MAC_(record_address_error) ( ThreadId tid, Addr a,
sewardjaf48a602003-07-06 00:54:47 +0000351 Int size, Bool isWrite );
nethercote8b76fe52004-11-08 19:20:09 +0000352extern void MAC_(record_core_mem_error) ( ThreadId tid, Bool isUnaddr,
njn43c799e2003-04-08 00:08:52 +0000353 Char* s );
nethercote8b76fe52004-11-08 19:20:09 +0000354extern void MAC_(record_param_error) ( ThreadId tid, Addr a, Bool isReg,
355 Bool isUnaddr, Char* msg );
njn72718642003-07-24 08:45:32 +0000356extern void MAC_(record_jump_error) ( ThreadId tid, Addr a );
357extern void MAC_(record_free_error) ( ThreadId tid, Addr a );
358extern void MAC_(record_freemismatch_error)( ThreadId tid, Addr a );
sewardj2a99cf62004-11-24 10:44:19 +0000359extern void MAC_(record_overlap_error) ( ThreadId tid,
360 Char* function, OverlapExtra* oe );
rjwalshbc0bb832004-06-19 18:12:36 +0000361extern void MAC_(record_illegal_mempool_error) ( ThreadId tid, Addr pool );
njn5c004e42002-11-18 11:04:50 +0000362
njnb126f732004-11-22 17:57:07 +0000363extern void MAC_(pp_shared_Error) ( Error* err);
njn43c799e2003-04-08 00:08:52 +0000364
thughes4ad52d02004-06-27 17:37:21 +0000365extern MAC_Chunk* MAC_(first_matching_freed_MAC_Chunk)( Bool (*p)(MAC_Chunk*, void*), void* d );
njn43c799e2003-04-08 00:08:52 +0000366
njn3e884182003-04-15 13:03:23 +0000367extern void MAC_(common_pre_clo_init) ( void );
njnb8dca862005-03-14 02:42:44 +0000368extern void MAC_(common_fini) ( void (*leak_check)(ThreadId tid,
369 LeakCheckMode mode) );
njn3e884182003-04-15 13:03:23 +0000370
njn72718642003-07-24 08:45:32 +0000371extern Bool MAC_(handle_common_client_requests) ( ThreadId tid,
nethercoted1b64b22004-11-04 18:22:28 +0000372 UWord* arg_block, UWord* ret );
njn47363ab2003-04-21 13:24:40 +0000373
njn43c799e2003-04-08 00:08:52 +0000374/* For leak checking */
375extern void MAC_(pp_LeakError)(void* vl, UInt n_this_record,
376 UInt n_total_records);
377
njn86f12dc2005-03-14 01:16:05 +0000378extern void MAC_(print_malloc_stats) ( void );
379
njn43c799e2003-04-08 00:08:52 +0000380extern void MAC_(do_detect_memory_leaks) (
njnb8dca862005-03-14 02:42:44 +0000381 ThreadId tid, LeakCheckMode mode,
sewardjb5f6f512005-03-10 23:59:00 +0000382 Bool (*is_valid_64k_chunk) ( UInt ),
383 Bool (*is_valid_address) ( Addr )
njn43c799e2003-04-08 00:08:52 +0000384 );
385
nethercoteeec46302004-08-23 15:06:23 +0000386extern REGPARM(1) void MAC_(new_mem_stack_4) ( Addr old_ESP );
387extern REGPARM(1) void MAC_(die_mem_stack_4) ( Addr old_ESP );
388extern REGPARM(1) void MAC_(new_mem_stack_8) ( Addr old_ESP );
389extern REGPARM(1) void MAC_(die_mem_stack_8) ( Addr old_ESP );
390extern REGPARM(1) void MAC_(new_mem_stack_12) ( Addr old_ESP );
391extern REGPARM(1) void MAC_(die_mem_stack_12) ( Addr old_ESP );
392extern REGPARM(1) void MAC_(new_mem_stack_16) ( Addr old_ESP );
393extern REGPARM(1) void MAC_(die_mem_stack_16) ( Addr old_ESP );
394extern REGPARM(1) void MAC_(new_mem_stack_32) ( Addr old_ESP );
395extern REGPARM(1) void MAC_(die_mem_stack_32) ( Addr old_ESP );
nethercote451eae92004-11-02 13:06:32 +0000396extern void MAC_(die_mem_stack) ( Addr a, SizeT len);
397extern void MAC_(new_mem_stack) ( Addr a, SizeT len);
njn9b007f62003-04-07 14:40:25 +0000398
399
400/*------------------------------------------------------------*/
401/*--- Stack pointer adjustment ---*/
402/*------------------------------------------------------------*/
403
404/* Some noble preprocessor abuse, to enable Memcheck and Addrcheck to
njn3e884182003-04-15 13:03:23 +0000405 share this code, but call different functions.
njn9b007f62003-04-07 14:40:25 +0000406
407 Note that this code is executed very frequently and must be highly
408 optimised, which is why I resort to the preprocessor to achieve the
409 factoring, rather than eg. using function pointers.
410*/
411
412#define ESP_UPDATE_HANDLERS(ALIGNED4_NEW, ALIGNED4_DIE, \
413 ALIGNED8_NEW, ALIGNED8_DIE, \
414 UNALIGNED_NEW, UNALIGNED_DIE) \
415 \
nethercoteeec46302004-08-23 15:06:23 +0000416void REGPARM(1) MAC_(new_mem_stack_4)(Addr new_ESP) \
njn9b007f62003-04-07 14:40:25 +0000417{ \
418 PROF_EVENT(110); \
njnedfa0f62004-11-30 18:08:05 +0000419 if (IS_4_ALIGNED(new_ESP)) { \
njn9b007f62003-04-07 14:40:25 +0000420 ALIGNED4_NEW ( new_ESP ); \
421 } else { \
422 UNALIGNED_NEW ( new_ESP, 4 ); \
423 } \
424} \
425 \
nethercoteeec46302004-08-23 15:06:23 +0000426void REGPARM(1) MAC_(die_mem_stack_4)(Addr new_ESP) \
njn9b007f62003-04-07 14:40:25 +0000427{ \
428 PROF_EVENT(120); \
njnedfa0f62004-11-30 18:08:05 +0000429 if (IS_4_ALIGNED(new_ESP)) { \
njn9b007f62003-04-07 14:40:25 +0000430 ALIGNED4_DIE ( new_ESP-4 ); \
431 } else { \
432 UNALIGNED_DIE ( new_ESP-4, 4 ); \
433 } \
434} \
435 \
nethercoteeec46302004-08-23 15:06:23 +0000436void REGPARM(1) MAC_(new_mem_stack_8)(Addr new_ESP) \
njn9b007f62003-04-07 14:40:25 +0000437{ \
438 PROF_EVENT(111); \
njnedfa0f62004-11-30 18:08:05 +0000439 if (IS_8_ALIGNED(new_ESP)) { \
njn9b007f62003-04-07 14:40:25 +0000440 ALIGNED8_NEW ( new_ESP ); \
njnedfa0f62004-11-30 18:08:05 +0000441 } else if (IS_4_ALIGNED(new_ESP)) { \
njn9b007f62003-04-07 14:40:25 +0000442 ALIGNED4_NEW ( new_ESP ); \
443 ALIGNED4_NEW ( new_ESP+4 ); \
444 } else { \
445 UNALIGNED_NEW ( new_ESP, 8 ); \
446 } \
447} \
448 \
nethercoteeec46302004-08-23 15:06:23 +0000449void REGPARM(1) MAC_(die_mem_stack_8)(Addr new_ESP) \
njn9b007f62003-04-07 14:40:25 +0000450{ \
451 PROF_EVENT(121); \
njnedfa0f62004-11-30 18:08:05 +0000452 if (IS_8_ALIGNED(new_ESP)) { \
njn9b007f62003-04-07 14:40:25 +0000453 ALIGNED8_DIE ( new_ESP-8 ); \
njnedfa0f62004-11-30 18:08:05 +0000454 } else if (IS_4_ALIGNED(new_ESP)) { \
njn9b007f62003-04-07 14:40:25 +0000455 ALIGNED4_DIE ( new_ESP-8 ); \
456 ALIGNED4_DIE ( new_ESP-4 ); \
457 } else { \
458 UNALIGNED_DIE ( new_ESP-8, 8 ); \
459 } \
460} \
461 \
nethercoteeec46302004-08-23 15:06:23 +0000462void REGPARM(1) MAC_(new_mem_stack_12)(Addr new_ESP) \
njn9b007f62003-04-07 14:40:25 +0000463{ \
464 PROF_EVENT(112); \
njnedfa0f62004-11-30 18:08:05 +0000465 if (IS_8_ALIGNED(new_ESP)) { \
njn9b007f62003-04-07 14:40:25 +0000466 ALIGNED8_NEW ( new_ESP ); \
467 ALIGNED4_NEW ( new_ESP+8 ); \
njnedfa0f62004-11-30 18:08:05 +0000468 } else if (IS_4_ALIGNED(new_ESP)) { \
njn9b007f62003-04-07 14:40:25 +0000469 ALIGNED4_NEW ( new_ESP ); \
470 ALIGNED8_NEW ( new_ESP+4 ); \
471 } else { \
472 UNALIGNED_NEW ( new_ESP, 12 ); \
473 } \
474} \
475 \
nethercoteeec46302004-08-23 15:06:23 +0000476void REGPARM(1) MAC_(die_mem_stack_12)(Addr new_ESP) \
njn9b007f62003-04-07 14:40:25 +0000477{ \
478 PROF_EVENT(122); \
479 /* Note the -12 in the test */ \
njnedfa0f62004-11-30 18:08:05 +0000480 if (IS_8_ALIGNED(new_ESP-12)) { \
njn9b007f62003-04-07 14:40:25 +0000481 ALIGNED8_DIE ( new_ESP-12 ); \
482 ALIGNED4_DIE ( new_ESP-4 ); \
njnedfa0f62004-11-30 18:08:05 +0000483 } else if (IS_4_ALIGNED(new_ESP)) { \
njn9b007f62003-04-07 14:40:25 +0000484 ALIGNED4_DIE ( new_ESP-12 ); \
485 ALIGNED8_DIE ( new_ESP-8 ); \
486 } else { \
487 UNALIGNED_DIE ( new_ESP-12, 12 ); \
488 } \
489} \
490 \
nethercoteeec46302004-08-23 15:06:23 +0000491void REGPARM(1) MAC_(new_mem_stack_16)(Addr new_ESP) \
njn9b007f62003-04-07 14:40:25 +0000492{ \
493 PROF_EVENT(113); \
njnedfa0f62004-11-30 18:08:05 +0000494 if (IS_8_ALIGNED(new_ESP)) { \
njn9b007f62003-04-07 14:40:25 +0000495 ALIGNED8_NEW ( new_ESP ); \
496 ALIGNED8_NEW ( new_ESP+8 ); \
njnedfa0f62004-11-30 18:08:05 +0000497 } else if (IS_4_ALIGNED(new_ESP)) { \
njn9b007f62003-04-07 14:40:25 +0000498 ALIGNED4_NEW ( new_ESP ); \
499 ALIGNED8_NEW ( new_ESP+4 ); \
500 ALIGNED4_NEW ( new_ESP+12 ); \
501 } else { \
502 UNALIGNED_NEW ( new_ESP, 16 ); \
503 } \
504} \
505 \
nethercoteeec46302004-08-23 15:06:23 +0000506void REGPARM(1) MAC_(die_mem_stack_16)(Addr new_ESP) \
njn9b007f62003-04-07 14:40:25 +0000507{ \
508 PROF_EVENT(123); \
njnedfa0f62004-11-30 18:08:05 +0000509 if (IS_8_ALIGNED(new_ESP)) { \
njn9b007f62003-04-07 14:40:25 +0000510 ALIGNED8_DIE ( new_ESP-16 ); \
511 ALIGNED8_DIE ( new_ESP-8 ); \
njnedfa0f62004-11-30 18:08:05 +0000512 } else if (IS_4_ALIGNED(new_ESP)) { \
njn9b007f62003-04-07 14:40:25 +0000513 ALIGNED4_DIE ( new_ESP-16 ); \
514 ALIGNED8_DIE ( new_ESP-12 ); \
515 ALIGNED4_DIE ( new_ESP-4 ); \
516 } else { \
517 UNALIGNED_DIE ( new_ESP-16, 16 ); \
518 } \
519} \
520 \
nethercoteeec46302004-08-23 15:06:23 +0000521void REGPARM(1) MAC_(new_mem_stack_32)(Addr new_ESP) \
njn9b007f62003-04-07 14:40:25 +0000522{ \
523 PROF_EVENT(114); \
njnedfa0f62004-11-30 18:08:05 +0000524 if (IS_8_ALIGNED(new_ESP)) { \
njn9b007f62003-04-07 14:40:25 +0000525 ALIGNED8_NEW ( new_ESP ); \
526 ALIGNED8_NEW ( new_ESP+8 ); \
527 ALIGNED8_NEW ( new_ESP+16 ); \
528 ALIGNED8_NEW ( new_ESP+24 ); \
njnedfa0f62004-11-30 18:08:05 +0000529 } else if (IS_4_ALIGNED(new_ESP)) { \
njn9b007f62003-04-07 14:40:25 +0000530 ALIGNED4_NEW ( new_ESP ); \
531 ALIGNED8_NEW ( new_ESP+4 ); \
532 ALIGNED8_NEW ( new_ESP+12 ); \
533 ALIGNED8_NEW ( new_ESP+20 ); \
534 ALIGNED4_NEW ( new_ESP+28 ); \
535 } else { \
536 UNALIGNED_NEW ( new_ESP, 32 ); \
537 } \
538} \
539 \
nethercoteeec46302004-08-23 15:06:23 +0000540void REGPARM(1) MAC_(die_mem_stack_32)(Addr new_ESP) \
njn9b007f62003-04-07 14:40:25 +0000541{ \
542 PROF_EVENT(124); \
njnedfa0f62004-11-30 18:08:05 +0000543 if (IS_8_ALIGNED(new_ESP)) { \
njn9b007f62003-04-07 14:40:25 +0000544 ALIGNED8_DIE ( new_ESP-32 ); \
545 ALIGNED8_DIE ( new_ESP-24 ); \
546 ALIGNED8_DIE ( new_ESP-16 ); \
547 ALIGNED8_DIE ( new_ESP- 8 ); \
njnedfa0f62004-11-30 18:08:05 +0000548 } else if (IS_4_ALIGNED(new_ESP)) { \
njn9b007f62003-04-07 14:40:25 +0000549 ALIGNED4_DIE ( new_ESP-32 ); \
550 ALIGNED8_DIE ( new_ESP-28 ); \
551 ALIGNED8_DIE ( new_ESP-20 ); \
552 ALIGNED8_DIE ( new_ESP-12 ); \
553 ALIGNED4_DIE ( new_ESP-4 ); \
554 } else { \
555 UNALIGNED_DIE ( new_ESP-32, 32 ); \
556 } \
557} \
558 \
nethercote451eae92004-11-02 13:06:32 +0000559void MAC_(new_mem_stack) ( Addr a, SizeT len ) \
njn9b007f62003-04-07 14:40:25 +0000560{ \
561 PROF_EVENT(115); \
562 UNALIGNED_NEW ( a, len ); \
563} \
564 \
nethercote451eae92004-11-02 13:06:32 +0000565void MAC_(die_mem_stack) ( Addr a, SizeT len ) \
njn9b007f62003-04-07 14:40:25 +0000566{ \
567 PROF_EVENT(125); \
568 UNALIGNED_DIE ( a, len ); \
569}
570
njn43c799e2003-04-08 00:08:52 +0000571#endif /* __MAC_SHARED_H */
njn5c004e42002-11-18 11:04:50 +0000572
573/*--------------------------------------------------------------------*/
njn43c799e2003-04-08 00:08:52 +0000574/*--- end mac_shared.h ---*/
njn5c004e42002-11-18 11:04:50 +0000575/*--------------------------------------------------------------------*/