1 /* BLURB lgpl
2 
3                            Coda File System
4                               Release 5
5 
6           Copyright (c) 1987-2016 Carnegie Mellon University
7                   Additional copyrights listed below
8 
9 This  code  is  distributed "AS IS" without warranty of any kind under
10 the  terms of the  GNU  Library General Public Licence  Version 2,  as
11 shown in the file LICENSE. The technical and financial contributors to
12 Coda are listed in the file CREDITS.
13 
14                         Additional copyrights
15                            none currently
16 
17 #*/
18 
19 /*
20 *
21 *                   RVM internal structure debugging functions
22 *
23 */
24 
25 #include <sys/types.h>
26 #include <sys/uio.h>
27 #include <stdio.h>
28 #include "rvm_private.h"
29 
30 /* globals */
31 
32 extern rvm_length_t     page_size;
33 extern rvm_length_t     page_mask;
34 extern rvm_bool_t       rvm_no_log;
35 extern char             *rvm_errmsg; /* internal error message buffer */
36 
37 /* roots of memory structures */
38 
39 /* structure cache */
40 extern long             type_counts[NUM_CACHE_TYPES];
41 extern list_entry_t     free_lists[NUM_CACHE_TYPES];
42 extern long             pre_alloc[NUM_CACHE_TYPES];
43 extern long             max_alloc[NUM_CACHE_TYPES];
44 extern long             cache_type_sizes[NUM_CACHE_TYPES];
45 
46 /* main structures roots */
47 extern list_entry_t     seg_root;       /* segment list */
48 extern tree_node_t      *region_tree;   /* mapped regions tree */
49 extern list_entry_t     page_list;      /* free page list */
50 extern list_entry_t     log_root;       /* log list */
51 
52 /* locals */
53 
54 /* structure names & sizes for debug support */
55 #ifdef DEBUG_GDB
56 static char             *type_names[NUM_TYPES]
57                             = {TYPE_NAMES};
58 static rvm_length_t     type_sizes[NUM_TYPES]
59                             = {CACHE_TYPE_SIZES,OTHER_TYPE_SIZES};
60 #define SIZE(id)        (type_sizes[ID_INDEX(id)])
61 #define NAME(id)        (type_names[ID_INDEX(id)])
62 
63 /* address is in a structure */
64 #define IN_STRUCT(x,s,id) \
65                         (((x) >= (rvm_length_t)(s)) && \
66                          ((x) < (((rvm_length_t)(s))+SIZE(id))))
67 
68 /* address validation: must be on rvm_length_t size boundary */
69 #define ADDR_INVALID(x) ((rvm_length_t)(x) != CHOP_TO_LENGTH((x)))
70 
71 #define ADDR_INVALID_OR_NULL(x) \
72                         (ADDR_INVALID(x) || ((x) == NULL))
73 #endif /* DEBUG_GDB */
74 
75 /* empty routine to force loading of this module when referenced by a program
76    can also be used as a break point when a condition must be calculated */
rvm_debug(val)77 void rvm_debug(val)
78     rvm_length_t       val;
79     {
80     if (val != 0)
81         printf("\nAt rvm_debug: %ld (%lx)\n",val,val);
82     }
83 
84 #ifdef DEBUG_GDB
85 /* power of 2 table -- must be extended for machines with address
86      spaces greater than 32 bits */
87 #define NUM_TWOS        30
88 static rvm_length_t     twos[NUM_TWOS] =
89                             {
90                             1<<3,1<<4,1<<5,1<<6,1<<7,1<<8,1<<9,1<<10,
91                             1<<11,1<<12,1<<13,1<<14,1<<15,1<<16,1<<17,
92                             1<<18,1<<19,1<<20,1<<21,1<<22,1<<23,1<<24,
93                             1<<25,1<<26,1<<27,1<<28,1<<29,1<<30,1<<31,
94                             -1
95                             };
96 /* test ifaddress is in heap-allocated space */
in_heap(addr,buf,len)97 rvm_bool_t in_heap(addr,buf,len)
98     rvm_length_t        addr;           /* address to search for */
99     rvm_length_t        buf;            /* buffer to search */
100     rvm_length_t        len;            /* requested length of buffer */
101     {
102     long                i;
103 
104     if (buf == 0) return rvm_false;     /* skip null buffers */
105 
106     len += sizeof(rvm_length_t);        /* compensate for malloc back ptr */
107     buf -= sizeof(rvm_length_t);
108     for (i=0; i<NUM_TWOS; i++)
109         if ((len >= twos[i]) && (len < twos[i+1]))
110             break;
111     assert(i != NUM_TWOS);
112 
113     if ((addr >= buf) && (addr < (buf+twos[i])))
114         return rvm_true;
115 
116     return rvm_false;
117     }
118 /* list checker -- makes sure elements of list are valid */
chk_list(hdr,silent)119 rvm_bool_t chk_list(hdr,silent)
120     list_entry_t        *hdr;           /* header of list to check */
121     rvm_bool_t          silent;         /* print only errors if true */
122     {
123     list_entry_t        *entry;         /* current list entry */
124     list_entry_t        *prev;          /* previous list entry */
125     long                i = 0;
126     rvm_bool_t          retval = rvm_true;
127 
128     if (hdr == NULL)
129         {
130         printf("  List header is null\n");
131         return rvm_false;
132         }
133     if (ADDR_INVALID(hdr))
134         {
135         printf("  List header address invalid, hdr = %lx\n",(long)hdr);
136         return rvm_false;
137         }
138     if (hdr->is_hdr != rvm_true)
139         {
140         printf("  List header is not valid, is_hdr = %ld\n",
141                (long)hdr->is_hdr);
142         return rvm_false;
143         }
144     if (!(((long)hdr->struct_id > (long)struct_first_id) &&
145            ((long)hdr->struct_id < (long)struct_last_id)))
146         {
147         printf("  List header type is not valid, struct_id = %ld\n",
148                (long)hdr->struct_id);
149         return rvm_false;
150         }
151     if (hdr->list.length < 0)
152         printf("  List length invalid, length = %ld\n",hdr->list.length);
153     if (ADDR_INVALID_OR_NULL(hdr->nextentry))
154         {
155         printf("  List header at %lx has invalid nextentry field, ",(long)hdr);
156 	printf("hdr->nextentry = %lx\n",(long)hdr->nextentry);
157         return rvm_false;
158         }
159     if (ADDR_INVALID_OR_NULL(hdr->preventry))
160         {
161         printf("  List header at %lx has invalid preventry field, ",(long)hdr);
162 	printf("hdr->preventry = %lx\n",(long)hdr->nextentry);
163         return rvm_false;
164         }
165     if ((hdr->nextentry == hdr->preventry) && (hdr->nextentry == hdr))
166         {
167         if (!silent)
168             printf("  List empty\n");
169         if (hdr->list.length != 0)
170             {
171             printf("  List length invalid, length = %ld\n",
172                    hdr->list.length);
173             return rvm_false;
174             }
175         return rvm_true;
176         }
177     if (!silent)
178         printf("  List length = %ld\n",hdr->list.length);
179     /* check ptrs */
180     if (ADDR_INVALID_OR_NULL(hdr->nextentry))
181         {
182         printf("  List header at %lx has invalid nextentry field, ",(long)hdr);
183 	printf("hdr->nextentry = %lx\n",(long)hdr->nextentry);
184         return rvm_false;
185         }
186 
187     /* check all elements of list */
188     prev = hdr;
189     entry = hdr->nextentry;
190     while (entry->is_hdr != rvm_true)
191         {
192         i++;
193         if (hdr->struct_id != entry->struct_id)
194             {
195             printf("  List entry %ld (%lx) has wrong type, struct_id = %ld, ",
196 		   i, (long)entry, (long)entry->struct_id);
197 	    printf("hdr->struct_iud = %ld\n",(long)hdr->struct_id);
198             retval = rvm_false;
199             }
200         if (entry->list.name != hdr)
201             {
202             printf("  List entry %ld (%lx) does not point to header, name = %lx\n",
203                    i,(long)entry,(long)entry->list.name);
204             retval = rvm_false;
205             }
206         if (entry->preventry != prev)
207             {
208             printf("  List entry %ld (%lx)does not have correct preventry,",
209 		   i, (long)entry);
210 	    printf(" preventry = %lx\n",(long)entry->preventry);
211             retval = rvm_false;
212             }
213         if (ADDR_INVALID_OR_NULL(entry->nextentry))
214             {
215             printf("  List entry %ld (%lx) has invalid nextentry field, ",
216 		   i,(long)entry);
217 	    printf("nextentry = %lx\n",(long)entry->nextentry);
218             return rvm_false;
219             }
220         prev = entry;
221         entry = entry->nextentry;
222         }
223     /* check results */
224     if (i != hdr->list.length)
225         {
226         printf("  List length wrong, length = %ld, actual length = %ld\n",
227                hdr->list.length,i);
228         retval = rvm_false;
229         }
230     if (ADDR_INVALID_OR_NULL(hdr->preventry))
231         {
232         printf("  List header at %lx has invalid preventry field, ",(long)hdr);
233 	printf("hdr->preventry = %lx\n",(long)hdr->nextentry);
234         retval = rvm_false;
235         }
236 
237     if ((retval) && (!silent))
238         printf("  List is OK\n");
239 
240     return retval;
241     }
242 /* structure cache free list checker */
chk_free_list(struct_id)243 rvm_bool_t chk_free_list(struct_id)
244     struct_id_t     struct_id;          /* type of free list to check */
245     {
246     if (!(((long)struct_id > (long)struct_first_id) &&
247            ((long)struct_id < (long)struct_last_cache_id)))
248         {
249         printf("This structure is not cached\n");
250         return rvm_false;
251         }
252 
253     return chk_list(&free_lists[ID_INDEX(struct_id)],rvm_true);
254     }
255 
256 /* check all free lists */
chk_all_free_lists()257 void chk_all_free_lists()
258     {
259     long            i;
260 
261     for (i=ID_INDEX(log_id);i < ID_INDEX(struct_last_cache_id); i++)
262         {
263         printf("Checking free list for %s\n",type_names[i]);
264         chk_free_list(INDEX_ID(i));
265         }
266     }
267 /* locate an address in simple list */
search_list(hdr,struct_id,addr)268 rvm_bool_t search_list(hdr,struct_id,addr)
269     list_entry_t    *hdr;               /* header of list to search */
270     struct_id_t     struct_id;          /* type of list to search */
271     rvm_length_t    addr;               /* address to search for */
272     {
273     list_entry_t    *entry;             /* current list entry */
274     long            i = 0;
275     rvm_bool_t      pr_hdr = rvm_true;
276     rvm_bool_t      retval = rvm_false;
277 
278     /* see if in header */
279     if (hdr == NULL)
280         return rvm_false;
281     if ((addr >= (rvm_length_t)hdr)
282         && (addr < ((rvm_length_t)hdr+addr)))
283         {
284         printf("  Address contained in %s list header at %lx\n",
285                NAME(struct_id),(long)hdr);
286         retval = rvm_true;
287         }
288 
289     /* search the list */
290     entry = hdr->nextentry;
291     while (!entry->is_hdr)
292         {
293         i++;
294         if ((addr >= (rvm_length_t)entry)
295         && (addr < ((rvm_length_t)entry+SIZE(struct_id))))
296             {
297             if (pr_hdr)
298                 {
299                 printf("  Address contained in %s list at %lx\n",
300                        NAME(struct_id),(long)hdr);
301                 pr_hdr = rvm_false;
302                 }
303             printf("   in entry %ld at %lx\n",i,(long)entry);
304             retval = rvm_true;
305             }
306         entry = entry->nextentry;
307         }
308     return retval;
309     }
310 /* locate an address in free page list */
in_free_page_list(addr)311 rvm_bool_t in_free_page_list(addr)
312     rvm_length_t    addr;               /* address to search for */
313     {
314     free_page_t     *pg;
315     rvm_bool_t      retval = rvm_false;
316 
317     /* sanity check the list structure */
318     printf("Searching free page list\n");
319     if (!chk_list(&page_list,rvm_true))
320         return rvm_false;
321 
322     /* search the pages */
323     FOR_ENTRIES_OF(page_list,free_page_t,pg)
324         {
325         if ((addr >= (rvm_length_t)pg)
326             && (addr < ((rvm_length_t)pg+pg->len)))
327             {
328             printf("  Address contained in free page entry at %lx\n",
329                    (long)pg);
330             retval = rvm_true;
331             }
332         }
333 
334     return retval;
335     }
336 /* locate an address in free list */
in_free_list(struct_id,addr)337 rvm_bool_t in_free_list(struct_id,addr)
338     struct_id_t     struct_id;          /* type of free list to search */
339     rvm_length_t    addr;               /* address to search for */
340     {
341 
342     /* check basic list structure */
343     if (!chk_list(&free_lists[ID_INDEX(struct_id)],rvm_true))
344         return rvm_false;
345 
346     /* see if addr is in any element of list */
347     return search_list(&free_lists[ID_INDEX(struct_id)],struct_id,addr);
348     }
349 
350 /* locate an address in free lists (searches all) */
in_free_lists(addr)351 rvm_bool_t in_free_lists(addr)
352     rvm_length_t    addr;               /* address to search for */
353     {
354     rvm_bool_t      retval = rvm_false;
355     long            i;
356 
357     for (i=ID_INDEX(log_id);i < ID_INDEX(struct_last_cache_id); i++)
358         {
359         printf("Searching free list %s\n",type_names[i]);
360         if (in_free_list(INDEX_ID(i),addr))
361             retval = rvm_true;
362         }
363 
364     return retval;
365     }
366 /* mem_region_t tree node checks */
chk_mem_node(node)367 rvm_bool_t chk_mem_node(node)
368     mem_region_t    *node;
369     {
370     region_t        *region;
371     seg_t           *seg;
372     rvm_bool_t      retval = rvm_true;
373 
374     /* basic memory region node checks */
375     if (ADDR_INVALID_OR_NULL(node->region))
376         {
377         printf("  Region ptr is invalid, node->object = %lx\n",
378                (long)node->region);
379         return rvm_false;
380         }
381     region = node->region;
382     if (region->links.struct_id != region_id)
383         {
384         printf("  Mem_region node at %lx does not point to",(long)node);
385 	printf(" region descriptor\n");
386         return rvm_false;
387         }
388     if (ADDR_INVALID_OR_NULL(region->mem_region)
389         || ((mem_region_t *)region->mem_region != node))
390         {
391         printf("  Region descriptor at %lx does not point back to",
392 	       (long)region);
393 	printf(" mem_region node at %lx\n",(long)node);
394         return rvm_false;
395         }
396     if (ADDR_INVALID_OR_NULL(region->seg))
397         {
398         printf("  Mem_region node at %lx region descriptor has invalid",
399 	       (long)node);
400 	printf(" segment ptr, ptr = %lx\n",(long)region->seg);
401         return rvm_false;
402         }
403     if (region->seg->links.struct_id != seg_id)
404         {
405         printf("  Mem_region node at %lx region descriptor has invalid",
406 	       (long)node);
407 	printf(" segment descriptor, seg = %lx\n",(long)region->seg);
408         return rvm_false;
409         }
410     /* related structure and list checks */
411     if (!chk_list(&seg_root,rvm_true))
412         return rvm_false;
413     FOR_ENTRIES_OF(seg_root,seg_t,seg)
414         if (seg == region->seg) break;
415     if ((list_entry_t *)seg == &seg_root)
416         {
417         printf("  Mem_region node at %lx region descriptor's segment",
418 	       (long)region);
419 	printf(" descriptor is not on seg_root list, seg = %lx\n",
420                (long)region->seg);
421         retval = rvm_false;
422         }
423 
424     seg = region->seg;
425     if (!chk_list(&seg->map_list,rvm_true))
426         {
427         printf("  Mem_region's region's segment's map_list is damaged,");
428 	printf(" seg = %lx\n",(long)seg);
429         return rvm_false;
430         }
431     FOR_ENTRIES_OF(seg->map_list,region_t,region)
432         if (region == node->region) break;
433     if (region != node->region)
434         {
435         printf("  Mem_region node at %lx region descriptor is",(long)node);
436 	printf(" not on its segment's map_list, region = %lx\n",
437                (long)node->region);
438         return rvm_false;
439         }
440     region = node->region;
441     if (region->links.struct_id != region_id)
442         {
443         printf("  Mem_region node at %lx does not point to",(long)node);
444 	printf(" region descriptor\n");
445         return rvm_false;
446         }
447     if (ADDR_INVALID_OR_NULL(region->mem_region)
448         || ((mem_region_t *)region->mem_region != node))
449         {
450         printf("  Region descriptor at %lx does not point back to",
451 	       (long)region);
452 	printf(" mem_region node at %lx\n",(long)node);
453         return rvm_false;
454         }
455     if (ADDR_INVALID_OR_NULL(region->seg))
456         {
457         printf("  Mem_region node at %lx region descriptor has invalid",
458 	       (long)node);
459 	printf(" segment ptr, ptr = %lx\n",(long)region->seg);
460         return rvm_false;
461         }
462     if (region->seg->links.struct_id != seg_id)
463         {
464         printf("  Mem_region node at %lx region descriptor has invalid",
465 	       (long)node);
466 	printf(" segment descriptor, seg = %lx\n",(long)region->seg);
467         return rvm_false;
468         }
469     /* related structure and list checks */
470     if (!chk_list(&seg_root,rvm_true))
471         return rvm_false;
472     FOR_ENTRIES_OF(seg_root,seg_t,seg)
473         if (seg == region->seg) break;
474     if ((list_entry_t *)seg == &seg_root)
475         {
476         printf("  Mem_region node at %lx region descriptor's segment",
477 	       (long)region);
478 	printf(" descriptor is not on seg_root list, seg = %lx\n",
479                (long)region->seg);
480         retval = rvm_false;
481         }
482 
483     seg = region->seg;
484     if (!chk_list(&seg->map_list,rvm_true))
485         {
486         printf("  Mem_region's region's segment's map_list is damaged,");
487 	printf(" seg = %lx\n",(long)seg);
488         return rvm_false;
489         }
490     FOR_ENTRIES_OF(seg->map_list,region_t,region)
491         if (region == node->region) break;
492     if (region != node->region)
493         {
494         printf("  Mem_region node at %lx region descriptor is",(long)node);
495 	printf(" not on its segment's map_list, region = %lx\n",
496 	       (long)node->region);
497         retval = rvm_false;
498         }
499 
500     if (!chk_list(&seg->unmap_list,rvm_true))
501         {
502         printf("  Mem_region's region's segment's unmap_list is damaged,");
503 	printf(" seg = %lx\n",(long)seg);
504         return rvm_false;
505         }
506     FOR_ENTRIES_OF(seg->unmap_list,region_t,region)
507         if (region == node->region)
508             {
509             printf("  Mem_region node at %lx region descriptor is",
510 		   (long)node);
511 	    printf(" on its segment's unmap_list, region = %lx\n",
512 		   (long)region);
513             retval = rvm_false; break;
514             }
515 
516     return retval;
517     }
518 /* validate dev_region node */
chk_dev_node(dev_region_t * node)519 rvm_bool_t chk_dev_node(dev_region_t *node)
520 {
521     rvm_bool_t      retval = rvm_true;
522     /* check validity of nv buffer ptrs */
523     if (!((node->nv_ptr == NULL) && (node->nv_buf == NULL)))
524         {
525         if (ADDR_INVALID_OR_NULL(node->nv_ptr))
526             {
527             printf("  Dev_region node at %lx has bad nv_ptr\n",(long)node);
528             retval = rvm_false;
529             }
530         if (ADDR_INVALID(node->nv_buf))
531             {
532             printf("  Dev_region node at %lx has bad nv_buf\n",(long)node);
533             retval = rvm_false;
534             }
535         }
536 
537     /* check consistency of nv buffer vs. log offset */
538     if (!((node->nv_ptr != NULL)
539           && RVM_OFFSET_EQL_ZERO(node->log_offset))
540         || ((!RVM_OFFSET_EQL_ZERO(node->log_offset))
541             && (node->nv_ptr == NULL)))
542         {
543         printf("  Dev_region node at %lx has inconsistent nv_ptr",(long)node);
544 	printf(" & log_offset\n");
545         retval = rvm_false;
546         }
547 
548     return retval;
549 }
550 /* check validity of tree node */
chk_node(tree_node_t * node,struct_id_t struct_id)551 rvm_bool_t chk_node(tree_node_t *node, struct_id_t struct_id)
552 {
553     rvm_bool_t      retval = rvm_true;
554 
555     /* basic structure checks */
556     if (node->struct_id != struct_id)
557         {
558         printf("  Node at %lx has wrong struct_id, id = %d, should be %ld\'n",
559                (long)node,node->struct_id,(long)struct_id);
560         retval = rvm_false;
561         }
562     if (node->gtr != NULL)
563         if (ADDR_INVALID(node->gtr) || (node->gtr->struct_id != struct_id))
564             {
565             printf("  Node at %lx gtr ptr invalid\n",(long)node);
566             retval = rvm_false;
567             }
568     if (node->lss != NULL)
569         if (ADDR_INVALID(node->lss) || (node->lss->struct_id != struct_id))
570             {
571             printf("  Node at %lx lss ptr invalid\n",(long)node);
572             retval = rvm_false;
573             }
574 
575     /* type-specific checks */
576     switch (struct_id)
577         {
578       case mem_region_id:
579         retval = chk_mem_node((mem_region_t *)node) && retval;
580         break;
581       case dev_region_id:
582         retval = chk_dev_node((dev_region_t *)node) && retval;
583         break;
584       default:      assert(rvm_false);
585         }
586 
587     return retval;
588 }
589 /* search mem_region tree node */
search_mem_region(addr,node)590 rvm_bool_t search_mem_region(addr,node)
591     rvm_length_t    addr;               /* address to search for */
592     mem_region_t    *node;              /* mem_region node to search */
593     {
594     rvm_bool_t      retval = rvm_false;
595 
596     /* check tree node */
597     if (!chk_node((tree_node_t *)node,mem_region_id))
598         return rvm_false;
599 
600     /* see if address is in node */
601     if ((addr >= (rvm_length_t)node) &&
602         (addr < ((rvm_length_t)node+SIZE(mem_region_id))))
603         {
604         printf("  ***  Address is in mem_region node at %lx\n",(long)node);
605         retval = rvm_true;
606         }
607 
608     /* see if address is in node's vm */
609     if ((addr >= (rvm_length_t)node->vmaddr) &&
610         (addr < ((rvm_length_t)node->vmaddr+node->length)))
611         {
612         printf("  ***  Address is in vm represented by mem_region node at %lx\n"
613                ,(long)node);
614         retval = rvm_true;
615         }
616 
617     /* check lower branches */
618     if (node->links.node.lss != NULL)
619         if (search_mem_region(addr,(mem_region_t *)node->links.node.lss))
620             retval = rvm_true;
621     if (node->links.node.gtr != NULL)
622         if (search_mem_region(addr,(mem_region_t *)node->links.node.gtr))
623             retval = rvm_true;
624 
625     return retval;
626     }
627 
628 /* locate an address in region_tree */
in_region_tree(addr)629 rvm_bool_t in_region_tree(addr)
630     rvm_length_t    addr;               /* address to search for */
631     {
632 
633     printf("Searching mapped region tree\n");
634 
635     return search_mem_region(addr,(mem_region_t *)region_tree);
636     }
637 /* */
search_dev_region(addr,node)638 rvm_bool_t search_dev_region(addr,node)
639     rvm_length_t    addr;               /* address to search for */
640     dev_region_t    *node;              /* segment region node to search */
641     {
642     rvm_bool_t      retval = rvm_false;
643 
644     /* basic node checks */
645     if (!chk_node((tree_node_t *)node,dev_region_id))
646         return rvm_false;
647 
648     /* see if addr is in node */
649     if (IN_STRUCT(addr,node,dev_region_id))
650         {
651         printf("  ***  Address is in dev_region node at %lx\n",
652                (long)node);
653         retval = rvm_true;
654         }
655 
656     /* see if address is in node's nv buffer */
657     if (node->nv_ptr != NULL)
658         if (in_heap(addr,(rvm_length_t)node->nv_buf,
659                     node->nv_buf->alloc_len))
660             {
661             printf("  ***  Address is in dev_region at %lx nv buffer\n",
662 		   (long)node);
663             retval = rvm_true;
664             }
665 
666     /* check lower nodes */
667     if (node->links.node.lss != NULL)
668         if (search_dev_region(addr,(dev_region_t *)node->links.node.lss))
669             retval = rvm_true;
670     if (node->links.node.gtr != NULL)
671         if (search_dev_region(addr,(dev_region_t *)node->links.node.gtr))
672             retval = rvm_true;
673 
674     return retval;
675     }
676 /* search region descriptor */
in_region(addr,region,n)677 rvm_bool_t in_region(addr,region,n)
678     rvm_length_t    addr;               /* address to search for */
679     region_t        *region;            /* region descriptor to search */
680     long            n;
681     {
682     rvm_bool_t      retval = rvm_false;
683 
684     /* see if in region descriptor */
685     printf("    Searching region %ld\n",n);
686     if (IN_STRUCT(addr,region,region_id))
687         {
688         printf("  ***  Address is in region descriptor at %lx\n",
689 	       (long)region);
690         retval = rvm_true;
691         }
692 
693     return retval;
694     }
695 /* search segment descriptor */
in_seg(addr,seg,n)696 rvm_bool_t in_seg(addr,seg,n)
697     rvm_length_t    addr;               /* address to search for */
698     seg_t           *seg;               /* segment descriptor to search */
699     long            n;
700     {
701     region_t        *region,*region2;
702     long            i = 0;
703     rvm_bool_t      retval = rvm_false;
704 
705     /* see if address is in descriptor */
706     printf("  Searching segment %ld\n",n);
707     if (IN_STRUCT(addr,seg,seg_id))
708         {
709         printf("  ***  Address is in segment descriptor at %lx\n",
710 	       (long)seg);
711         retval = rvm_true;
712         }
713 
714     /* see if in device name */
715     if (ADDR_INVALID_OR_NULL(seg->dev.name))
716         printf("  Segment descriptor at %lx has bad dev.name\n",
717 	       (long)seg);
718     else
719         if (in_heap(addr,(rvm_length_t)seg->dev.name,seg->dev.name_len))
720             {
721             printf("  ***  Address is in segment at %lx device name\n",
722 		   (long)seg);
723             retval = rvm_true;
724             }
725 
726     /* validate and scan mapping lists */
727     if (!chk_list(&seg->map_list,rvm_true))
728         {
729         printf("  Segment descriptor at %lx has bad map list\n",
730 	       (long)seg);
731         return retval;
732         }
733     if (!chk_list(&seg->unmap_list,rvm_true))
734         {
735         printf("  Segment descriptor at %lx has bad unmap list\n",
736 	       (long)seg);
737         return retval;
738         }
739     FOR_ENTRIES_OF(seg->map_list,region_t,region)
740         {
741         i++;
742         if (in_region(addr,region,i))
743             {
744             printf("  ***  Address is in region descriptor at %lx\n",
745 		   (long)region);
746             retval = rvm_true;
747             }
748         FOR_ENTRIES_OF(seg->unmap_list,region_t,region2)
749             if (region == region2)
750                 {
751                 printf("  Region descriptor at %lx is on both map and unmap",
752 		       (long)region);
753 		printf(" lists of segment descriptor at %lx\n",
754 		       (long)seg);
755                 break;
756                 }
757         }
758     i = 0;
759     FOR_ENTRIES_OF(seg->unmap_list,region_t,region)
760         {
761         i++;
762         if (in_region(addr,region,i))
763             {
764             printf("  ***  Address is in region descriptor at %lx\n",
765 		   (long)region);
766             retval = rvm_true;
767             }
768         }
769 
770     return retval;
771     }
772 /* search segment list */
in_seg_list(addr)773 rvm_bool_t in_seg_list(addr)
774     rvm_length_t    addr;               /* address to search for */
775     {
776     seg_t           *seg;
777     long            i = 0;
778     rvm_bool_t      retval = rvm_false;
779 
780     /* basic list checks */
781     printf("Searching segment list\n");
782     if (!chk_list(&seg_root,rvm_true))
783         return retval;
784 
785     /* check each segment descriptor */
786     FOR_ENTRIES_OF(seg_root,seg_t,seg)
787         {
788         i++;
789         if (in_seg(addr,seg,i))
790             retval = rvm_true;
791         }
792 
793     return retval;
794     }
795 /* locate an address in change tree */
in_seg_dict(addr,seg_dict,n)796 rvm_bool_t in_seg_dict(addr,seg_dict,n)
797     rvm_length_t    addr;               /* address to search for */
798     seg_dict_t      *seg_dict;          /* segment dictionary entry */
799     long            n;
800     {
801     char            *seg_name;
802     rvm_bool_t      retval = rvm_false;
803 
804     printf("   Searching segment dictionary entry %ld\n",n);
805     if (seg_dict->seg != NULL)
806         seg_name = seg_dict->seg->dev.name;
807     else
808         seg_name = seg_dict->dev.name;
809     if (seg_name == NULL)
810         printf("Searching change tree for UNKNOWN segment at %lx\n",
811                (long)seg_dict);
812     else
813         printf("Searching change tree for %s\n",seg_name);
814 
815     if (seg_dict->seg != NULL)
816         retval = in_seg(addr,seg_dict->seg,0);
817     if (IN_STRUCT(addr,seg_dict,seg_dict_id))
818         {
819         printf("  ***  Address is in seg_dict at %lx\n",(long)seg_dict);
820         retval = rvm_true;
821         }
822     if (seg_dict->dev.name != NULL)
823         if (in_heap(addr,(rvm_length_t)seg_dict->dev.name,seg_dict->dev.name_len))
824             {
825             printf("  ***  Address is in device name of seg_dict at %lx\n",
826                    (long)seg_dict);
827             retval = rvm_true;
828             }
829 
830     if (search_dev_region(addr,(dev_region_t *)seg_dict->mod_tree.root))
831         retval = rvm_true;
832 
833     return retval;
834     }
835 /* search log special function descriptor */
in_log_special(addr,special,n)836 rvm_bool_t in_log_special(addr,special,n)
837     rvm_length_t    addr;               /* address to search for */
838     log_special_t   *special;           /* log special descriptor to search */
839     long            n;
840     {
841     rvm_bool_t      retval = rvm_false;
842 
843     /* see if in descriptor */
844     printf("   Searching special function descriptor %ld\n",n);
845     if (IN_STRUCT(addr,special,log_special_id))
846         {
847         printf("  ***  Address is in log special function decriptor at %lx\n",
848                (long)special);
849         retval = rvm_true;
850         }
851 
852     /* structure specific tests */
853     switch (special->rec_hdr.struct_id)
854         {
855       case log_seg_id:
856         if (in_heap(addr,(rvm_length_t)special->special.log_seg.name,
857                     special->special.log_seg.name_len+1))
858             {
859             printf("  ***  Address is in segment name buffer\n");
860             retval = rvm_true;
861             }
862         break;
863       default:
864         printf("  Record has unknown struct_id\n");
865         }
866 
867     return retval;
868     }
869 /* search modification range descriptor */
in_range(addr,range,n)870 rvm_bool_t in_range(addr,range,n)
871     rvm_length_t    addr;               /* address to search for */
872     range_t         *range;
873     long            n;
874     {
875     rvm_bool_t      retval = rvm_false;
876 
877     /* see if in descriptor */
878     printf("     Searching range %ld\n",n);
879     if (IN_STRUCT(addr,range,range_id))
880         {
881         printf("  ***  Address is in modification range decriptor at %lx\n",
882                (long)range);
883         retval = rvm_true;
884         }
885 
886     /* see if in old value save buffer */
887     if (in_heap(addr,(rvm_length_t)range->data,range->data_len))
888         {
889         printf("  ***  Address is in data buffer of range descriptor");
890 	printf(" at %lx\n",(long)range);
891         retval = rvm_true;
892         }
893     if (range->nvaddr != NULL)
894         if ((addr >= (rvm_length_t)range->nvaddr) &&
895             (addr < ((rvm_length_t)range->nvaddr + range->nv.length)))
896             {
897             printf("  ***  Address is in data buffer of range descriptor");
898 	    printf(" at %lx\n",(long)range);
899             retval = rvm_true;
900             }
901 
902     /* check the region ptr */
903     if (ADDR_INVALID_OR_NULL(range->region))
904         printf("  Range at %lx has bad region ptr\n",(long)range);
905     else
906         if (range->region->links.struct_id != region_id) {
907             printf("  Region at %lx has invalid struct_id,",
908 		   (long)range->region);
909 	    printf(" struct_id = %d\n",range->region->links.struct_id);
910 	}
911 
912     return retval;
913     }
914 /* search transaction descriptor */
in_tid(addr,tid,n)915 rvm_bool_t in_tid(addr,tid,n)
916     rvm_length_t    addr;               /* address to search for */
917     int_tid_t       *tid;               /* transaction descriptor to search */
918     long            n;
919     {
920     range_t         *range;
921     long            i = 0;
922     rvm_bool_t      retval = rvm_false;
923 
924     /* see if in descriptor */
925     printf("   Searching tid %ld\n",n);
926     if (IN_STRUCT(addr,tid,int_tid_id))
927         {
928         printf("    ***  Address is in transaction decriptor at %lx\n",
929                (long)tid);
930         retval = rvm_true;
931         }
932 
933     /* see if in search vector */
934     if (in_heap(addr,(rvm_length_t)tid->x_ranges,
935                 tid->x_ranges_alloc*sizeof(range_t *)))
936         {
937         printf("    ***  Address is in tid.x_ranges at %lx\n",(long)tid);
938         retval = rvm_true;
939         }
940 
941     /* check range list and range descriptors */
942         printf("    Checking modification ranges\n");
943 
944 /* need chk_tree function
945     if (!chk_tree(&tid->range_tree,rvm_true))
946         printf("  Tid at %x has damaged range tree\n",tid);
947     else
948 */
949         FOR_NODES_OF(tid->range_tree,range_t,range)
950             {
951             i++;
952             if (in_range(addr,range,i))
953                 retval = rvm_true;
954             }
955 
956     return retval;
957     }
958 /* search a log descriptor */
in_log(addr,log,n)959 rvm_bool_t in_log(addr,log,n)
960     rvm_length_t    addr;               /* address to search for */
961     log_t           *log;               /* log descriptor to search */
962     long            n;                  /* position in list */
963     {
964     long            i;
965     int_tid_t       *tid;
966     log_special_t   *special;
967     rvm_bool_t      retval = rvm_false;
968 
969     /* see if in descriptor */
970     printf("  Searching log %ld\n",n);
971     if (IN_STRUCT(addr,log,log_id))
972         {
973         printf("  ***  Address is in log descriptor at %lx\n",(long)log);
974         retval = rvm_true;
975         }
976 
977     /* check device name and raw i/o buffer */
978     if (ADDR_INVALID_OR_NULL(log->dev.name))
979         printf("  Log descriptor at %lx has bad dev.name\n",(long)log);
980     else
981         if (in_heap(addr,(rvm_length_t)log->dev.name,log->dev.name_len))
982             {
983             printf("  ***  Address is in log at %lx device name\n",(long)log);
984             retval = rvm_true;
985             }
986     if (log->dev.raw_io)
987         {
988         if (in_heap(addr,(rvm_length_t)log->dev.wrt_buf,log->dev.wrt_buf_len))
989             {
990             printf("  ***  Address is in log at %lx wrt_buf\n",(long)log);
991             retval = rvm_true;
992             }
993         }
994     /* check i/o vector and pad buffer */
995     if (log->dev.iov_length != 0)
996         {
997         if (ADDR_INVALID_OR_NULL(log->dev.iov))
998             printf("  Log descriptor at %lx has bad dev.iov ptr\n",(long)log);
999         else
1000             {
1001             if (in_heap(addr,(rvm_length_t)log->dev.iov,
1002                         log->dev.iov_length * sizeof(struct iovec)))
1003                 {
1004                 printf("  ***  Address is in log at %lx i/o vector\n",
1005 		       (long)log);
1006                 retval = rvm_true;
1007                 }
1008             }
1009         }
1010     if (log->dev.pad_buf_len != 0)
1011         {
1012         if (ADDR_INVALID_OR_NULL(log->dev.pad_buf))
1013             printf("  Log descriptor at %lx has bad dev.pad_buf ptr\n",
1014 		   (long)log);
1015         else
1016             {
1017             if (in_heap(addr,(rvm_length_t)log->dev.pad_buf,
1018                         log->dev.pad_buf_len))
1019                 {
1020                 printf("  ***  Address is in log pad buffer at %lx\n",
1021 		       (long)log);
1022                 retval = rvm_true;
1023                 }
1024             }
1025         }
1026     /* check recovery buffers */
1027     if (ADDR_INVALID_OR_NULL(log->log_buf.buf))
1028         printf("  Log descriptor at %lx has bad log_buf.malloc_buf ptr",
1029                (long)log);
1030     else
1031         {
1032         if (in_heap(addr,(rvm_length_t)log->log_buf.buf,
1033                     log->log_buf.length))
1034             {
1035             printf("  ***  Address is in log recovery buffer at %lx\n",
1036 		   (long)log);
1037             retval = rvm_true;
1038             }
1039         }
1040     if (ADDR_INVALID_OR_NULL(log->log_buf.aux_buf))
1041         printf("  Log descriptor at %lx has bad log_buf.aux_buf ptr",
1042                (long)log);
1043     else
1044         {
1045             if (in_heap(addr,(rvm_length_t)log->log_buf.aux_buf,
1046                         log->log_buf.aux_length))
1047                 {
1048                 printf("  ***  Address is in auxillary buffer log at %lx",
1049 		       (long)log);
1050 		printf(" recovery buffer\n");
1051                 retval = rvm_true;
1052                 }
1053         }
1054     /* check tid and flush lists */
1055     printf("  Checking uncommitted tids\n");
1056     if (!chk_list(&log->tid_list,rvm_true))
1057         printf("  Log at %lx has damaged uncommited tid list\n",(long)log);
1058     else
1059         {
1060         i = 0;
1061         FOR_ENTRIES_OF(log->tid_list,int_tid_t,tid)
1062             {
1063             i++;
1064             if (in_tid(addr,tid,i))
1065                 retval = rvm_true;
1066             }
1067         }
1068     printf("  Checking flush list\n");
1069     if (!chk_list(&log->flush_list,rvm_true))
1070         printf("  Log at %lx has damaged flush list\n",(long)log);
1071     else
1072         {
1073         i = 0;
1074         FOR_ENTRIES_OF(log->flush_list,int_tid_t,tid)
1075             {
1076             i++;
1077             if (in_tid(addr,tid,i))
1078                 retval = rvm_true;
1079             }
1080         }
1081 
1082     /* check immediate stream list */
1083     printf("  Checking special list\n");
1084     if (!chk_list(&log->special_list,rvm_true))
1085         printf("  Log at %lx has damaged special list\n",(long)log);
1086     else
1087         {
1088         i = 0;
1089         FOR_ENTRIES_OF(log->special_list,log_special_t,special)
1090             {
1091             i++;
1092             if (in_log_special(addr,special,i))
1093                 retval = rvm_true;
1094             }
1095         }
1096 
1097     /* check segment dictionary */
1098     if (log->seg_dict_vec != NULL)
1099         {
1100         if (ADDR_INVALID(log->seg_dict_vec))
1101             printf("  Log descriptor at %lx has bad seg_dict_vec ptr\n",
1102                    (long)log);
1103         else
1104             {
1105             printf("  Searching segment dictionary\n");
1106             if (in_heap(addr,(rvm_length_t)log->seg_dict_vec,
1107                         log->seg_dict_len*sizeof(seg_dict_t)))
1108                 {
1109                 printf("  ***  Address is in log at %lx seg_dict_vec\n",
1110 		       (long)log);
1111                 retval = rvm_true;
1112                 }
1113             for (i = 0; i < log->seg_dict_len; i++)
1114                 if (in_seg_dict(addr,&log->seg_dict_vec[i],i+1))
1115                     retval = rvm_true;
1116             }
1117         }
1118 
1119     return retval;
1120     }
1121 /* search log list */
in_log_list(addr)1122 rvm_bool_t in_log_list(addr)
1123     rvm_length_t    addr;               /* address to search for */
1124     {
1125     log_t           *log;
1126     long            i = 0;
1127     rvm_bool_t      retval = rvm_false;
1128 
1129     /* basic list checks */
1130     printf("Searching log list\n");
1131     if (!chk_list(&log_root,rvm_true))
1132         return retval;
1133 
1134     /* check each segment descriptor */
1135     FOR_ENTRIES_OF(log_root,log_t,log)
1136         {
1137         i++;
1138         if (in_log(addr,log,i)) retval = rvm_true;
1139         }
1140 
1141     return retval;
1142     }
1143 /* locate an address in RVM internal structures */
find_addr(addr)1144 void find_addr(addr)
1145     rvm_length_t    addr;               /* address to search for */
1146     {
1147     rvm_bool_t      retval = rvm_false;
1148 
1149     if (in_free_page_list(addr))
1150         retval = rvm_true;
1151     if (in_free_lists(addr))
1152         retval = rvm_true;
1153     if (in_region_tree(addr))
1154         retval = rvm_true;
1155     if (in_seg_list(addr))
1156         retval = rvm_true;
1157     if (in_log_list(addr))
1158         retval = rvm_true;
1159 
1160     if (!retval)
1161         printf("\nAddress not found\n");
1162 
1163     }
1164 /* test if entry is on list -- more forgiving than chk_list */
on_list(hdr,addr)1165 void on_list(hdr,addr)
1166     list_entry_t        *hdr;           /* header of list to search */
1167     list_entry_t        *addr;          /* entry to search for */
1168     {
1169     list_entry_t        *entry;         /* current list entry */
1170     long                i = 0;
1171 
1172     if (hdr == NULL)
1173         {
1174         printf("List header is null\n"); return;
1175         }
1176     if (ADDR_INVALID(hdr))
1177         {
1178         printf("List header address invalid\n"); return;
1179         }
1180     if (hdr->is_hdr != rvm_true)
1181         {
1182         printf("List header invalid\n"); return;
1183         }
1184     if (addr == hdr)
1185         {
1186         printf("Entry is list header\n"); return;
1187         }
1188 
1189     if (addr == NULL)
1190         {
1191         printf("Entry is null\n"); return;
1192         }
1193     if (ADDR_INVALID(addr))
1194         {
1195         printf("Entry address invalid\n"); return;
1196         }
1197     if (addr->is_hdr)
1198         printf("Entry claims to be a list header\n");
1199 
1200     if (!(((long)hdr->struct_id > (long)struct_first_id) &&
1201            ((long)hdr->struct_id < (long)struct_last_id)))
1202         printf("  List header type is not valid, struct_id = %ld\n",
1203                (long)hdr->struct_id);
1204     if (!(((long)addr->struct_id > (long)struct_first_id) &&
1205            ((long)addr->struct_id < (long)struct_last_id)))
1206         printf("  Entry type is not valid, struct_id = %ld\n",
1207                (long)addr->struct_id);
1208     if (hdr->struct_id != addr->struct_id) {
1209         printf("Entry is not of same type as list -- \n");
1210 	printf("  Entry->struct_id  = %ld\n",(long)addr->struct_id);
1211 	printf("  Header->struct_id = %ld\n",(long)hdr->struct_id);
1212     }
1213     if (addr->list.name != hdr)
1214         printf("Entry claims to be on list %lx\n",(long)addr->list.name);
1215 
1216     if (ADDR_INVALID_OR_NULL(hdr->nextentry))
1217         {
1218         printf("  List header has invalid nextentry field, ");
1219 	printf("hdr->nextentry = %lx\n",(long)hdr->nextentry);
1220         return;
1221         }
1222     if (ADDR_INVALID_OR_NULL(hdr->preventry)) {
1223         printf("  List header has invalid preventry field, ");
1224 	printf("hdr->preventry = %lx\n",(long)hdr->nextentry);
1225     }
1226 
1227     /* check all elements of list */
1228     entry = hdr->nextentry;
1229     while (entry->is_hdr != rvm_true)
1230         {
1231         i++;
1232         if (entry == addr)
1233             {
1234             printf("Entry is number %ld of list\n",i);
1235             return;
1236             }
1237         if (ADDR_INVALID_OR_NULL(entry->nextentry))
1238             {
1239             printf("Entry %ld has invalid nextentry field, ",i);
1240 	    printf("nextentry = %lx\n",(long)entry->nextentry);
1241             return;
1242             }
1243         entry = entry->nextentry;
1244         }
1245 
1246     printf("Entry not on list\n");
1247     }
1248 #endif /* DEBUG_GDB */
1249