blob: cd8eba12fa386272b6661f751d8aad4bcbf46967 [file] [log] [blame]
sewardjde4a1d02002-03-22 01:27:54 +00001
2/*--------------------------------------------------------------------*/
3/*--- Maintain bitmaps of memory, tracking the accessibility (A) ---*/
4/*--- and validity (V) status of each byte. ---*/
5/*--- vg_memory.c ---*/
6/*--------------------------------------------------------------------*/
7
8/*
9 This file is part of Valgrind, an x86 protected-mode emulator
10 designed for debugging and profiling binaries on x86-Unixes.
11
12 Copyright (C) 2000-2002 Julian Seward
13 jseward@acm.org
sewardjde4a1d02002-03-22 01:27:54 +000014
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 LICENSE.
31*/
32
33#include "vg_include.h"
34
35/* Define to debug the mem audit system. */
36/* #define VG_DEBUG_MEMORY */
37
38/* Define to debug the memory-leak-detector. */
39/* #define VG_DEBUG_LEAKCHECK */
40
41/* Define to collect detailed performance info. */
42/* #define VG_PROFILE_MEMORY */
43
44
45/*------------------------------------------------------------*/
46/*--- Low-level support for memory checking. ---*/
47/*------------------------------------------------------------*/
48
49/*
50 All reads and writes are checked against a memory map, which
51 records the state of all memory in the process. The memory map is
52 organised like this:
53
54 The top 16 bits of an address are used to index into a top-level
55 map table, containing 65536 entries. Each entry is a pointer to a
56 second-level map, which records the accesibililty and validity
57 permissions for the 65536 bytes indexed by the lower 16 bits of the
58 address. Each byte is represented by nine bits, one indicating
59 accessibility, the other eight validity. So each second-level map
60 contains 73728 bytes. This two-level arrangement conveniently
61 divides the 4G address space into 64k lumps, each size 64k bytes.
62
63 All entries in the primary (top-level) map must point to a valid
64 secondary (second-level) map. Since most of the 4G of address
65 space will not be in use -- ie, not mapped at all -- there is a
66 distinguished secondary map, which indicates `not addressible and
67 not valid' writeable for all bytes. Entries in the primary map for
68 which the entire 64k is not in use at all point at this
69 distinguished map.
70
71 [...] lots of stuff deleted due to out of date-ness
72
73 As a final optimisation, the alignment and address checks for
74 4-byte loads and stores are combined in a neat way. The primary
75 map is extended to have 262144 entries (2^18), rather than 2^16.
76 The top 3/4 of these entries are permanently set to the
77 distinguished secondary map. For a 4-byte load/store, the
78 top-level map is indexed not with (addr >> 16) but instead f(addr),
79 where
80
81 f( XXXX XXXX XXXX XXXX ____ ____ ____ __YZ )
82 = ____ ____ ____ __YZ XXXX XXXX XXXX XXXX or
83 = ____ ____ ____ __ZY XXXX XXXX XXXX XXXX
84
85 ie the lowest two bits are placed above the 16 high address bits.
86 If either of these two bits are nonzero, the address is misaligned;
87 this will select a secondary map from the upper 3/4 of the primary
88 map. Because this is always the distinguished secondary map, a
89 (bogus) address check failure will result. The failure handling
90 code can then figure out whether this is a genuine addr check
91 failure or whether it is a possibly-legitimate access at a
92 misaligned address.
93*/
94
95
96/*------------------------------------------------------------*/
97/*--- Crude profiling machinery. ---*/
98/*------------------------------------------------------------*/
99
100#ifdef VG_PROFILE_MEMORY
101
sewardj4f51f9a2002-05-07 23:38:30 +0000102#define N_PROF_EVENTS 150
sewardjde4a1d02002-03-22 01:27:54 +0000103
104static UInt event_ctr[N_PROF_EVENTS];
105
106static void init_prof_mem ( void )
107{
108 Int i;
109 for (i = 0; i < N_PROF_EVENTS; i++)
110 event_ctr[i] = 0;
111}
112
113void VG_(done_prof_mem) ( void )
114{
115 Int i;
116 for (i = 0; i < N_PROF_EVENTS; i++) {
117 if ((i % 10) == 0)
118 VG_(printf)("\n");
119 if (event_ctr[i] > 0)
120 VG_(printf)( "prof mem event %2d: %d\n", i, event_ctr[i] );
121 }
122 VG_(printf)("\n");
123}
124
125#define PROF_EVENT(ev) \
126 do { vg_assert((ev) >= 0 && (ev) < N_PROF_EVENTS); \
127 event_ctr[ev]++; \
128 } while (False);
129
130#else
131
132static void init_prof_mem ( void ) { }
133 void VG_(done_prof_mem) ( void ) { }
134
135#define PROF_EVENT(ev) /* */
136
137#endif
138
139/* Event index. If just the name of the fn is given, this means the
140 number of calls to the fn. Otherwise it is the specified event.
141
142 10 alloc_secondary_map
143
144 20 get_abit
145 21 get_vbyte
146 22 set_abit
147 23 set_vbyte
148 24 get_abits4_ALIGNED
149 25 get_vbytes4_ALIGNED
150
151 30 set_address_range_perms
152 31 set_address_range_perms(lower byte loop)
153 32 set_address_range_perms(quadword loop)
154 33 set_address_range_perms(upper byte loop)
155
156 35 make_noaccess
157 36 make_writable
158 37 make_readable
159
160 40 copy_address_range_perms
161 41 copy_address_range_perms(byte loop)
162 42 check_writable
163 43 check_writable(byte loop)
164 44 check_readable
165 45 check_readable(byte loop)
166 46 check_readable_asciiz
167 47 check_readable_asciiz(byte loop)
168
169 50 make_aligned_word_NOACCESS
170 51 make_aligned_word_WRITABLE
171
172 60 helperc_LOADV4
173 61 helperc_STOREV4
174 62 helperc_LOADV2
175 63 helperc_STOREV2
176 64 helperc_LOADV1
177 65 helperc_STOREV1
178
179 70 rim_rd_V4_SLOWLY
180 71 rim_wr_V4_SLOWLY
181 72 rim_rd_V2_SLOWLY
182 73 rim_wr_V2_SLOWLY
183 74 rim_rd_V1_SLOWLY
184 75 rim_wr_V1_SLOWLY
185
186 80 fpu_read
187 81 fpu_read aligned 4
188 82 fpu_read aligned 8
189 83 fpu_read 2
190 84 fpu_read 10
191
192 85 fpu_write
193 86 fpu_write aligned 4
194 87 fpu_write aligned 8
195 88 fpu_write 2
196 89 fpu_write 10
197
198 90 fpu_read_check_SLOWLY
199 91 fpu_read_check_SLOWLY(byte loop)
200 92 fpu_write_check_SLOWLY
201 93 fpu_write_check_SLOWLY(byte loop)
202
203 100 is_plausible_stack_addr
204 101 handle_esp_assignment
205 102 handle_esp_assignment(-4)
206 103 handle_esp_assignment(+4)
sewardj4f51f9a2002-05-07 23:38:30 +0000207 104 handle_esp_assignment(-12)
208 105 handle_esp_assignment(-8)
209 106 handle_esp_assignment(+16)
210 107 handle_esp_assignment(+12)
211 108 handle_esp_assignment(0)
212 109 handle_esp_assignment(+8)
213 110 handle_esp_assignment(-16)
214 111 handle_esp_assignment(+20)
215 112 handle_esp_assignment(-20)
216 113 handle_esp_assignment(+24)
217 114 handle_esp_assignment(-24)
sewardjde4a1d02002-03-22 01:27:54 +0000218
sewardj4f51f9a2002-05-07 23:38:30 +0000219 120 vg_handle_esp_assignment_SLOWLY
220 121 vg_handle_esp_assignment_SLOWLY(normal; move down)
221 122 vg_handle_esp_assignment_SLOWLY(normal; move up)
222 123 vg_handle_esp_assignment_SLOWLY(normal)
223 124 vg_handle_esp_assignment_SLOWLY(>= HUGE_DELTA)
sewardjde4a1d02002-03-22 01:27:54 +0000224*/
225
226/*------------------------------------------------------------*/
227/*--- Function declarations. ---*/
228/*------------------------------------------------------------*/
229
230/* Set permissions for an address range. Not speed-critical. */
231void VGM_(make_noaccess) ( Addr a, UInt len );
232void VGM_(make_writable) ( Addr a, UInt len );
233void VGM_(make_readable) ( Addr a, UInt len );
234
235/* Check permissions for an address range. Not speed-critical. */
236Bool VGM_(check_writable) ( Addr a, UInt len, Addr* bad_addr );
237Bool VGM_(check_readable) ( Addr a, UInt len, Addr* bad_addr );
238Bool VGM_(check_readable_asciiz) ( Addr a, Addr* bad_addr );
239
240static UInt vgm_rd_V4_SLOWLY ( Addr a );
241static UInt vgm_rd_V2_SLOWLY ( Addr a );
242static UInt vgm_rd_V1_SLOWLY ( Addr a );
243static void vgm_wr_V4_SLOWLY ( Addr a, UInt vbytes );
244static void vgm_wr_V2_SLOWLY ( Addr a, UInt vbytes );
245static void vgm_wr_V1_SLOWLY ( Addr a, UInt vbytes );
246static void fpu_read_check_SLOWLY ( Addr addr, Int size );
247static void fpu_write_check_SLOWLY ( Addr addr, Int size );
248
249
250/*------------------------------------------------------------*/
251/*--- Data defns. ---*/
252/*------------------------------------------------------------*/
253
254typedef
255 struct {
256 UChar abits[8192];
257 UChar vbyte[65536];
258 }
259 SecMap;
260
261/* These two are statically allocated. Should they be non-public? */
262SecMap* VG_(primary_map)[ /*65536*/ 262144 ];
263static SecMap vg_distinguished_secondary_map;
264
265#define IS_DISTINGUISHED_SM(smap) \
266 ((smap) == &vg_distinguished_secondary_map)
267
268#define ENSURE_MAPPABLE(addr,caller) \
269 do { \
270 if (IS_DISTINGUISHED_SM(VG_(primary_map)[(addr) >> 16])) { \
271 VG_(primary_map)[(addr) >> 16] = alloc_secondary_map(caller); \
272 /* VG_(printf)("new 2map because of %p\n", addr); */ \
273 } \
274 } while(0)
275
276#define BITARR_SET(aaa_p,iii_p) \
277 do { \
278 UInt iii = (UInt)iii_p; \
279 UChar* aaa = (UChar*)aaa_p; \
280 aaa[iii >> 3] |= (1 << (iii & 7)); \
281 } while (0)
282
283#define BITARR_CLEAR(aaa_p,iii_p) \
284 do { \
285 UInt iii = (UInt)iii_p; \
286 UChar* aaa = (UChar*)aaa_p; \
287 aaa[iii >> 3] &= ~(1 << (iii & 7)); \
288 } while (0)
289
290#define BITARR_TEST(aaa_p,iii_p) \
291 (0 != (((UChar*)aaa_p)[ ((UInt)iii_p) >> 3 ] \
292 & (1 << (((UInt)iii_p) & 7)))) \
293
294
295#define VGM_BIT_VALID 0
296#define VGM_BIT_INVALID 1
297
298#define VGM_NIBBLE_VALID 0
299#define VGM_NIBBLE_INVALID 0xF
300
301#define VGM_BYTE_VALID 0
302#define VGM_BYTE_INVALID 0xFF
303
sewardjc3bd5f52002-05-01 03:24:23 +0000304/* Now in vg_include.h.
sewardjde4a1d02002-03-22 01:27:54 +0000305#define VGM_WORD_VALID 0
306#define VGM_WORD_INVALID 0xFFFFFFFF
sewardjc3bd5f52002-05-01 03:24:23 +0000307*/
sewardjde4a1d02002-03-22 01:27:54 +0000308
309#define VGM_EFLAGS_VALID 0xFFFFFFFE
310#define VGM_EFLAGS_INVALID 0xFFFFFFFF
311
312
313#define IS_ALIGNED4_ADDR(aaa_p) (0 == (((UInt)(aaa_p)) & 3))
314
315
316/*------------------------------------------------------------*/
317/*--- Basic bitmap management, reading and writing. ---*/
318/*------------------------------------------------------------*/
319
320/* Allocate and initialise a secondary map. */
321
322static SecMap* alloc_secondary_map ( __attribute__ ((unused))
323 Char* caller )
324{
325 SecMap* map;
326 UInt i;
327 PROF_EVENT(10);
328
329 /* Mark all bytes as invalid access and invalid value. */
330
331 /* It just happens that a SecMap occupies exactly 18 pages --
332 although this isn't important, so the following assert is
333 spurious. */
334 vg_assert(0 == (sizeof(SecMap) % VKI_BYTES_PER_PAGE));
335 map = VG_(get_memory_from_mmap)( sizeof(SecMap) );
336
337 for (i = 0; i < 8192; i++)
338 map->abits[i] = VGM_BYTE_INVALID; /* Invalid address */
339 for (i = 0; i < 65536; i++)
340 map->vbyte[i] = VGM_BYTE_INVALID; /* Invalid Value */
341
342 /* VG_(printf)("ALLOC_2MAP(%s)\n", caller ); */
343 return map;
344}
345
346
347/* Basic reading/writing of the bitmaps, for byte-sized accesses. */
348
349static __inline__ UChar get_abit ( Addr a )
350{
351 SecMap* sm = VG_(primary_map)[a >> 16];
352 UInt sm_off = a & 0xFFFF;
353 PROF_EVENT(20);
354 return BITARR_TEST(sm->abits, sm_off)
355 ? VGM_BIT_INVALID : VGM_BIT_VALID;
356}
357
358static __inline__ UChar get_vbyte ( Addr a )
359{
360 SecMap* sm = VG_(primary_map)[a >> 16];
361 UInt sm_off = a & 0xFFFF;
362 PROF_EVENT(21);
363 return sm->vbyte[sm_off];
364}
365
366static __inline__ void set_abit ( Addr a, UChar abit )
367{
368 SecMap* sm;
369 UInt sm_off;
370 PROF_EVENT(22);
371 ENSURE_MAPPABLE(a, "set_abit");
372 sm = VG_(primary_map)[a >> 16];
373 sm_off = a & 0xFFFF;
374 if (abit)
375 BITARR_SET(sm->abits, sm_off);
376 else
377 BITARR_CLEAR(sm->abits, sm_off);
378}
379
380static __inline__ void set_vbyte ( Addr a, UChar vbyte )
381{
382 SecMap* sm;
383 UInt sm_off;
384 PROF_EVENT(23);
385 ENSURE_MAPPABLE(a, "set_vbyte");
386 sm = VG_(primary_map)[a >> 16];
387 sm_off = a & 0xFFFF;
388 sm->vbyte[sm_off] = vbyte;
389}
390
391
392/* Reading/writing of the bitmaps, for aligned word-sized accesses. */
393
394static __inline__ UChar get_abits4_ALIGNED ( Addr a )
395{
396 SecMap* sm;
397 UInt sm_off;
398 UChar abits8;
399 PROF_EVENT(24);
400# ifdef VG_DEBUG_MEMORY
401 vg_assert(IS_ALIGNED4_ADDR(a));
402# endif
403 sm = VG_(primary_map)[a >> 16];
404 sm_off = a & 0xFFFF;
405 abits8 = sm->abits[sm_off >> 3];
406 abits8 >>= (a & 4 /* 100b */); /* a & 4 is either 0 or 4 */
407 abits8 &= 0x0F;
408 return abits8;
409}
410
411static UInt __inline__ get_vbytes4_ALIGNED ( Addr a )
412{
413 SecMap* sm = VG_(primary_map)[a >> 16];
414 UInt sm_off = a & 0xFFFF;
415 PROF_EVENT(25);
416# ifdef VG_DEBUG_MEMORY
417 vg_assert(IS_ALIGNED4_ADDR(a));
418# endif
419 return ((UInt*)(sm->vbyte))[sm_off >> 2];
420}
421
422
423/*------------------------------------------------------------*/
424/*--- Setting permissions over address ranges. ---*/
425/*------------------------------------------------------------*/
426
427static void set_address_range_perms ( Addr a, UInt len,
428 UInt example_a_bit,
429 UInt example_v_bit )
430{
431 UChar vbyte, abyte8;
432 UInt vword4, sm_off;
433 SecMap* sm;
434
435 PROF_EVENT(30);
436
437 if (len == 0)
438 return;
439
440 if (len > 100 * 1000 * 1000)
441 VG_(message)(Vg_UserMsg,
442 "Warning: set address range perms: "
443 "large range %d, a %d, v %d",
444 len, example_a_bit, example_v_bit );
445
446 VGP_PUSHCC(VgpSARP);
447
448 /* Requests to change permissions of huge address ranges may
449 indicate bugs in our machinery. 30,000,000 is arbitrary, but so
450 far all legitimate requests have fallen beneath that size. */
451 /* 4 Mar 02: this is just stupid; get rid of it. */
452 /* vg_assert(len < 30000000); */
453
454 /* Check the permissions make sense. */
455 vg_assert(example_a_bit == VGM_BIT_VALID
456 || example_a_bit == VGM_BIT_INVALID);
457 vg_assert(example_v_bit == VGM_BIT_VALID
458 || example_v_bit == VGM_BIT_INVALID);
459 if (example_a_bit == VGM_BIT_INVALID)
460 vg_assert(example_v_bit == VGM_BIT_INVALID);
461
462 /* The validity bits to write. */
463 vbyte = example_v_bit==VGM_BIT_VALID
464 ? VGM_BYTE_VALID : VGM_BYTE_INVALID;
465
466 /* In order that we can charge through the address space at 8
467 bytes/main-loop iteration, make up some perms. */
468 abyte8 = (example_a_bit << 7)
469 | (example_a_bit << 6)
470 | (example_a_bit << 5)
471 | (example_a_bit << 4)
472 | (example_a_bit << 3)
473 | (example_a_bit << 2)
474 | (example_a_bit << 1)
475 | (example_a_bit << 0);
476 vword4 = (vbyte << 24) | (vbyte << 16) | (vbyte << 8) | vbyte;
477
478# ifdef VG_DEBUG_MEMORY
479 /* Do it ... */
480 while (True) {
481 PROF_EVENT(31);
482 if (len == 0) break;
483 set_abit ( a, example_a_bit );
484 set_vbyte ( a, vbyte );
485 a++;
486 len--;
487 }
488
489# else
490 /* Slowly do parts preceding 8-byte alignment. */
491 while (True) {
492 PROF_EVENT(31);
493 if (len == 0) break;
494 if ((a % 8) == 0) break;
495 set_abit ( a, example_a_bit );
496 set_vbyte ( a, vbyte );
497 a++;
498 len--;
499 }
500
501 if (len == 0) {
502 VGP_POPCC;
503 return;
504 }
505 vg_assert((a % 8) == 0 && len > 0);
506
507 /* Once aligned, go fast. */
508 while (True) {
509 PROF_EVENT(32);
510 if (len < 8) break;
511 ENSURE_MAPPABLE(a, "set_address_range_perms(fast)");
512 sm = VG_(primary_map)[a >> 16];
513 sm_off = a & 0xFFFF;
514 sm->abits[sm_off >> 3] = abyte8;
515 ((UInt*)(sm->vbyte))[(sm_off >> 2) + 0] = vword4;
516 ((UInt*)(sm->vbyte))[(sm_off >> 2) + 1] = vword4;
517 a += 8;
518 len -= 8;
519 }
520
521 if (len == 0) {
522 VGP_POPCC;
523 return;
524 }
525 vg_assert((a % 8) == 0 && len > 0 && len < 8);
526
527 /* Finish the upper fragment. */
528 while (True) {
529 PROF_EVENT(33);
530 if (len == 0) break;
531 set_abit ( a, example_a_bit );
532 set_vbyte ( a, vbyte );
533 a++;
534 len--;
535 }
536# endif
537
538 /* Check that zero page and highest page have not been written to
539 -- this could happen with buggy syscall wrappers. Today
540 (2001-04-26) had precisely such a problem with
541 __NR_setitimer. */
sewardj126a41f2002-05-07 23:45:03 +0000542 vg_assert(VG_(first_and_last_secondaries_look_plausible)());
sewardjde4a1d02002-03-22 01:27:54 +0000543 VGP_POPCC;
544}
545
546
547/* Set permissions for address ranges ... */
548
549void VGM_(make_noaccess) ( Addr a, UInt len )
550{
551 PROF_EVENT(35);
552 set_address_range_perms ( a, len, VGM_BIT_INVALID, VGM_BIT_INVALID );
553}
554
555void VGM_(make_writable) ( Addr a, UInt len )
556{
557 PROF_EVENT(36);
558 set_address_range_perms ( a, len, VGM_BIT_VALID, VGM_BIT_INVALID );
559}
560
561void VGM_(make_readable) ( Addr a, UInt len )
562{
563 PROF_EVENT(37);
564 set_address_range_perms ( a, len, VGM_BIT_VALID, VGM_BIT_VALID );
565}
566
567void VGM_(make_readwritable) ( Addr a, UInt len )
568{
569 PROF_EVENT(38);
570 set_address_range_perms ( a, len, VGM_BIT_VALID, VGM_BIT_VALID );
571}
572
573/* Block-copy permissions (needed for implementing realloc()). */
574
575void VGM_(copy_address_range_perms) ( Addr src, Addr dst, UInt len )
576{
577 UInt i;
578 PROF_EVENT(40);
579 for (i = 0; i < len; i++) {
580 UChar abit = get_abit ( src+i );
581 UChar vbyte = get_vbyte ( src+i );
582 PROF_EVENT(41);
583 set_abit ( dst+i, abit );
584 set_vbyte ( dst+i, vbyte );
585 }
586}
587
588
589/* Check permissions for address range. If inadequate permissions
590 exist, *bad_addr is set to the offending address, so the caller can
591 know what it is. */
592
593Bool VGM_(check_writable) ( Addr a, UInt len, Addr* bad_addr )
594{
595 UInt i;
596 UChar abit;
597 PROF_EVENT(42);
598 for (i = 0; i < len; i++) {
599 PROF_EVENT(43);
600 abit = get_abit(a);
601 if (abit == VGM_BIT_INVALID) {
602 if (bad_addr != NULL) *bad_addr = a;
603 return False;
604 }
605 a++;
606 }
607 return True;
608}
609
610Bool VGM_(check_readable) ( Addr a, UInt len, Addr* bad_addr )
611{
612 UInt i;
613 UChar abit;
614 UChar vbyte;
615 PROF_EVENT(44);
616 for (i = 0; i < len; i++) {
617 abit = get_abit(a);
618 vbyte = get_vbyte(a);
619 PROF_EVENT(45);
620 if (abit != VGM_BIT_VALID || vbyte != VGM_BYTE_VALID) {
621 if (bad_addr != NULL) *bad_addr = a;
622 return False;
623 }
624 a++;
625 }
626 return True;
627}
628
629
630/* Check a zero-terminated ascii string. Tricky -- don't want to
631 examine the actual bytes, to find the end, until we're sure it is
632 safe to do so. */
633
634Bool VGM_(check_readable_asciiz) ( Addr a, Addr* bad_addr )
635{
636 UChar abit;
637 UChar vbyte;
638 PROF_EVENT(46);
639 while (True) {
640 PROF_EVENT(47);
641 abit = get_abit(a);
642 vbyte = get_vbyte(a);
643 if (abit != VGM_BIT_VALID || vbyte != VGM_BYTE_VALID) {
644 if (bad_addr != NULL) *bad_addr = a;
645 return False;
646 }
647 /* Ok, a is safe to read. */
648 if (* ((UChar*)a) == 0) return True;
649 a++;
650 }
651}
652
653
654/* Setting permissions for aligned words. This supports fast stack
655 operations. */
656
657static __inline__ void make_aligned_word_NOACCESS ( Addr a )
658{
659 SecMap* sm;
660 UInt sm_off;
661 UChar mask;
662 PROF_EVENT(50);
663# ifdef VG_DEBUG_MEMORY
664 vg_assert(IS_ALIGNED4_ADDR(a));
665# endif
666 ENSURE_MAPPABLE(a, "make_aligned_word_NOACCESS");
667 sm = VG_(primary_map)[a >> 16];
668 sm_off = a & 0xFFFF;
669 ((UInt*)(sm->vbyte))[sm_off >> 2] = VGM_WORD_INVALID;
670 mask = 0x0F;
671 mask <<= (a & 4 /* 100b */); /* a & 4 is either 0 or 4 */
672 /* mask now contains 1s where we wish to make address bits
673 invalid (1s). */
674 sm->abits[sm_off >> 3] |= mask;
675}
676
677static __inline__ void make_aligned_word_WRITABLE ( Addr a )
678{
679 SecMap* sm;
680 UInt sm_off;
681 UChar mask;
682 PROF_EVENT(51);
683# ifdef VG_DEBUG_MEMORY
684 vg_assert(IS_ALIGNED4_ADDR(a));
685# endif
686 ENSURE_MAPPABLE(a, "make_aligned_word_WRITABLE");
687 sm = VG_(primary_map)[a >> 16];
688 sm_off = a & 0xFFFF;
689 ((UInt*)(sm->vbyte))[sm_off >> 2] = VGM_WORD_INVALID;
690 mask = 0x0F;
691 mask <<= (a & 4 /* 100b */); /* a & 4 is either 0 or 4 */
692 /* mask now contains 1s where we wish to make address bits
693 invalid (0s). */
694 sm->abits[sm_off >> 3] &= ~mask;
695}
696
697
698/*------------------------------------------------------------*/
699/*--- Functions called directly from generated code. ---*/
700/*------------------------------------------------------------*/
701
702static __inline__ UInt rotateRight16 ( UInt x )
703{
704 /* Amazingly, gcc turns this into a single rotate insn. */
705 return (x >> 16) | (x << 16);
706}
707
708
709static __inline__ UInt shiftRight16 ( UInt x )
710{
711 return x >> 16;
712}
713
714
715/* Read/write 1/2/4 sized V bytes, and emit an address error if
716 needed. */
717
718/* VG_(helperc_{LD,ST}V{1,2,4}) handle the common case fast.
719 Under all other circumstances, it defers to the relevant _SLOWLY
720 function, which can handle all situations.
721*/
sewardjde4a1d02002-03-22 01:27:54 +0000722UInt VG_(helperc_LOADV4) ( Addr a )
723{
724# ifdef VG_DEBUG_MEMORY
725 return vgm_rd_V4_SLOWLY(a);
726# else
727 UInt sec_no = rotateRight16(a) & 0x3FFFF;
728 SecMap* sm = VG_(primary_map)[sec_no];
729 UInt a_off = (a & 0xFFFF) >> 3;
730 UChar abits = sm->abits[a_off];
731 abits >>= (a & 4);
732 abits &= 15;
733 PROF_EVENT(60);
734 if (abits == VGM_NIBBLE_VALID) {
735 /* Handle common case quickly: a is suitably aligned, is mapped,
736 and is addressible. */
737 UInt v_off = a & 0xFFFF;
738 return ((UInt*)(sm->vbyte))[ v_off >> 2 ];
739 } else {
740 /* Slow but general case. */
741 return vgm_rd_V4_SLOWLY(a);
742 }
743# endif
744}
745
746void VG_(helperc_STOREV4) ( Addr a, UInt vbytes )
747{
748# ifdef VG_DEBUG_MEMORY
749 vgm_wr_V4_SLOWLY(a, vbytes);
750# else
751 UInt sec_no = rotateRight16(a) & 0x3FFFF;
752 SecMap* sm = VG_(primary_map)[sec_no];
753 UInt a_off = (a & 0xFFFF) >> 3;
754 UChar abits = sm->abits[a_off];
755 abits >>= (a & 4);
756 abits &= 15;
757 PROF_EVENT(61);
758 if (abits == VGM_NIBBLE_VALID) {
759 /* Handle common case quickly: a is suitably aligned, is mapped,
760 and is addressible. */
761 UInt v_off = a & 0xFFFF;
762 ((UInt*)(sm->vbyte))[ v_off >> 2 ] = vbytes;
763 } else {
764 /* Slow but general case. */
765 vgm_wr_V4_SLOWLY(a, vbytes);
766 }
767# endif
768}
769
770UInt VG_(helperc_LOADV2) ( Addr a )
771{
772# ifdef VG_DEBUG_MEMORY
773 return vgm_rd_V2_SLOWLY(a);
774# else
775 UInt sec_no = rotateRight16(a) & 0x1FFFF;
776 SecMap* sm = VG_(primary_map)[sec_no];
777 UInt a_off = (a & 0xFFFF) >> 3;
778 PROF_EVENT(62);
779 if (sm->abits[a_off] == VGM_BYTE_VALID) {
780 /* Handle common case quickly. */
781 UInt v_off = a & 0xFFFF;
782 return 0xFFFF0000
783 |
784 (UInt)( ((UShort*)(sm->vbyte))[ v_off >> 1 ] );
785 } else {
786 /* Slow but general case. */
787 return vgm_rd_V2_SLOWLY(a);
788 }
789# endif
790}
791
792void VG_(helperc_STOREV2) ( Addr a, UInt vbytes )
793{
794# ifdef VG_DEBUG_MEMORY
795 vgm_wr_V2_SLOWLY(a, vbytes);
796# else
797 UInt sec_no = rotateRight16(a) & 0x1FFFF;
798 SecMap* sm = VG_(primary_map)[sec_no];
799 UInt a_off = (a & 0xFFFF) >> 3;
800 PROF_EVENT(63);
801 if (sm->abits[a_off] == VGM_BYTE_VALID) {
802 /* Handle common case quickly. */
803 UInt v_off = a & 0xFFFF;
804 ((UShort*)(sm->vbyte))[ v_off >> 1 ] = vbytes & 0x0000FFFF;
805 } else {
806 /* Slow but general case. */
807 vgm_wr_V2_SLOWLY(a, vbytes);
808 }
809# endif
810}
811
812UInt VG_(helperc_LOADV1) ( Addr a )
813{
814# ifdef VG_DEBUG_MEMORY
815 return vgm_rd_V1_SLOWLY(a);
816# else
817 UInt sec_no = shiftRight16(a);
818 SecMap* sm = VG_(primary_map)[sec_no];
819 UInt a_off = (a & 0xFFFF) >> 3;
820 PROF_EVENT(64);
821 if (sm->abits[a_off] == VGM_BYTE_VALID) {
822 /* Handle common case quickly. */
823 UInt v_off = a & 0xFFFF;
824 return 0xFFFFFF00
825 |
826 (UInt)( ((UChar*)(sm->vbyte))[ v_off ] );
827 } else {
828 /* Slow but general case. */
829 return vgm_rd_V1_SLOWLY(a);
830 }
831# endif
832}
833
834void VG_(helperc_STOREV1) ( Addr a, UInt vbytes )
835{
836# ifdef VG_DEBUG_MEMORY
837 vgm_wr_V1_SLOWLY(a, vbytes);
838# else
839 UInt sec_no = shiftRight16(a);
840 SecMap* sm = VG_(primary_map)[sec_no];
841 UInt a_off = (a & 0xFFFF) >> 3;
842 PROF_EVENT(65);
843 if (sm->abits[a_off] == VGM_BYTE_VALID) {
844 /* Handle common case quickly. */
845 UInt v_off = a & 0xFFFF;
846 ((UChar*)(sm->vbyte))[ v_off ] = vbytes & 0x000000FF;
847 } else {
848 /* Slow but general case. */
849 vgm_wr_V1_SLOWLY(a, vbytes);
850 }
851# endif
852}
853
854
855/*------------------------------------------------------------*/
856/*--- Fallback functions to handle cases that the above ---*/
857/*--- VG_(helperc_{LD,ST}V{1,2,4}) can't manage. ---*/
858/*------------------------------------------------------------*/
859
860static UInt vgm_rd_V4_SLOWLY ( Addr a )
861{
862 Bool a0ok, a1ok, a2ok, a3ok;
863 UInt vb0, vb1, vb2, vb3;
864
865 PROF_EVENT(70);
866
867 /* First establish independently the addressibility of the 4 bytes
868 involved. */
869 a0ok = get_abit(a+0) == VGM_BIT_VALID;
870 a1ok = get_abit(a+1) == VGM_BIT_VALID;
871 a2ok = get_abit(a+2) == VGM_BIT_VALID;
872 a3ok = get_abit(a+3) == VGM_BIT_VALID;
873
874 /* Also get the validity bytes for the address. */
875 vb0 = (UInt)get_vbyte(a+0);
876 vb1 = (UInt)get_vbyte(a+1);
877 vb2 = (UInt)get_vbyte(a+2);
878 vb3 = (UInt)get_vbyte(a+3);
879
880 /* Now distinguish 3 cases */
881
882 /* Case 1: the address is completely valid, so:
883 - no addressing error
884 - return V bytes as read from memory
885 */
886 if (a0ok && a1ok && a2ok && a3ok) {
887 UInt vw = VGM_WORD_INVALID;
888 vw <<= 8; vw |= vb3;
889 vw <<= 8; vw |= vb2;
890 vw <<= 8; vw |= vb1;
891 vw <<= 8; vw |= vb0;
892 return vw;
893 }
894
895 /* Case 2: the address is completely invalid.
896 - emit addressing error
897 - return V word indicating validity.
898 This sounds strange, but if we make loads from invalid addresses
899 give invalid data, we also risk producing a number of confusing
900 undefined-value errors later, which confuses the fact that the
901 error arose in the first place from an invalid address.
902 */
903 /* VG_(printf)("%p (%d %d %d %d)\n", a, a0ok, a1ok, a2ok, a3ok); */
904 if (!VG_(clo_partial_loads_ok)
905 || ((a & 3) != 0)
906 || (!a0ok && !a1ok && !a2ok && !a3ok)) {
907 VG_(record_address_error)( a, 4, False );
908 return (VGM_BYTE_VALID << 24) | (VGM_BYTE_VALID << 16)
909 | (VGM_BYTE_VALID << 8) | VGM_BYTE_VALID;
910 }
911
912 /* Case 3: the address is partially valid.
913 - no addressing error
914 - returned V word is invalid where the address is invalid,
915 and contains V bytes from memory otherwise.
916 Case 3 is only allowed if VG_(clo_partial_loads_ok) is True
917 (which is the default), and the address is 4-aligned.
918 If not, Case 2 will have applied.
919 */
920 vg_assert(VG_(clo_partial_loads_ok));
921 {
922 UInt vw = VGM_WORD_INVALID;
923 vw <<= 8; vw |= (a3ok ? vb3 : VGM_BYTE_INVALID);
924 vw <<= 8; vw |= (a2ok ? vb2 : VGM_BYTE_INVALID);
925 vw <<= 8; vw |= (a1ok ? vb1 : VGM_BYTE_INVALID);
926 vw <<= 8; vw |= (a0ok ? vb0 : VGM_BYTE_INVALID);
927 return vw;
928 }
929}
930
931static void vgm_wr_V4_SLOWLY ( Addr a, UInt vbytes )
932{
933 /* Check the address for validity. */
934 Bool aerr = False;
935 PROF_EVENT(71);
936
937 if (get_abit(a+0) != VGM_BIT_VALID) aerr = True;
938 if (get_abit(a+1) != VGM_BIT_VALID) aerr = True;
939 if (get_abit(a+2) != VGM_BIT_VALID) aerr = True;
940 if (get_abit(a+3) != VGM_BIT_VALID) aerr = True;
941
942 /* Store the V bytes, remembering to do it little-endian-ly. */
943 set_vbyte( a+0, vbytes & 0x000000FF ); vbytes >>= 8;
944 set_vbyte( a+1, vbytes & 0x000000FF ); vbytes >>= 8;
945 set_vbyte( a+2, vbytes & 0x000000FF ); vbytes >>= 8;
946 set_vbyte( a+3, vbytes & 0x000000FF );
947
948 /* If an address error has happened, report it. */
949 if (aerr)
950 VG_(record_address_error)( a, 4, True );
951}
952
953static UInt vgm_rd_V2_SLOWLY ( Addr a )
954{
955 /* Check the address for validity. */
956 UInt vw = VGM_WORD_INVALID;
957 Bool aerr = False;
958 PROF_EVENT(72);
959
960 if (get_abit(a+0) != VGM_BIT_VALID) aerr = True;
961 if (get_abit(a+1) != VGM_BIT_VALID) aerr = True;
962
963 /* Fetch the V bytes, remembering to do it little-endian-ly. */
964 vw <<= 8; vw |= (UInt)get_vbyte(a+1);
965 vw <<= 8; vw |= (UInt)get_vbyte(a+0);
966
967 /* If an address error has happened, report it. */
968 if (aerr) {
969 VG_(record_address_error)( a, 2, False );
970 vw = (VGM_BYTE_INVALID << 24) | (VGM_BYTE_INVALID << 16)
971 | (VGM_BYTE_VALID << 8) | (VGM_BYTE_VALID);
972 }
973 return vw;
974}
975
976static void vgm_wr_V2_SLOWLY ( Addr a, UInt vbytes )
977{
978 /* Check the address for validity. */
979 Bool aerr = False;
980 PROF_EVENT(73);
981
982 if (get_abit(a+0) != VGM_BIT_VALID) aerr = True;
983 if (get_abit(a+1) != VGM_BIT_VALID) aerr = True;
984
985 /* Store the V bytes, remembering to do it little-endian-ly. */
986 set_vbyte( a+0, vbytes & 0x000000FF ); vbytes >>= 8;
987 set_vbyte( a+1, vbytes & 0x000000FF );
988
989 /* If an address error has happened, report it. */
990 if (aerr)
991 VG_(record_address_error)( a, 2, True );
992}
993
994static UInt vgm_rd_V1_SLOWLY ( Addr a )
995{
996 /* Check the address for validity. */
997 UInt vw = VGM_WORD_INVALID;
998 Bool aerr = False;
999 PROF_EVENT(74);
1000
1001 if (get_abit(a+0) != VGM_BIT_VALID) aerr = True;
1002
1003 /* Fetch the V byte. */
1004 vw <<= 8; vw |= (UInt)get_vbyte(a+0);
1005
1006 /* If an address error has happened, report it. */
1007 if (aerr) {
1008 VG_(record_address_error)( a, 1, False );
1009 vw = (VGM_BYTE_INVALID << 24) | (VGM_BYTE_INVALID << 16)
1010 | (VGM_BYTE_INVALID << 8) | (VGM_BYTE_VALID);
1011 }
1012 return vw;
1013}
1014
1015static void vgm_wr_V1_SLOWLY ( Addr a, UInt vbytes )
1016{
1017 /* Check the address for validity. */
1018 Bool aerr = False;
1019 PROF_EVENT(75);
1020 if (get_abit(a+0) != VGM_BIT_VALID) aerr = True;
1021
1022 /* Store the V bytes, remembering to do it little-endian-ly. */
1023 set_vbyte( a+0, vbytes & 0x000000FF );
1024
1025 /* If an address error has happened, report it. */
1026 if (aerr)
1027 VG_(record_address_error)( a, 1, True );
1028}
1029
1030
1031/* ---------------------------------------------------------------------
1032 Called from generated code, or from the assembly helpers.
1033 Handlers for value check failures.
1034 ------------------------------------------------------------------ */
1035
1036void VG_(helperc_value_check0_fail) ( void )
1037{
1038 VG_(record_value_error) ( 0 );
1039}
1040
1041void VG_(helperc_value_check1_fail) ( void )
1042{
1043 VG_(record_value_error) ( 1 );
1044}
1045
1046void VG_(helperc_value_check2_fail) ( void )
1047{
1048 VG_(record_value_error) ( 2 );
1049}
1050
1051void VG_(helperc_value_check4_fail) ( void )
1052{
1053 VG_(record_value_error) ( 4 );
1054}
1055
1056
1057/* ---------------------------------------------------------------------
1058 FPU load and store checks, called from generated code.
1059 ------------------------------------------------------------------ */
1060
1061void VGM_(fpu_read_check) ( Addr addr, Int size )
1062{
1063 /* Ensure the read area is both addressible and valid (ie,
1064 readable). If there's an address error, don't report a value
1065 error too; but if there isn't an address error, check for a
1066 value error.
1067
1068 Try to be reasonably fast on the common case; wimp out and defer
1069 to fpu_read_check_SLOWLY for everything else. */
1070
1071 SecMap* sm;
1072 UInt sm_off, v_off, a_off;
1073 Addr addr4;
1074
1075 PROF_EVENT(80);
1076
1077# ifdef VG_DEBUG_MEMORY
1078 fpu_read_check_SLOWLY ( addr, size );
1079# else
1080
1081 if (size == 4) {
1082 if (!IS_ALIGNED4_ADDR(addr)) goto slow4;
1083 PROF_EVENT(81);
1084 /* Properly aligned. */
1085 sm = VG_(primary_map)[addr >> 16];
1086 sm_off = addr & 0xFFFF;
1087 a_off = sm_off >> 3;
1088 if (sm->abits[a_off] != VGM_BYTE_VALID) goto slow4;
1089 /* Properly aligned and addressible. */
1090 v_off = addr & 0xFFFF;
1091 if (((UInt*)(sm->vbyte))[ v_off >> 2 ] != VGM_WORD_VALID)
1092 goto slow4;
1093 /* Properly aligned, addressible and with valid data. */
1094 return;
1095 slow4:
1096 fpu_read_check_SLOWLY ( addr, 4 );
1097 return;
1098 }
1099
1100 if (size == 8) {
1101 if (!IS_ALIGNED4_ADDR(addr)) goto slow8;
1102 PROF_EVENT(82);
1103 /* Properly aligned. Do it in two halves. */
1104 addr4 = addr + 4;
1105 /* First half. */
1106 sm = VG_(primary_map)[addr >> 16];
1107 sm_off = addr & 0xFFFF;
1108 a_off = sm_off >> 3;
1109 if (sm->abits[a_off] != VGM_BYTE_VALID) goto slow8;
1110 /* First half properly aligned and addressible. */
1111 v_off = addr & 0xFFFF;
1112 if (((UInt*)(sm->vbyte))[ v_off >> 2 ] != VGM_WORD_VALID)
1113 goto slow8;
1114 /* Second half. */
1115 sm = VG_(primary_map)[addr4 >> 16];
1116 sm_off = addr4 & 0xFFFF;
1117 a_off = sm_off >> 3;
1118 if (sm->abits[a_off] != VGM_BYTE_VALID) goto slow8;
1119 /* Second half properly aligned and addressible. */
1120 v_off = addr4 & 0xFFFF;
1121 if (((UInt*)(sm->vbyte))[ v_off >> 2 ] != VGM_WORD_VALID)
1122 goto slow8;
1123 /* Both halves properly aligned, addressible and with valid
1124 data. */
1125 return;
1126 slow8:
1127 fpu_read_check_SLOWLY ( addr, 8 );
1128 return;
1129 }
1130
1131 /* Can't be bothered to huff'n'puff to make these (allegedly) rare
1132 cases go quickly. */
1133 if (size == 2) {
1134 PROF_EVENT(83);
1135 fpu_read_check_SLOWLY ( addr, 2 );
1136 return;
1137 }
1138
1139 if (size == 10) {
1140 PROF_EVENT(84);
1141 fpu_read_check_SLOWLY ( addr, 10 );
1142 return;
1143 }
1144
1145 VG_(printf)("size is %d\n", size);
1146 VG_(panic)("vgm_fpu_read_check: unhandled size");
1147# endif
1148}
1149
1150
1151void VGM_(fpu_write_check) ( Addr addr, Int size )
1152{
1153 /* Ensure the written area is addressible, and moan if otherwise.
1154 If it is addressible, make it valid, otherwise invalid.
1155 */
1156
1157 SecMap* sm;
1158 UInt sm_off, v_off, a_off;
1159 Addr addr4;
1160
1161 PROF_EVENT(85);
1162
1163# ifdef VG_DEBUG_MEMORY
1164 fpu_write_check_SLOWLY ( addr, size );
1165# else
1166
1167 if (size == 4) {
1168 if (!IS_ALIGNED4_ADDR(addr)) goto slow4;
1169 PROF_EVENT(86);
1170 /* Properly aligned. */
1171 sm = VG_(primary_map)[addr >> 16];
1172 sm_off = addr & 0xFFFF;
1173 a_off = sm_off >> 3;
1174 if (sm->abits[a_off] != VGM_BYTE_VALID) goto slow4;
1175 /* Properly aligned and addressible. Make valid. */
1176 v_off = addr & 0xFFFF;
1177 ((UInt*)(sm->vbyte))[ v_off >> 2 ] = VGM_WORD_VALID;
1178 return;
1179 slow4:
1180 fpu_write_check_SLOWLY ( addr, 4 );
1181 return;
1182 }
1183
1184 if (size == 8) {
1185 if (!IS_ALIGNED4_ADDR(addr)) goto slow8;
1186 PROF_EVENT(87);
1187 /* Properly aligned. Do it in two halves. */
1188 addr4 = addr + 4;
1189 /* First half. */
1190 sm = VG_(primary_map)[addr >> 16];
1191 sm_off = addr & 0xFFFF;
1192 a_off = sm_off >> 3;
1193 if (sm->abits[a_off] != VGM_BYTE_VALID) goto slow8;
1194 /* First half properly aligned and addressible. Make valid. */
1195 v_off = addr & 0xFFFF;
1196 ((UInt*)(sm->vbyte))[ v_off >> 2 ] = VGM_WORD_VALID;
1197 /* Second half. */
1198 sm = VG_(primary_map)[addr4 >> 16];
1199 sm_off = addr4 & 0xFFFF;
1200 a_off = sm_off >> 3;
1201 if (sm->abits[a_off] != VGM_BYTE_VALID) goto slow8;
1202 /* Second half properly aligned and addressible. */
1203 v_off = addr4 & 0xFFFF;
1204 ((UInt*)(sm->vbyte))[ v_off >> 2 ] = VGM_WORD_VALID;
1205 /* Properly aligned, addressible and with valid data. */
1206 return;
1207 slow8:
1208 fpu_write_check_SLOWLY ( addr, 8 );
1209 return;
1210 }
1211
1212 /* Can't be bothered to huff'n'puff to make these (allegedly) rare
1213 cases go quickly. */
1214 if (size == 2) {
1215 PROF_EVENT(88);
1216 fpu_write_check_SLOWLY ( addr, 2 );
1217 return;
1218 }
1219
1220 if (size == 10) {
1221 PROF_EVENT(89);
1222 fpu_write_check_SLOWLY ( addr, 10 );
1223 return;
1224 }
1225
1226 VG_(printf)("size is %d\n", size);
1227 VG_(panic)("vgm_fpu_write_check: unhandled size");
1228# endif
1229}
1230
1231
1232/* ---------------------------------------------------------------------
1233 Slow, general cases for FPU load and store checks.
1234 ------------------------------------------------------------------ */
1235
1236/* Generic version. Test for both addr and value errors, but if
1237 there's an addr error, don't report a value error even if it
1238 exists. */
1239
1240void fpu_read_check_SLOWLY ( Addr addr, Int size )
1241{
1242 Int i;
1243 Bool aerr = False;
1244 Bool verr = False;
1245 PROF_EVENT(90);
1246 for (i = 0; i < size; i++) {
1247 PROF_EVENT(91);
1248 if (get_abit(addr+i) != VGM_BIT_VALID)
1249 aerr = True;
1250 if (get_vbyte(addr+i) != VGM_BYTE_VALID)
1251 verr = True;
1252 }
1253
1254 if (aerr) {
1255 VG_(record_address_error)( addr, size, False );
1256 } else {
1257 if (verr)
1258 VG_(record_value_error)( size );
1259 }
1260}
1261
1262
1263/* Generic version. Test for addr errors. Valid addresses are
1264 given valid values, and invalid addresses invalid values. */
1265
1266void fpu_write_check_SLOWLY ( Addr addr, Int size )
1267{
1268 Int i;
1269 Addr a_here;
1270 Bool a_ok;
1271 Bool aerr = False;
1272 PROF_EVENT(92);
1273 for (i = 0; i < size; i++) {
1274 PROF_EVENT(93);
1275 a_here = addr+i;
1276 a_ok = get_abit(a_here) == VGM_BIT_VALID;
1277 if (a_ok) {
1278 set_vbyte(a_here, VGM_BYTE_VALID);
1279 } else {
1280 set_vbyte(a_here, VGM_BYTE_INVALID);
1281 aerr = True;
1282 }
1283 }
1284 if (aerr) {
1285 VG_(record_address_error)( addr, size, True );
1286 }
1287}
1288
1289
1290/*------------------------------------------------------------*/
1291/*--- Tracking permissions around %esp changes. ---*/
1292/*------------------------------------------------------------*/
1293
1294/*
1295 The stack
1296 ~~~~~~~~~
1297 The stack's segment seems to be dynamically extended downwards
1298 by the kernel as the stack pointer moves down. Initially, a
1299 1-page (4k) stack is allocated. When %esp moves below that for
1300 the first time, presumably a page fault occurs. The kernel
1301 detects that the faulting address is in the range from %esp upwards
1302 to the current valid stack. It then extends the stack segment
1303 downwards for enough to cover the faulting address, and resumes
1304 the process (invisibly). The process is unaware of any of this.
1305
1306 That means that Valgrind can't spot when the stack segment is
1307 being extended. Fortunately, we want to precisely and continuously
1308 update stack permissions around %esp, so we need to spot all
1309 writes to %esp anyway.
1310
1311 The deal is: when %esp is assigned a lower value, the stack is
1312 being extended. Create a secondary maps to fill in any holes
1313 between the old stack ptr and this one, if necessary. Then
1314 mark all bytes in the area just "uncovered" by this %esp change
1315 as write-only.
1316
1317 When %esp goes back up, mark the area receded over as unreadable
1318 and unwritable.
1319
1320 Just to record the %esp boundary conditions somewhere convenient:
1321 %esp always points to the lowest live byte in the stack. All
1322 addresses below %esp are not live; those at and above it are.
1323*/
1324
sewardj1e8cdc92002-04-18 11:37:52 +00001325/* Does this address look like something in or vaguely near the
1326 current thread's stack? */
1327static
1328Bool is_plausible_stack_addr ( ThreadState* tst, Addr aa )
sewardjde4a1d02002-03-22 01:27:54 +00001329{
1330 UInt a = (UInt)aa;
1331 PROF_EVENT(100);
sewardj1e8cdc92002-04-18 11:37:52 +00001332 if (a <= tst->stack_highest_word &&
1333 a > tst->stack_highest_word - VG_PLAUSIBLE_STACK_SIZE)
sewardjde4a1d02002-03-22 01:27:54 +00001334 return True;
1335 else
1336 return False;
1337}
1338
1339
1340/* Is this address within some small distance below %ESP? Used only
1341 for the --workaround-gcc296-bugs kludge. */
sewardj8c824512002-04-14 04:16:48 +00001342Bool VG_(is_just_below_ESP)( Addr esp, Addr aa )
sewardjde4a1d02002-03-22 01:27:54 +00001343{
sewardj8c824512002-04-14 04:16:48 +00001344 if ((UInt)esp > (UInt)aa
1345 && ((UInt)esp - (UInt)aa) <= VG_GCC296_BUG_STACK_SLOP)
sewardjde4a1d02002-03-22 01:27:54 +00001346 return True;
1347 else
1348 return False;
1349}
1350
1351
1352/* Kludgey ... how much does %esp have to change before we reckon that
1353 the application is switching stacks ? */
1354#define VG_HUGE_DELTA (VG_PLAUSIBLE_STACK_SIZE / 4)
1355
1356static Addr get_page_base ( Addr a )
1357{
1358 return a & ~(VKI_BYTES_PER_PAGE-1);
1359}
1360
1361
1362static void vg_handle_esp_assignment_SLOWLY ( Addr );
1363
1364void VGM_(handle_esp_assignment) ( Addr new_espA )
1365{
1366 UInt old_esp = VG_(baseBlock)[VGOFF_(m_esp)];
1367 UInt new_esp = (UInt)new_espA;
1368 Int delta = ((Int)new_esp) - ((Int)old_esp);
1369
1370 PROF_EVENT(101);
1371
1372# ifndef VG_DEBUG_MEMORY
1373
1374 if (IS_ALIGNED4_ADDR(old_esp)) {
1375
1376 /* Deal with the most common cases fast. These are ordered in
1377 the sequence most common first. */
1378
1379 if (delta == -4) {
1380 /* Moving down by 4 and properly aligned.. */
1381 PROF_EVENT(102);
1382 make_aligned_word_WRITABLE(new_esp);
1383 return;
1384 }
1385
1386 if (delta == 4) {
1387 /* Moving up by 4 and properly aligned. */
1388 PROF_EVENT(103);
1389 make_aligned_word_NOACCESS(old_esp);
1390 return;
1391 }
1392
sewardj4f51f9a2002-05-07 23:38:30 +00001393 if (delta == -12) {
sewardjde4a1d02002-03-22 01:27:54 +00001394 PROF_EVENT(104);
sewardj4f51f9a2002-05-07 23:38:30 +00001395 make_aligned_word_WRITABLE(new_esp);
1396 make_aligned_word_WRITABLE(new_esp+4);
1397 make_aligned_word_WRITABLE(new_esp+8);
1398 return;
1399 }
1400
1401 if (delta == -8) {
1402 PROF_EVENT(105);
1403 make_aligned_word_WRITABLE(new_esp);
1404 make_aligned_word_WRITABLE(new_esp+4);
1405 return;
1406 }
1407
1408 if (delta == 16) {
1409 PROF_EVENT(106);
sewardjde4a1d02002-03-22 01:27:54 +00001410 make_aligned_word_NOACCESS(old_esp);
1411 make_aligned_word_NOACCESS(old_esp+4);
1412 make_aligned_word_NOACCESS(old_esp+8);
1413 make_aligned_word_NOACCESS(old_esp+12);
1414 return;
1415 }
1416
sewardj4f51f9a2002-05-07 23:38:30 +00001417 if (delta == 12) {
1418 PROF_EVENT(107);
1419 make_aligned_word_NOACCESS(old_esp);
1420 make_aligned_word_NOACCESS(old_esp+4);
1421 make_aligned_word_NOACCESS(old_esp+8);
1422 return;
1423 }
1424
1425 if (delta == 0) {
1426 PROF_EVENT(108);
sewardjde4a1d02002-03-22 01:27:54 +00001427 return;
1428 }
1429
1430 if (delta == 8) {
sewardj4f51f9a2002-05-07 23:38:30 +00001431 PROF_EVENT(109);
sewardjde4a1d02002-03-22 01:27:54 +00001432 make_aligned_word_NOACCESS(old_esp);
1433 make_aligned_word_NOACCESS(old_esp+4);
1434 return;
1435 }
1436
sewardj4f51f9a2002-05-07 23:38:30 +00001437 if (delta == -16) {
1438 PROF_EVENT(110);
sewardjde4a1d02002-03-22 01:27:54 +00001439 make_aligned_word_WRITABLE(new_esp);
1440 make_aligned_word_WRITABLE(new_esp+4);
sewardj4f51f9a2002-05-07 23:38:30 +00001441 make_aligned_word_WRITABLE(new_esp+8);
1442 make_aligned_word_WRITABLE(new_esp+12);
sewardjde4a1d02002-03-22 01:27:54 +00001443 return;
1444 }
sewardj4f51f9a2002-05-07 23:38:30 +00001445
1446 if (delta == 20) {
1447 PROF_EVENT(111);
1448 make_aligned_word_NOACCESS(old_esp);
1449 make_aligned_word_NOACCESS(old_esp+4);
1450 make_aligned_word_NOACCESS(old_esp+8);
1451 make_aligned_word_NOACCESS(old_esp+12);
1452 make_aligned_word_NOACCESS(old_esp+16);
1453 return;
1454 }
1455
1456 if (delta == -20) {
1457 PROF_EVENT(112);
1458 make_aligned_word_WRITABLE(new_esp);
1459 make_aligned_word_WRITABLE(new_esp+4);
1460 make_aligned_word_WRITABLE(new_esp+8);
1461 make_aligned_word_WRITABLE(new_esp+12);
1462 make_aligned_word_WRITABLE(new_esp+16);
1463 return;
1464 }
1465
1466 if (delta == 24) {
1467 PROF_EVENT(113);
1468 make_aligned_word_NOACCESS(old_esp);
1469 make_aligned_word_NOACCESS(old_esp+4);
1470 make_aligned_word_NOACCESS(old_esp+8);
1471 make_aligned_word_NOACCESS(old_esp+12);
1472 make_aligned_word_NOACCESS(old_esp+16);
1473 make_aligned_word_NOACCESS(old_esp+20);
1474 return;
1475 }
1476
1477 if (delta == -24) {
1478 PROF_EVENT(114);
1479 make_aligned_word_WRITABLE(new_esp);
1480 make_aligned_word_WRITABLE(new_esp+4);
1481 make_aligned_word_WRITABLE(new_esp+8);
1482 make_aligned_word_WRITABLE(new_esp+12);
1483 make_aligned_word_WRITABLE(new_esp+16);
1484 make_aligned_word_WRITABLE(new_esp+20);
1485 return;
1486 }
1487
sewardjde4a1d02002-03-22 01:27:54 +00001488 }
1489
1490# endif
1491
1492 /* The above special cases handle 90% to 95% of all the stack
1493 adjustments. The rest we give to the slow-but-general
1494 mechanism. */
1495 vg_handle_esp_assignment_SLOWLY ( new_espA );
1496}
1497
1498
1499static void vg_handle_esp_assignment_SLOWLY ( Addr new_espA )
1500{
1501 UInt old_esp = VG_(baseBlock)[VGOFF_(m_esp)];
1502 UInt new_esp = (UInt)new_espA;
1503 Int delta = ((Int)new_esp) - ((Int)old_esp);
sewardj4f51f9a2002-05-07 23:38:30 +00001504 // VG_(printf)("%d ", delta);
1505 PROF_EVENT(120);
sewardjde4a1d02002-03-22 01:27:54 +00001506 if (-(VG_HUGE_DELTA) < delta && delta < VG_HUGE_DELTA) {
1507 /* "Ordinary" stack change. */
1508 if (new_esp < old_esp) {
1509 /* Moving down; the stack is growing. */
sewardj4f51f9a2002-05-07 23:38:30 +00001510 PROF_EVENT(121);
sewardjde4a1d02002-03-22 01:27:54 +00001511 VGM_(make_writable) ( new_esp, old_esp - new_esp );
1512 return;
1513 }
1514 if (new_esp > old_esp) {
1515 /* Moving up; the stack is shrinking. */
sewardj4f51f9a2002-05-07 23:38:30 +00001516 PROF_EVENT(122);
sewardjde4a1d02002-03-22 01:27:54 +00001517 VGM_(make_noaccess) ( old_esp, new_esp - old_esp );
1518 return;
1519 }
sewardj4f51f9a2002-05-07 23:38:30 +00001520 PROF_EVENT(123);
sewardjde4a1d02002-03-22 01:27:54 +00001521 return; /* when old_esp == new_esp */
1522 }
1523
1524 /* %esp has changed by more than HUGE_DELTA. We take this to mean
1525 that the application is switching to a new stack, for whatever
1526 reason, and we attempt to initialise the permissions around the
1527 new stack in some plausible way. All pretty kludgey; needed to
1528 make netscape-4.07 run without generating thousands of error
1529 contexts.
1530
1531 If we appear to be switching back to the main stack, don't mess
1532 with the permissions in the area at and above the stack ptr.
1533 Otherwise, we're switching to an alternative stack; make the
1534 area above %esp readable -- this doesn't seem right -- the right
1535 thing to do would be to make it writable -- but is needed to
1536 avoid huge numbers of errs in netscape. To be investigated. */
1537
1538 { Addr invalid_down_to = get_page_base(new_esp)
1539 - 0 * VKI_BYTES_PER_PAGE;
1540 Addr valid_up_to = get_page_base(new_esp) + VKI_BYTES_PER_PAGE
1541 + 0 * VKI_BYTES_PER_PAGE;
sewardj1e8cdc92002-04-18 11:37:52 +00001542 ThreadState* tst = VG_(get_current_thread_state)();
sewardj4f51f9a2002-05-07 23:38:30 +00001543 PROF_EVENT(124);
sewardjde4a1d02002-03-22 01:27:54 +00001544 if (VG_(clo_verbosity) > 1)
1545 VG_(message)(Vg_UserMsg, "Warning: client switching stacks? "
1546 "%%esp: %p --> %p",
1547 old_esp, new_esp);
1548 /* VG_(printf)("na %p, %%esp %p, wr %p\n",
1549 invalid_down_to, new_esp, valid_up_to ); */
1550 VGM_(make_noaccess) ( invalid_down_to, new_esp - invalid_down_to );
sewardj1e8cdc92002-04-18 11:37:52 +00001551 if (!is_plausible_stack_addr(tst, new_esp)) {
sewardjde4a1d02002-03-22 01:27:54 +00001552 VGM_(make_readable) ( new_esp, valid_up_to - new_esp );
1553 }
1554 }
1555}
1556
1557
1558/*--------------------------------------------------------------*/
1559/*--- Initialise the memory audit system on program startup. ---*/
1560/*--------------------------------------------------------------*/
1561
1562/* Handle one entry derived from /proc/self/maps. */
1563
1564static
1565void init_memory_audit_callback (
1566 Addr start, UInt size,
1567 Char rr, Char ww, Char xx,
1568 UInt foffset, UChar* filename )
1569{
1570 UChar example_a_bit;
1571 UChar example_v_bit;
1572 UInt r_esp;
1573 Bool is_stack_segment;
1574
1575 /* Sanity check ... if this is the executable's text segment,
1576 ensure it is loaded where we think it ought to be. Any file
1577 name which doesn't contain ".so" is assumed to be the
1578 executable. */
1579 if (filename != NULL
1580 && xx == 'x'
1581 && VG_(strstr(filename, ".so")) == NULL
1582 ) {
1583 /* We assume this is the executable. */
1584 if (start != VG_ASSUMED_EXE_BASE) {
1585 VG_(message)(Vg_UserMsg,
1586 "FATAL: executable base addr not as assumed.");
1587 VG_(message)(Vg_UserMsg, "name %s, actual %p, assumed %p.",
1588 filename, start, VG_ASSUMED_EXE_BASE);
sewardjc7c6aed2002-03-24 12:03:00 +00001589 VG_(message)(Vg_UserMsg,
1590 "One reason this could happen is that you have a shared object");
1591 VG_(message)(Vg_UserMsg,
1592 " whose name doesn't contain the characters \".so\", so Valgrind ");
1593 VG_(message)(Vg_UserMsg,
1594 "naively assumes it is the executable. ");
1595 VG_(message)(Vg_UserMsg,
1596 "In that case, rename it appropriately.");
sewardjde4a1d02002-03-22 01:27:54 +00001597 VG_(panic)("VG_ASSUMED_EXE_BASE doesn't match reality");
1598 }
1599 }
1600
1601 if (0)
1602 VG_(message)(Vg_DebugMsg,
1603 "initial map %8x-%8x %c%c%c? %8x (%d) (%s)",
1604 start,start+size,rr,ww,xx,foffset,
1605 size, filename?filename:(UChar*)"NULL");
1606
1607 r_esp = VG_(baseBlock)[VGOFF_(m_esp)];
1608 is_stack_segment = start <= r_esp && r_esp < start+size;
1609
1610 /* Figure out the segment's permissions.
1611
1612 All segments are addressible -- since a process can read its
1613 own text segment.
1614
1615 A read-but-not-write segment presumably contains initialised
1616 data, so is all valid. Read-write segments presumably contains
1617 uninitialised data, so is all invalid. */
1618
1619 /* ToDo: make this less bogus. */
1620 if (rr != 'r' && xx != 'x' && ww != 'w') {
1621 /* Very bogus; this path never gets taken. */
1622 /* A no, V no */
1623 example_a_bit = VGM_BIT_INVALID;
1624 example_v_bit = VGM_BIT_INVALID;
1625 } else {
1626 /* A yes, V yes */
1627 example_a_bit = VGM_BIT_VALID;
1628 example_v_bit = VGM_BIT_VALID;
1629 /* Causes a lot of errs for unknown reasons.
1630 if (filename is valgrind.so
1631 [careful about end conditions on filename]) {
1632 example_a_bit = VGM_BIT_INVALID;
1633 example_v_bit = VGM_BIT_INVALID;
1634 }
1635 */
1636 }
1637
1638 set_address_range_perms ( start, size,
1639 example_a_bit, example_v_bit );
1640
1641 if (is_stack_segment) {
1642 /* This is the stack segment. Mark all below %esp as
1643 noaccess. */
1644 if (0)
1645 VG_(message)(Vg_DebugMsg,
1646 "invalidating stack area: %x .. %x",
1647 start,r_esp);
1648 VGM_(make_noaccess)( start, r_esp-start );
1649 }
1650}
1651
1652
sewardjde4a1d02002-03-22 01:27:54 +00001653/* Initialise the memory audit system. */
1654void VGM_(init_memory_audit) ( void )
1655{
1656 Int i;
1657
1658 init_prof_mem();
1659
1660 for (i = 0; i < 8192; i++)
1661 vg_distinguished_secondary_map.abits[i]
1662 = VGM_BYTE_INVALID; /* Invalid address */
1663 for (i = 0; i < 65536; i++)
1664 vg_distinguished_secondary_map.vbyte[i]
1665 = VGM_BYTE_INVALID; /* Invalid Value */
1666
1667 /* These entries gradually get overwritten as the used address
1668 space expands. */
1669 for (i = 0; i < 65536; i++)
1670 VG_(primary_map)[i] = &vg_distinguished_secondary_map;
1671 /* These ones should never change; it's a bug in Valgrind if they
1672 do. */
1673 for (i = 65536; i < 262144; i++)
1674 VG_(primary_map)[i] = &vg_distinguished_secondary_map;
1675
1676 /* Read the initial memory mapping from the /proc filesystem, and
1677 set up our own maps accordingly. */
1678 VG_(read_procselfmaps) ( init_memory_audit_callback );
1679
1680 /* Last but not least, set up the shadow regs with reasonable (sic)
1681 values. All regs are claimed to have valid values.
1682 */
1683 VG_(baseBlock)[VGOFF_(sh_esp)] = VGM_WORD_VALID;
1684 VG_(baseBlock)[VGOFF_(sh_ebp)] = VGM_WORD_VALID;
1685 VG_(baseBlock)[VGOFF_(sh_eax)] = VGM_WORD_VALID;
1686 VG_(baseBlock)[VGOFF_(sh_ecx)] = VGM_WORD_VALID;
1687 VG_(baseBlock)[VGOFF_(sh_edx)] = VGM_WORD_VALID;
1688 VG_(baseBlock)[VGOFF_(sh_ebx)] = VGM_WORD_VALID;
1689 VG_(baseBlock)[VGOFF_(sh_esi)] = VGM_WORD_VALID;
1690 VG_(baseBlock)[VGOFF_(sh_edi)] = VGM_WORD_VALID;
1691 VG_(baseBlock)[VGOFF_(sh_eflags)] = VGM_EFLAGS_VALID;
1692
1693 /* Record the end of the data segment, so that vg_syscall_mem.c
1694 can make sense of calls to brk().
1695 */
sewardjb3586202002-05-09 17:38:13 +00001696 VGM_(curr_dataseg_end) = (Addr)VG_(brk)(0);
sewardjde4a1d02002-03-22 01:27:54 +00001697 if (VGM_(curr_dataseg_end) == (Addr)(-1))
1698 VG_(panic)("vgm_init_memory_audit: can't determine data-seg end");
1699
1700 if (0)
sewardj9a199dc2002-04-14 13:01:38 +00001701 VG_(printf)("DS END is %p\n", (void*)VGM_(curr_dataseg_end));
sewardjde4a1d02002-03-22 01:27:54 +00001702
1703 /* Read the list of errors to suppress. This should be found in
1704 the file specified by vg_clo_suppressions. */
1705 VG_(load_suppressions)();
1706}
1707
1708
1709/*------------------------------------------------------------*/
1710/*--- Low-level address-space scanning, for the leak ---*/
1711/*--- detector. ---*/
1712/*------------------------------------------------------------*/
1713
1714static
1715jmp_buf memscan_jmpbuf;
1716
1717static
1718void vg_scan_all_valid_memory_sighandler ( Int sigNo )
1719{
1720 __builtin_longjmp(memscan_jmpbuf, 1);
1721}
1722
1723UInt VG_(scan_all_valid_memory) ( void (*notify_word)( Addr, UInt ) )
1724{
1725 /* All volatile, because some gccs seem paranoid about longjmp(). */
1726 volatile UInt res, numPages, page, vbytes, primaryMapNo, nWordsNotified;
1727 volatile Addr pageBase, addr;
1728 volatile SecMap* sm;
1729 volatile UChar abits;
1730 volatile UInt page_first_word;
1731
1732 vki_ksigaction sigbus_saved;
1733 vki_ksigaction sigbus_new;
1734 vki_ksigaction sigsegv_saved;
1735 vki_ksigaction sigsegv_new;
1736 vki_ksigset_t blockmask_saved;
1737 vki_ksigset_t unblockmask_new;
1738
1739 /* Temporarily install a new sigsegv and sigbus handler, and make
1740 sure SIGBUS, SIGSEGV and SIGTERM are unblocked. (Perhaps the
1741 first two can never be blocked anyway?) */
1742
1743 sigbus_new.ksa_handler = vg_scan_all_valid_memory_sighandler;
1744 sigbus_new.ksa_flags = VKI_SA_ONSTACK | VKI_SA_RESTART;
1745 sigbus_new.ksa_restorer = NULL;
1746 res = VG_(ksigemptyset)( &sigbus_new.ksa_mask );
1747 vg_assert(res == 0);
1748
1749 sigsegv_new.ksa_handler = vg_scan_all_valid_memory_sighandler;
1750 sigsegv_new.ksa_flags = VKI_SA_ONSTACK | VKI_SA_RESTART;
1751 sigsegv_new.ksa_restorer = NULL;
1752 res = VG_(ksigemptyset)( &sigsegv_new.ksa_mask );
1753 vg_assert(res == 0+0);
1754
1755 res = VG_(ksigemptyset)( &unblockmask_new );
1756 res |= VG_(ksigaddset)( &unblockmask_new, VKI_SIGBUS );
1757 res |= VG_(ksigaddset)( &unblockmask_new, VKI_SIGSEGV );
1758 res |= VG_(ksigaddset)( &unblockmask_new, VKI_SIGTERM );
1759 vg_assert(res == 0+0+0);
1760
1761 res = VG_(ksigaction)( VKI_SIGBUS, &sigbus_new, &sigbus_saved );
1762 vg_assert(res == 0+0+0+0);
1763
1764 res = VG_(ksigaction)( VKI_SIGSEGV, &sigsegv_new, &sigsegv_saved );
1765 vg_assert(res == 0+0+0+0+0);
1766
1767 res = VG_(ksigprocmask)( VKI_SIG_UNBLOCK, &unblockmask_new, &blockmask_saved );
1768 vg_assert(res == 0+0+0+0+0+0);
1769
1770 /* The signal handlers are installed. Actually do the memory scan. */
1771 numPages = 1 << (32-VKI_BYTES_PER_PAGE_BITS);
1772 vg_assert(numPages == 1048576);
1773 vg_assert(4096 == (1 << VKI_BYTES_PER_PAGE_BITS));
1774
1775 nWordsNotified = 0;
1776
1777 for (page = 0; page < numPages; page++) {
1778 pageBase = page << VKI_BYTES_PER_PAGE_BITS;
1779 primaryMapNo = pageBase >> 16;
1780 sm = VG_(primary_map)[primaryMapNo];
1781 if (IS_DISTINGUISHED_SM(sm)) continue;
1782 if (__builtin_setjmp(memscan_jmpbuf) == 0) {
1783 /* try this ... */
1784 page_first_word = * (volatile UInt*)pageBase;
1785 /* we get here if we didn't get a fault */
1786 /* Scan the page */
1787 for (addr = pageBase; addr < pageBase+VKI_BYTES_PER_PAGE; addr += 4) {
1788 abits = get_abits4_ALIGNED(addr);
1789 vbytes = get_vbytes4_ALIGNED(addr);
1790 if (abits == VGM_NIBBLE_VALID
1791 && vbytes == VGM_WORD_VALID) {
1792 nWordsNotified++;
1793 notify_word ( addr, *(UInt*)addr );
1794 }
1795 }
1796 } else {
1797 /* We get here if reading the first word of the page caused a
1798 fault, which in turn caused the signal handler to longjmp.
1799 Ignore this page. */
1800 if (0)
1801 VG_(printf)(
1802 "vg_scan_all_valid_memory_sighandler: ignoring page at %p\n",
sewardj9a199dc2002-04-14 13:01:38 +00001803 (void*)pageBase
sewardjde4a1d02002-03-22 01:27:54 +00001804 );
1805 }
1806 }
1807
1808 /* Restore signal state to whatever it was before. */
1809 res = VG_(ksigaction)( VKI_SIGBUS, &sigbus_saved, NULL );
1810 vg_assert(res == 0 +0);
1811
1812 res = VG_(ksigaction)( VKI_SIGSEGV, &sigsegv_saved, NULL );
1813 vg_assert(res == 0 +0 +0);
1814
1815 res = VG_(ksigprocmask)( VKI_SIG_SETMASK, &blockmask_saved, NULL );
1816 vg_assert(res == 0 +0 +0 +0);
1817
1818 return nWordsNotified;
1819}
1820
1821
1822/*------------------------------------------------------------*/
1823/*--- Detecting leaked (unreachable) malloc'd blocks. ---*/
1824/*------------------------------------------------------------*/
1825
1826/* A block is either
1827 -- Proper-ly reached; a pointer to its start has been found
1828 -- Interior-ly reached; only an interior pointer to it has been found
1829 -- Unreached; so far, no pointers to any part of it have been found.
1830*/
1831typedef
1832 enum { Unreached, Interior, Proper }
1833 Reachedness;
1834
1835/* A block record, used for generating err msgs. */
1836typedef
1837 struct _LossRecord {
1838 struct _LossRecord* next;
1839 /* Where these lost blocks were allocated. */
1840 ExeContext* allocated_at;
1841 /* Their reachability. */
1842 Reachedness loss_mode;
1843 /* Number of blocks and total # bytes involved. */
1844 UInt total_bytes;
1845 UInt num_blocks;
1846 }
1847 LossRecord;
1848
1849
1850/* Find the i such that ptr points at or inside the block described by
1851 shadows[i]. Return -1 if none found. This assumes that shadows[]
1852 has been sorted on the ->data field. */
1853
1854#ifdef VG_DEBUG_LEAKCHECK
1855/* Used to sanity-check the fast binary-search mechanism. */
1856static Int find_shadow_for_OLD ( Addr ptr,
1857 ShadowChunk** shadows,
1858 Int n_shadows )
1859
1860{
1861 Int i;
1862 Addr a_lo, a_hi;
1863 PROF_EVENT(70);
1864 for (i = 0; i < n_shadows; i++) {
1865 PROF_EVENT(71);
1866 a_lo = shadows[i]->data;
1867 a_hi = ((Addr)shadows[i]->data) + shadows[i]->size - 1;
1868 if (a_lo <= ptr && ptr <= a_hi)
1869 return i;
1870 }
1871 return -1;
1872}
1873#endif
1874
1875
1876static Int find_shadow_for ( Addr ptr,
1877 ShadowChunk** shadows,
1878 Int n_shadows )
1879{
1880 Addr a_mid_lo, a_mid_hi;
1881 Int lo, mid, hi, retVal;
1882 PROF_EVENT(70);
1883 /* VG_(printf)("find shadow for %p = ", ptr); */
1884 retVal = -1;
1885 lo = 0;
1886 hi = n_shadows-1;
1887 while (True) {
1888 PROF_EVENT(71);
1889
1890 /* invariant: current unsearched space is from lo to hi,
1891 inclusive. */
1892 if (lo > hi) break; /* not found */
1893
1894 mid = (lo + hi) / 2;
1895 a_mid_lo = shadows[mid]->data;
1896 a_mid_hi = ((Addr)shadows[mid]->data) + shadows[mid]->size - 1;
1897
1898 if (ptr < a_mid_lo) {
1899 hi = mid-1;
1900 continue;
1901 }
1902 if (ptr > a_mid_hi) {
1903 lo = mid+1;
1904 continue;
1905 }
1906 vg_assert(ptr >= a_mid_lo && ptr <= a_mid_hi);
1907 retVal = mid;
1908 break;
1909 }
1910
1911# ifdef VG_DEBUG_LEAKCHECK
1912 vg_assert(retVal == find_shadow_for_OLD ( ptr, shadows, n_shadows ));
1913# endif
1914 /* VG_(printf)("%d\n", retVal); */
1915 return retVal;
1916}
1917
1918
1919
1920static void sort_malloc_shadows ( ShadowChunk** shadows, UInt n_shadows )
1921{
1922 Int incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
1923 9841, 29524, 88573, 265720,
1924 797161, 2391484 };
1925 Int lo = 0;
1926 Int hi = n_shadows-1;
1927 Int i, j, h, bigN, hp;
1928 ShadowChunk* v;
1929
1930 PROF_EVENT(72);
1931 bigN = hi - lo + 1; if (bigN < 2) return;
1932 hp = 0; while (incs[hp] < bigN) hp++; hp--;
1933
1934 for (; hp >= 0; hp--) {
1935 PROF_EVENT(73);
1936 h = incs[hp];
1937 i = lo + h;
1938 while (1) {
1939 PROF_EVENT(74);
1940 if (i > hi) break;
1941 v = shadows[i];
1942 j = i;
1943 while (shadows[j-h]->data > v->data) {
1944 PROF_EVENT(75);
1945 shadows[j] = shadows[j-h];
1946 j = j - h;
1947 if (j <= (lo + h - 1)) break;
1948 }
1949 shadows[j] = v;
1950 i++;
1951 }
1952 }
1953}
1954
1955/* Globals, for the callback used by VG_(detect_memory_leaks). */
1956
1957static ShadowChunk** vglc_shadows;
1958static Int vglc_n_shadows;
1959static Reachedness* vglc_reachedness;
1960static Addr vglc_min_mallocd_addr;
1961static Addr vglc_max_mallocd_addr;
1962
1963static
1964void vg_detect_memory_leaks_notify_addr ( Addr a, UInt word_at_a )
1965{
1966 Int sh_no;
1967 Addr ptr = (Addr)word_at_a;
1968 if (ptr >= vglc_min_mallocd_addr && ptr <= vglc_max_mallocd_addr) {
1969 /* Might be legitimate; we'll have to investigate further. */
1970 sh_no = find_shadow_for ( ptr, vglc_shadows, vglc_n_shadows );
1971 if (sh_no != -1) {
1972 /* Found a block at/into which ptr points. */
1973 vg_assert(sh_no >= 0 && sh_no < vglc_n_shadows);
1974 vg_assert(ptr < vglc_shadows[sh_no]->data
1975 + vglc_shadows[sh_no]->size);
1976 /* Decide whether Proper-ly or Interior-ly reached. */
1977 if (ptr == vglc_shadows[sh_no]->data) {
1978 vglc_reachedness[sh_no] = Proper;
1979 } else {
1980 if (vglc_reachedness[sh_no] == Unreached)
1981 vglc_reachedness[sh_no] = Interior;
1982 }
1983 }
1984 }
1985}
1986
1987
1988void VG_(detect_memory_leaks) ( void )
1989{
1990 Int i;
1991 Int blocks_leaked, bytes_leaked;
1992 Int blocks_dubious, bytes_dubious;
1993 Int blocks_reachable, bytes_reachable;
1994 Int n_lossrecords;
1995 UInt bytes_notified;
1996
1997 LossRecord* errlist;
1998 LossRecord* p;
1999
2000 Bool (*ec_comparer_fn) ( ExeContext*, ExeContext* );
2001 PROF_EVENT(76);
2002 vg_assert(VG_(clo_instrument));
2003
2004 /* Decide how closely we want to match ExeContexts in leak
2005 records. */
2006 switch (VG_(clo_leak_resolution)) {
2007 case 2:
2008 ec_comparer_fn = VG_(eq_ExeContext_top2);
2009 break;
2010 case 4:
2011 ec_comparer_fn = VG_(eq_ExeContext_top4);
2012 break;
2013 case VG_DEEPEST_BACKTRACE:
2014 ec_comparer_fn = VG_(eq_ExeContext_all);
2015 break;
2016 default:
2017 VG_(panic)("VG_(detect_memory_leaks): "
2018 "bad VG_(clo_leak_resolution)");
2019 break;
2020 }
2021
2022 /* vg_get_malloc_shadows allocates storage for shadows */
2023 vglc_shadows = VG_(get_malloc_shadows)( &vglc_n_shadows );
2024 if (vglc_n_shadows == 0) {
2025 vg_assert(vglc_shadows == NULL);
2026 VG_(message)(Vg_UserMsg,
2027 "No malloc'd blocks -- no leaks are possible.\n");
2028 return;
2029 }
2030
2031 VG_(message)(Vg_UserMsg,
2032 "searching for pointers to %d not-freed blocks.",
2033 vglc_n_shadows );
2034 sort_malloc_shadows ( vglc_shadows, vglc_n_shadows );
2035
2036 /* Sanity check; assert that the blocks are now in order and that
2037 they don't overlap. */
2038 for (i = 0; i < vglc_n_shadows-1; i++) {
2039 vg_assert( ((Addr)vglc_shadows[i]->data)
2040 < ((Addr)vglc_shadows[i+1]->data) );
2041 vg_assert( ((Addr)vglc_shadows[i]->data) + vglc_shadows[i]->size
2042 < ((Addr)vglc_shadows[i+1]->data) );
2043 }
2044
2045 vglc_min_mallocd_addr = ((Addr)vglc_shadows[0]->data);
2046 vglc_max_mallocd_addr = ((Addr)vglc_shadows[vglc_n_shadows-1]->data)
2047 + vglc_shadows[vglc_n_shadows-1]->size - 1;
2048
2049 vglc_reachedness
2050 = VG_(malloc)( VG_AR_PRIVATE, vglc_n_shadows * sizeof(Reachedness) );
2051 for (i = 0; i < vglc_n_shadows; i++)
2052 vglc_reachedness[i] = Unreached;
2053
2054 /* Do the scan of memory. */
2055 bytes_notified
2056 = VG_(scan_all_valid_memory)( &vg_detect_memory_leaks_notify_addr )
2057 * VKI_BYTES_PER_WORD;
2058
2059 VG_(message)(Vg_UserMsg, "checked %d bytes.", bytes_notified);
2060
2061 blocks_leaked = bytes_leaked = 0;
2062 blocks_dubious = bytes_dubious = 0;
2063 blocks_reachable = bytes_reachable = 0;
2064
2065 for (i = 0; i < vglc_n_shadows; i++) {
2066 if (vglc_reachedness[i] == Unreached) {
2067 blocks_leaked++;
2068 bytes_leaked += vglc_shadows[i]->size;
2069 }
2070 else if (vglc_reachedness[i] == Interior) {
2071 blocks_dubious++;
2072 bytes_dubious += vglc_shadows[i]->size;
2073 }
2074 else if (vglc_reachedness[i] == Proper) {
2075 blocks_reachable++;
2076 bytes_reachable += vglc_shadows[i]->size;
2077 }
2078 }
2079
2080 VG_(message)(Vg_UserMsg, "");
2081 VG_(message)(Vg_UserMsg, "definitely lost: %d bytes in %d blocks.",
2082 bytes_leaked, blocks_leaked );
2083 VG_(message)(Vg_UserMsg, "possibly lost: %d bytes in %d blocks.",
2084 bytes_dubious, blocks_dubious );
2085 VG_(message)(Vg_UserMsg, "still reachable: %d bytes in %d blocks.",
2086 bytes_reachable, blocks_reachable );
2087
2088
2089 /* Common up the lost blocks so we can print sensible error
2090 messages. */
2091
2092 n_lossrecords = 0;
2093 errlist = NULL;
2094 for (i = 0; i < vglc_n_shadows; i++) {
2095 for (p = errlist; p != NULL; p = p->next) {
2096 if (p->loss_mode == vglc_reachedness[i]
2097 && ec_comparer_fn (
2098 p->allocated_at,
2099 vglc_shadows[i]->where) ) {
2100 break;
2101 }
2102 }
2103 if (p != NULL) {
2104 p->num_blocks ++;
2105 p->total_bytes += vglc_shadows[i]->size;
2106 } else {
2107 n_lossrecords ++;
2108 p = VG_(malloc)(VG_AR_PRIVATE, sizeof(LossRecord));
2109 p->loss_mode = vglc_reachedness[i];
2110 p->allocated_at = vglc_shadows[i]->where;
2111 p->total_bytes = vglc_shadows[i]->size;
2112 p->num_blocks = 1;
2113 p->next = errlist;
2114 errlist = p;
2115 }
2116 }
2117
2118 for (i = 0; i < n_lossrecords; i++) {
2119 LossRecord* p_min = NULL;
2120 UInt n_min = 0xFFFFFFFF;
2121 for (p = errlist; p != NULL; p = p->next) {
2122 if (p->num_blocks > 0 && p->total_bytes < n_min) {
2123 n_min = p->total_bytes;
2124 p_min = p;
2125 }
2126 }
2127 vg_assert(p_min != NULL);
2128
2129 if ( (!VG_(clo_show_reachable)) && p_min->loss_mode == Proper) {
2130 p_min->num_blocks = 0;
2131 continue;
2132 }
2133
2134 VG_(message)(Vg_UserMsg, "");
2135 VG_(message)(
2136 Vg_UserMsg,
2137 "%d bytes in %d blocks are %s in loss record %d of %d",
2138 p_min->total_bytes, p_min->num_blocks,
2139 p_min->loss_mode==Unreached ? "definitely lost" :
2140 (p_min->loss_mode==Interior ? "possibly lost"
2141 : "still reachable"),
2142 i+1, n_lossrecords
2143 );
2144 VG_(pp_ExeContext)(p_min->allocated_at);
2145 p_min->num_blocks = 0;
2146 }
2147
2148 VG_(message)(Vg_UserMsg, "");
2149 VG_(message)(Vg_UserMsg, "LEAK SUMMARY:");
2150 VG_(message)(Vg_UserMsg, " possibly lost: %d bytes in %d blocks.",
2151 bytes_dubious, blocks_dubious );
2152 VG_(message)(Vg_UserMsg, " definitely lost: %d bytes in %d blocks.",
2153 bytes_leaked, blocks_leaked );
2154 VG_(message)(Vg_UserMsg, " still reachable: %d bytes in %d blocks.",
2155 bytes_reachable, blocks_reachable );
2156 if (!VG_(clo_show_reachable)) {
2157 VG_(message)(Vg_UserMsg,
2158 "Reachable blocks (those to which a pointer was found) are not shown.");
2159 VG_(message)(Vg_UserMsg,
2160 "To see them, rerun with: --show-reachable=yes");
2161 }
2162 VG_(message)(Vg_UserMsg, "");
2163
2164 VG_(free) ( VG_AR_PRIVATE, vglc_shadows );
2165 VG_(free) ( VG_AR_PRIVATE, vglc_reachedness );
2166}
2167
2168
2169/* ---------------------------------------------------------------------
2170 Sanity check machinery (permanently engaged).
2171 ------------------------------------------------------------------ */
2172
2173/* Check that nobody has spuriously claimed that the first or last 16
2174 pages (64 KB) of address space have become accessible. Failure of
2175 the following do not per se indicate an internal consistency
2176 problem, but they are so likely to that we really want to know
2177 about it if so. */
2178
2179Bool VG_(first_and_last_secondaries_look_plausible) ( void )
2180{
2181 if (IS_DISTINGUISHED_SM(VG_(primary_map)[0])
2182 && IS_DISTINGUISHED_SM(VG_(primary_map)[65535])) {
2183 return True;
2184 } else {
2185 return False;
2186 }
2187}
2188
2189
2190/* A fast sanity check -- suitable for calling circa once per
2191 millisecond. */
2192
sewardj0c3b53f2002-05-01 01:58:35 +00002193void VG_(do_sanity_checks) ( Bool force_expensive )
sewardjde4a1d02002-03-22 01:27:54 +00002194{
sewardj2e93c502002-04-12 11:12:52 +00002195 Int i;
2196 Bool do_expensive_checks;
sewardjde4a1d02002-03-22 01:27:54 +00002197
2198 if (VG_(sanity_level) < 1) return;
2199
2200 /* --- First do all the tests that we can do quickly. ---*/
2201
2202 VG_(sanity_fast_count)++;
2203
2204 /* Check that we haven't overrun our private stack. */
2205 for (i = 0; i < 10; i++) {
2206 vg_assert(VG_(stack)[i]
2207 == ((UInt)(&VG_(stack)[i]) ^ 0xA4B3C2D1));
2208 vg_assert(VG_(stack)[10000-1-i]
2209 == ((UInt)(&VG_(stack)[10000-i-1]) ^ 0xABCD4321));
2210 }
2211
2212 /* Check stuff pertaining to the memory check system. */
2213
2214 if (VG_(clo_instrument)) {
2215
sewardjde4a1d02002-03-22 01:27:54 +00002216 /* Check that nobody has spuriously claimed that the first or
2217 last 16 pages of memory have become accessible [...] */
sewardj126a41f2002-05-07 23:45:03 +00002218 vg_assert(VG_(first_and_last_secondaries_look_plausible)());
sewardjde4a1d02002-03-22 01:27:54 +00002219 }
2220
sewardjde4a1d02002-03-22 01:27:54 +00002221 /* --- Now some more expensive checks. ---*/
2222
2223 /* Once every 25 times, check some more expensive stuff. */
2224
2225 do_expensive_checks = False;
2226 if (force_expensive)
2227 do_expensive_checks = True;
2228 if (VG_(sanity_level) > 1)
2229 do_expensive_checks = True;
2230 if (VG_(sanity_level) == 1
2231 && (VG_(sanity_fast_count) % 25) == 0)
2232 do_expensive_checks = True;
2233
2234 if (do_expensive_checks) {
2235 VG_(sanity_slow_count)++;
2236
2237# if 0
2238 { void zzzmemscan(void); zzzmemscan(); }
2239# endif
2240
2241 if ((VG_(sanity_fast_count) % 250) == 0)
2242 VG_(sanity_check_tc_tt)();
2243
2244 if (VG_(clo_instrument)) {
2245 /* Make sure nobody changed the distinguished secondary. */
2246 for (i = 0; i < 8192; i++)
2247 vg_assert(vg_distinguished_secondary_map.abits[i]
2248 == VGM_BYTE_INVALID);
2249 for (i = 0; i < 65536; i++)
2250 vg_assert(vg_distinguished_secondary_map.vbyte[i]
2251 == VGM_BYTE_INVALID);
2252
2253 /* Make sure that the upper 3/4 of the primary map hasn't
2254 been messed with. */
2255 for (i = 65536; i < 262144; i++)
2256 vg_assert(VG_(primary_map)[i]
2257 == & vg_distinguished_secondary_map);
2258 }
2259 /*
2260 if ((VG_(sanity_fast_count) % 500) == 0) VG_(mallocSanityCheckAll)();
2261 */
2262 }
2263
2264 if (VG_(sanity_level) > 1) {
2265 /* Check sanity of the low-level memory manager. Note that bugs
2266 in the client's code can cause this to fail, so we don't do
2267 this check unless specially asked for. And because it's
2268 potentially very expensive. */
2269 VG_(mallocSanityCheckAll)();
2270 }
2271}
2272
2273
2274/* ---------------------------------------------------------------------
2275 Debugging machinery (turn on to debug). Something of a mess.
2276 ------------------------------------------------------------------ */
2277
2278/* Print the value tags on the 8 integer registers & flag reg. */
2279
2280static void uint_to_bits ( UInt x, Char* str )
2281{
2282 Int i;
2283 Int w = 0;
2284 /* str must point to a space of at least 36 bytes. */
2285 for (i = 31; i >= 0; i--) {
2286 str[w++] = (x & ( ((UInt)1) << i)) ? '1' : '0';
2287 if (i == 24 || i == 16 || i == 8)
2288 str[w++] = ' ';
2289 }
2290 str[w++] = 0;
2291 vg_assert(w == 36);
2292}
2293
sewardj2e93c502002-04-12 11:12:52 +00002294/* Caution! Not vthread-safe; looks in VG_(baseBlock), not the thread
2295 state table. */
2296
sewardjde4a1d02002-03-22 01:27:54 +00002297void VG_(show_reg_tags) ( void )
2298{
2299 Char buf1[36];
2300 Char buf2[36];
2301 UInt z_eax, z_ebx, z_ecx, z_edx,
2302 z_esi, z_edi, z_ebp, z_esp, z_eflags;
2303
2304 z_eax = VG_(baseBlock)[VGOFF_(sh_eax)];
2305 z_ebx = VG_(baseBlock)[VGOFF_(sh_ebx)];
2306 z_ecx = VG_(baseBlock)[VGOFF_(sh_ecx)];
2307 z_edx = VG_(baseBlock)[VGOFF_(sh_edx)];
2308 z_esi = VG_(baseBlock)[VGOFF_(sh_esi)];
2309 z_edi = VG_(baseBlock)[VGOFF_(sh_edi)];
2310 z_ebp = VG_(baseBlock)[VGOFF_(sh_ebp)];
2311 z_esp = VG_(baseBlock)[VGOFF_(sh_esp)];
2312 z_eflags = VG_(baseBlock)[VGOFF_(sh_eflags)];
2313
2314 uint_to_bits(z_eflags, buf1);
2315 VG_(message)(Vg_DebugMsg, "efl %\n", buf1);
2316
2317 uint_to_bits(z_eax, buf1);
2318 uint_to_bits(z_ebx, buf2);
2319 VG_(message)(Vg_DebugMsg, "eax %s ebx %s\n", buf1, buf2);
2320
2321 uint_to_bits(z_ecx, buf1);
2322 uint_to_bits(z_edx, buf2);
2323 VG_(message)(Vg_DebugMsg, "ecx %s edx %s\n", buf1, buf2);
2324
2325 uint_to_bits(z_esi, buf1);
2326 uint_to_bits(z_edi, buf2);
2327 VG_(message)(Vg_DebugMsg, "esi %s edi %s\n", buf1, buf2);
2328
2329 uint_to_bits(z_ebp, buf1);
2330 uint_to_bits(z_esp, buf2);
2331 VG_(message)(Vg_DebugMsg, "ebp %s esp %s\n", buf1, buf2);
2332}
2333
2334
2335#if 0
2336/* For debugging only. Scan the address space and touch all allegedly
2337 addressible words. Useful for establishing where Valgrind's idea of
2338 addressibility has diverged from what the kernel believes. */
2339
2340static
2341void zzzmemscan_notify_word ( Addr a, UInt w )
2342{
2343}
2344
2345void zzzmemscan ( void )
2346{
2347 Int n_notifies
2348 = VG_(scan_all_valid_memory)( zzzmemscan_notify_word );
2349 VG_(printf)("zzzmemscan: n_bytes = %d\n", 4 * n_notifies );
2350}
2351#endif
2352
2353
2354
2355
2356#if 0
2357static Int zzz = 0;
2358
2359void show_bb ( Addr eip_next )
2360{
2361 VG_(printf)("[%4d] ", zzz);
2362 VG_(show_reg_tags)( &VG_(m_shadow );
2363 VG_(translate) ( eip_next, NULL, NULL, NULL );
2364}
2365#endif /* 0 */
2366
2367/*--------------------------------------------------------------------*/
2368/*--- end vg_memory.c ---*/
2369/*--------------------------------------------------------------------*/