Stackdb
Stackdb is a stackable, multi-target and -level source debugger and memory forensics library.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
clfit.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, 2013, 2014 The University of Utah
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of
7  * the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <limits.h>
22 #include "common.h"
23 #include "log.h"
24 #include "clfit.h"
25 #include "alist.h"
26 
28  return (Pvoid_t) NULL;
29 }
30 
32  while (crd->containing_range)
33  crd = crd->containing_range;
34 
35  return crd;
36 }
37 
38 struct clf_range_data *crd_get_loosest(struct array_list *crdlist,
39  Word_t start,Word_t end,
40  int *contains_saveptr) {
41  int i;
42  Word_t loosest_len = 0;
43  struct clf_range_data *crd;
44  struct clf_range_data *best_crd = NULL;
45 
46  if (end < start)
47  return NULL;
48 
49  if (contains_saveptr)
50  *contains_saveptr = 0;
51 
52  for (i = 0; i < array_list_len(crdlist); ++i) {
53  crd = (struct clf_range_data *)array_list_item(crdlist,i);
54  if ((CLRANGE_END(crd) - CLRANGE_START(crd)) > loosest_len) {
55  loosest_len = CLRANGE_END(crd) - CLRANGE_START(crd);
56  best_crd = crd;
57  if (contains_saveptr
58  && CLRANGE_START(crd) <= start && CLRANGE_END(crd) >= end)
59  *contains_saveptr = 1;
60  }
61  }
62 
63  return best_crd;
64 }
65 
66 struct clf_range_data *crd_get_tightest(struct array_list *crdlist,
67  Word_t start,Word_t end,
68  int *contains_saveptr) {
69  int i;
70  Word_t tightest_len = ULONG_MAX;
71  Word_t tightest_containing_len = ULONG_MAX;
72  struct clf_range_data *crd;
73  struct clf_range_data *best_crd = NULL;
74  struct clf_range_data *best_containing_crd = NULL;
75 
76  if (contains_saveptr)
77  *contains_saveptr = 0;
78 
79  if (end < start)
80  return NULL;
81 
82  for (i = 0; i < array_list_len(crdlist); ++i) {
83  crd = (struct clf_range_data *)array_list_item(crdlist,i);
84  if ((CLRANGE_END(crd) - CLRANGE_START(crd)) < tightest_len) {
85  tightest_len = CLRANGE_END(crd) - CLRANGE_START(crd);
86  best_crd = crd;
87  if (CLRANGE_START(crd) <= start && CLRANGE_END(crd) > end
88  && (CLRANGE_END(crd) - CLRANGE_START(crd))
89  < tightest_containing_len) {
90  if (contains_saveptr)
91  *contains_saveptr = 1;
92  best_containing_crd = crd;
93  tightest_containing_len = CLRANGE_END(crd) - CLRANGE_START(crd);
94  }
95  }
96  }
97 
98  if (best_containing_crd)
99  return best_containing_crd;
100  else
101  return best_crd;
102 }
103 
104 int clrange_add(clrange_t *clf,Word_t start,Word_t end,void *data) {
105  struct clf_range_data *crd = NULL;
106  PWord_t pv = NULL;
107  struct array_list *alist;
108  struct array_list *tmpalist;
109  int created = 0;
110  struct clf_range_data *ccrd;
111  int contains = 0;
112  Word_t idx;
113 
114  if (end < start) {
115  verror("end 0x%lx < start 0x%lx; not adding!\n",end,start);
116  goto errout;
117  }
118 
119  crd = (struct clf_range_data *)malloc(sizeof(*crd));
120 
121  crd->start = start;
122  crd->end = end;
123  crd->data = data;
124  crd->containing_range = NULL;
125 
126  idx = start;
127  if (*clf)
128  JLG(pv,*clf,idx);
129  if (!pv) {
130  vdebug(10,LA_LIB,LF_CLRANGE,"inserting new alist for 0x%lx,0x%lx\n",start,end);
131  alist = array_list_create(1);
132  created = 1;
133  JLI(pv,*clf,start);
134  if (pv == PJERR) {
135  goto errout;
136  }
137  *pv = (Word_t)alist;
138 
139  /* Now we need to find the containing parent. Basically...
140  *
141  * 1) If the previous range (previous, inclusive, of index - 1)
142  * does not contain our range, we have two cases:
143  * a) if that previous range is contained, we keep searching up that
144  * hierarchy until there is no more containing ranges to
145  * find one that contains our range; OR
146  * b) if that previous range is not contained, our range also
147  * has no container.
148  * OR
149  * 2) If the previous range (previous, inclusive, of index - 1)
150  * DOES contain our range, our range's container is that
151  * previous range.
152  *
153  * AND, for these, we want the *tightest* containing parent.
154  */
155  pv = NULL;
156  idx = start;
157  JLP(pv,*clf,idx);
158  if (pv && pv != PJERR) {
159  /* Find the widest containing range in this list. */
160  tmpalist = (struct array_list *)*pv;
161  ccrd = crd_get_tightest(tmpalist,start,end,&contains);
162 
163  if (!ccrd) {
164  verror("no crd containing range(0x%lx,0x%lx)!\n",start,end);
165  goto errout;
166  }
167 
168  /* Case 1a) above: */
169  if (!contains && ccrd->containing_range) {
170  while (ccrd->containing_range) {
171  if (start >= CLRANGE_START(ccrd->containing_range)
172  && end <= CLRANGE_END(ccrd->containing_range)) {
173  crd->containing_range = ccrd->containing_range;
174  break;
175  }
176  ccrd = ccrd->containing_range;
177  }
178  }
179  /* Case 1b) above: */
180  else if (!contains && !ccrd->containing_range)
181  crd->containing_range = NULL;
182  /* Case 2) above: */
183  else if (contains)
184  crd->containing_range = ccrd;
185 
186  if (crd->containing_range)
188  "containing range for (0x%lx,0x%lx) is (0x%lx,0x%lx)\n",
189  start,end,crd->containing_range->start,
190  crd->containing_range->end);
191  else
193  "no containing range for (0x%lx,0x%lx) (%d)!\n",
194  start,end,contains);
195  }
196  }
197  else if (pv == PJERR)
198  goto errout;
199  else {
200  /* Since we make the non-overlapping assumption, the container
201  * of this new range is the same as the container of the "peer"
202  * ranges on the alist.
203  */
204  alist = (struct array_list *)*pv;
205  crd->containing_range = ((struct clf_range_data *) \
206  array_list_item(alist,0))->containing_range;
207  }
208 
209  array_list_append(alist,crd);
210 
211  return 0;
212 
213  errout:
214  if (created)
215  array_list_free(alist);
216  if (crd)
217  free(crd);
218  return -1;
219 }
220 
221 int clrange_update_end(clrange_t *clf,Word_t start,Word_t end,void *data) {
222  struct clf_range_data *crd;
223  struct clf_range_data *ccrd;
224  struct clf_range_data *tmpcrd;
225  PWord_t pv;
226  struct array_list *alist;
227  int i;
228  Word_t idx;
229  int found;
230 
231  /* We look for an exact match, and update the end value if there is
232  * an exact match for this start addr and data.
233  */
234  JLG(pv,*clf,start);
235  if (!pv)
236  return -1;
237 
238  alist = (struct array_list *)*pv;
239  crd = NULL;
240  for (i = 0; i < array_list_len(alist); ++i) {
241  crd = (struct clf_range_data *)array_list_item(alist,i);
242  if (CLRANGE_END(crd) != end && CLRANGE_DATA(crd) == data) {
244  "updated alist %p crd %p start %lx end %lx (old end %lx)"
245  " i %d data %p\n",alist,crd,start,end,CLRANGE_END(crd),i,data);
246  CLRANGE_END(crd) = end;
247  break;
248  }
249  }
250 
251  /* Now, technically, we have to update the containing_range
252  * hierarchy as well, since we might have swallowed more ranges
253  * downstream from us.
254  *
255  * What we do is keep finding next indexes from our old end
256  * (inclusive) to our new end (exclusive); if they are contained in
257  * us: 1) if they have a container, and we are not already in that
258  * hierarchy, we become their new container; 2) if the don't have a
259  * container, we become their new container.
260  *
261  * XXX: case 1 relies on the assumption that the widest ranges at
262  * any start index come first in the array_list at that index! Fix
263  * this here and elsewhere.
264  */
265  /* Also, since ranges can't overlap, we can't "outgrow" our
266  * container.
267  */
268 
269  idx = end;
270  while (1) {
271  pv = NULL;
272  JLN(pv,*clf,idx);
273  if (!pv || pv == PJERR)
274  break;
275  alist = (struct array_list *)*pv;
276  tmpcrd = NULL;
277  for (i = 0; i < array_list_len(alist); ++i) {
278  tmpcrd = (struct clf_range_data *)array_list_item(alist,i);
279  /* This will break us out for good; see bottom of while loop. */
280  if (CLRANGE_START(tmpcrd) >= end)
281  goto while_done;
282 
283  /* If they are contained in us... */
284  if (start <= CLRANGE_START(tmpcrd) && CLRANGE_END(tmpcrd) <= end) {
285  /* Case 1) above: */
286  if (tmpcrd->containing_range) {
287  found = 0;
288  ccrd = tmpcrd;
289  while (ccrd->containing_range) {
290  if (ccrd->containing_range == crd) {
291  found = 1;
292  break;
293  }
294  ccrd = ccrd->containing_range;
295  }
296  if (!found)
297  tmpcrd = crd;
298  }
299  /* Case 2) above: */
300  else
301  tmpcrd->containing_range = crd;
302  }
303  }
304 
305  while_done:
306  ;
307  }
308 
309  return 0;
310 }
311 
312 void *clrange_find(clrange_t *clf,Word_t index) {
313  PWord_t pv;
314  struct array_list *alist;
315  Word_t idx = index;
316  int i;
317  Word_t lrlen = ~(Word_t)0;
318  struct clf_range_data *retval = NULL;
319 
320  if (!clf || !*clf)
321  return NULL;
322 
323  vdebug(10,LA_LIB,LF_CLRANGE,"starting looking for 0x%lx\n",idx);
324 
325  /*
326  * We look for the previous index (including @index itself). Each
327  * index will have an array_list associated with it; we scan through
328  * the whole array list looking for the tightest range containing
329  * @index. If we find such a range, return the *data associated
330  * with it. If we don't find a range in the array list, find the
331  * previous index of the previous index we found first, and repeat
332  * the range search for that array list. Keep going until we find a
333  * match...
334  */
335  while (1) {
336  vdebug(10,LA_LIB,LF_CLRANGE,"looking for 0x%lx\n",idx);
337  JLL(pv,*clf,idx);
338  if (pv == NULL)
339  return NULL;
340  vdebug(10,LA_LIB,LF_CLRANGE,"found 0x%lx\n",idx);
341  alist = (struct array_list *)*pv;
342 
343  for (i = array_list_len(alist) - 1; i > -1; --i) {
344  struct clf_range_data *crd = (struct clf_range_data *) \
345  array_list_item(alist,i);
346  if (index < CLRANGE_END(crd) && (CLRANGE_END(crd) - CLRANGE_START(crd)) < lrlen) {
347  retval = crd;
348  lrlen = CLRANGE_END(crd) - CLRANGE_START(crd);
349  }
350  }
351 
352  if (retval) {
353  /* We found a tightest bound containing @index; return! */
354  vdebug(10,LA_LIB,LF_CLRANGE,"found 0x%lx at %d\n",idx,i);
355  return CLRANGE_DATA(retval);
356  }
357  else {
358  /* If the index was zero, we can't find any previous
359  * matches, so we're done!
360  */
361  if (idx == 0) {
362  vdebug(10,LA_LIB,LF_CLRANGE,"did not find 0x%lx range fit!\n",idx,i);
363  return NULL;
364  }
365  }
366 
367  /* If we did not find a tightest bound containing @index, try
368  * the previous index to the current previous index.
369  */
370  idx -= 1;
371  }
372 }
373 
374 /*
375  * Find the range that is the widest range containing index.
376  */
378  struct array_list **al_saveptr) {
379  PWord_t pv;
380  struct array_list *alist;
381  struct clf_range_data *crd;
382  int contains = 0;
383  Word_t idx;
384 
385  if (!clf || !*clf)
386  return NULL;
387 
388  /* Find the index that is previous to index; if that range contains
389  * us and has a containing range, follow its containing_range chain
390  * on up; otherwise return that range.
391  */
392  idx = index;
393  JLL(pv,*clf,idx);
394  if (pv == NULL || pv == PJERR)
395  return NULL;
396 
397  vdebug(10,LA_LIB,LF_CLRANGE,"found 0x%lx previous to 0x%lx\n",idx,index);
398  alist = (struct array_list *)*pv;
399  crd = crd_get_tightest(alist,index,index,&contains);
400  if (crd) {
401  vdebug(10,LA_LIB,LF_CLRANGE,"found crd (0x%lx,0x%lx) (contains is %d)\n",
402  CLRANGE_START(crd),CLRANGE_END(crd),contains);
403  }
404  else {
405  verror("did not find a tightest range for 0x%lx even though we should have!\n",index);
406  return NULL;
407  }
408  if (contains && crd->containing_range) {
409  crd = crd_top_containing_range(crd);
410  vdebug(10,LA_LIB,LF_CLRANGE,"found top containing crd (0x%lx,0x%lx)\n",
411  CLRANGE_START(crd),CLRANGE_END(crd));
412  }
413 
414  if (al_saveptr)
415  *al_saveptr = alist;
416 
417  return crd;
418 }
419 
421  struct array_list **al_saveptr) {
422  struct array_list *alist;
423  Word_t idx;
424  struct array_list *prev_alist = NULL;
425  struct clf_range_data *prev_crd = NULL;
426  struct clf_range_data *crd;
427  int contains;
428 
429  if (!clf || !*clf)
430  return NULL;
431 
432  /*
433  * Find the loosest range that contains index. If there isn't one,
434  * just try to find the next range beyond index.
435  */
436  prev_crd = clrange_find_loosest(clf,index,&prev_alist);
437  if (!prev_crd)
438  idx = index + 1;
439  else
440  idx = CLRANGE_END(prev_crd);
441 
442  /*
443  * Find the next index, find the loosest range at that index, and
444  * return.
445  */
446  alist = clrange_find_next_inc(clf,idx);
447  if (!alist)
448  return NULL;
449 
450  crd = crd_get_loosest(alist,index,index,&contains);
451 
452  return crd;
453 }
454 
455 struct array_list *clrange_find_prev_inc(clrange_t *clf,Word_t index) {
456  PWord_t pv;
457 
458  if (!clf || !*clf)
459  return NULL;
460 
461  JLL(pv,*clf,index);
462  if (pv == NULL)
463  return NULL;
464 
465  return (struct array_list *)*pv;
466 }
467 
468 struct array_list *clrange_find_prev_exc(clrange_t *clf,Word_t index) {
469  PWord_t pv;
470 
471  if (!clf || !*clf)
472  return NULL;
473 
474  JLP(pv,*clf,index);
475  if (pv == NULL)
476  return NULL;
477 
478  return (struct array_list *)*pv;
479 }
480 
481 struct array_list *clrange_find_next_inc(clrange_t *clf,Word_t index) {
482  PWord_t pv;
483 
484  if (!clf || !*clf)
485  return NULL;
486 
487  JLF(pv,*clf,index);
488  if (pv == NULL)
489  return NULL;
490 
491  return (struct array_list *)*pv;
492 }
493 
494 struct array_list *clrange_find_next_exc(clrange_t *clf,Word_t index) {
495  PWord_t pv;
496 
497  if (!clf || !*clf)
498  return NULL;
499 
500  JLN(pv,*clf,index);
501  if (pv == NULL)
502  return NULL;
503 
504  return (struct array_list *)*pv;
505 }
506 
508  Word_t index,
509  unsigned int len) {
510  struct array_list *retval = NULL;
511  struct array_list *alist;
512  Word_t idx_end = index + len;
513  /* Start our search here, exclusive. */
514  Word_t idx = idx_end;
515  int i;
516  struct clf_range_data *crd;
517 
518  if (!clf || !*clf)
519  return NULL;
520 
521  retval = array_list_create(1);
522 
523  /*
524  * We look for the previous index prior to (@index + @len),
525  * exclusive; and keep repeating this until we find an index less
526  * than @index. For each range we find, if it is entirely inside
527  * the given range, we include it in our results.
528  */
529  while ((alist = (struct array_list *)clrange_find_prev_exc(clf,idx))) {
530  /* We do this loop backward so that we theoretically produce an
531  * exactly reverse-sorted list of struct clrnage_data * items --
532  * reverse of the way they are in the judy array.
533  */
534  crd = NULL;
535  for (i = array_list_len(alist) - 1; i >= 0; --i) {
536  crd = (struct clf_range_data *)array_list_item(alist,i);
537  if (CLRANGE_START(crd) <= index && CLRANGE_END(crd) <= idx_end)
538  array_list_append(retval,crd);
539  }
540  if (!crd) {
541  /* Bad! List was not-NULL but empty? Corruption somewhere
542  * is likely!
543  */
544  verror("CRD array list empty, but not NULL!\n");
545  goto errout;
546  }
547  /* Update the search idx. */
548  idx = CLRANGE_START(crd);
549  /* If the new idx is the start of the target range, or is prior
550  * to it, we're done.
551  *
552  * XXX: and yes, this means that the loop above is wasted for
553  * this list of CRDs.
554  */
555  if (idx <= index)
556  goto out;
557  }
558 
559  out:
560  /* If we didn't find anything, dealloc and leave. */
561  if (array_list_len(retval) == 0) {
562  array_list_free(retval);
563  retval = NULL;
564  }
565  return retval;
566 
567  errout:
568  array_list_free(retval);
569  return NULL;
570 }
571 
573  PWord_t pv;
574  int rci;
575  Word_t index;
576  int bytes_freed;
577 
578  if (!clf)
579  return;
580 
581  /* This stinks -- we have to free each element one by one. */
582  while (1) {
583  index = 0;
584  JLF(pv,clf,index);
585  if (pv == NULL)
586  break;
587  array_list_deep_free((struct array_list *)*pv);
588  *pv = (Word_t)NULL;
589  JLD(rci,clf,index);
590  }
591 
592  /*
593  * Man page says bytes_freed should be Word_t (unsigned), but
594  * compiler disagrees!
595  */
596  JLFA(bytes_freed,clf);
597 }
598 
599 void clrange_dump(clrange_t *clf,struct dump_info *ud,
600  clrange_dumper_t dumper) {
601  PWord_t pv;
602  Word_t index,nextindex;
603  struct clf_range_data *crd,*ccrd;
604  int i;
605 
606  if (!clf)
607  return;
608 
609  /*
610  * Scan each element one by one.
611  */
612  index = 0;
613  while (1) {
614  JLF(pv,clf,index);
615  if (pv == NULL)
616  break;
617  i = 0;
618  nextindex = index;
619  array_list_foreach(((struct array_list *)*pv),i,crd) {
620  if (i == 0) {
621  if (CLRANGE_END(crd) <= index)
622  nextindex = index + 1;
623  else
624  nextindex = CLRANGE_END(crd);
625  }
626  else if (CLRANGE_END(crd) < nextindex && CLRANGE_END(crd) > index)
627  nextindex = CLRANGE_END(crd);
628 
629  fprintf(ud->stream,"%s",ud->prefix);
630  ccrd = crd->containing_range;
631  while (ccrd) {
632  fputs(" ",ud->stream);
633  ccrd = ccrd->containing_range;
634  }
635  fprintf(ud->stream,"0x%"PRIxADDR",0x%"PRIxADDR": ",
636  CLRANGE_START(crd),CLRANGE_END(crd));
637  if (dumper)
638  dumper(CLRANGE_START(crd),CLRANGE_END(crd),ud,CLRANGE_DATA(crd));
639  fputs("\n",ud->stream);
640  }
641 
642  index = nextindex;
643  }
644 
645  return;
646 }
647 
649  return (Pvoid_t)NULL;
650 }
651 
652 int clrangesimple_add(clrangesimple_t *clr,Word_t start,Word_t end,void *data) {
653  struct clf_rangesimple_data *crd = NULL;
654  PWord_t pv = NULL;
655  Word_t idx;
656 
657  if (end < start) {
658  verror("end 0x%lx < start 0x%lx; not adding!\n",end,start);
659  return -1;
660  }
661 
662  /*
663  * We don't allow overlaps nor nesting, so make sure the requested
664  * start/end range is empty.
665  */
666  idx = start;
667  JLF(pv,*clr,idx);
668  if (pv == PJERR)
669  return -1;
670  else if (pv) {
671  crd = (struct clf_rangesimple_data *)*pv;
672  if (start == crd->start
673  || (start >= crd->start && start < crd->end)
674  || (end > crd->start && end <= crd->end))
675  return 1;
676  crd = NULL;
677  }
678  pv = NULL;
679  idx = start;
680  JLP(pv,*clr,idx);
681  if (pv == PJERR)
682  return -1;
683  else if (pv) {
684  crd = (struct clf_rangesimple_data *)*pv;
685  if (start == crd->start)
686  return 1;
687  if (start >= crd->start && start < crd->end)
688  return 1;
689  if (end > crd->start && end <= crd->end)
690  return 1;
691  crd = NULL;
692  }
693  pv = NULL;
694 
695  /* Ok, insert it! */
696  crd = (struct clf_rangesimple_data *)malloc(sizeof(*crd));
697 
698  crd->start = start;
699  crd->end = end;
700  crd->data = data;
701 
702  vdebug(10,LA_LIB,LF_CLRANGE,"inserting new crd for 0x%lx,0x%lx\n",start,end);
703  JLI(pv,*clr,start);
704  if (pv == PJERR) {
705  free(crd);
706  return -1;
707  }
708  *pv = (Word_t)crd;
709 
710  return 0;
711 }
712 
713 int clrangesimple_find(clrangesimple_t *clr,Word_t index,
714  Word_t *start,Word_t *end,void **data) {
715  struct clf_rangesimple_data *crd = NULL;
716  PWord_t pv = NULL;
717  Word_t idx;
718 
719  idx = index;
720  JLL(pv,*clr,idx);
721  if (pv == PJERR)
722  return -1;
723  else if (!pv)
724  return 1;
725  else {
726  crd = (struct clf_rangesimple_data *)*pv;
727  if (index < crd->start || index >= crd->end)
728  return 1;
729  if (start)
730  *start = crd->start;
731  if (end)
732  *end = crd->end;
733  if (data)
734  *data = crd->data;
735  return 0;
736  }
737 }
738 
739 int clrangesimple_remove(clrangesimple_t *clr,Word_t index,
740  Word_t *end,void **data) {
741  struct clf_rangesimple_data *crd = NULL;
742  PWord_t pv = NULL;
743  int rc;
744  Word_t idx;
745 
746  idx = index;
747  JLF(pv,*clr,idx);
748  if (pv == PJERR)
749  return -1;
750  else if (pv) {
751  crd = (struct clf_rangesimple_data *)*pv;
752 
753  /* NB: only remove direct hits! */
754  if (index == crd->start) {
755  idx = index;
756  JLD(rc,*clr,idx);
757  if (rc == JERR)
758  return -1;
759  else if (rc == 0)
760  return 1;
761  /* Ok, both JLF and JLD agree it was there! */
762  if (end)
763  *end = crd->end;
764  if (data)
765  *data = crd->data;
766  //crd->start = 0;
767  //crd->end = 0;
768  //crd->data = NULL;
769  free(crd);
770  return 0;
771  }
772  else
773  return 1;
774  }
775  else
776  return 1;
777 }
778 
780  clrangesimple_foreach_handler handler,void *hpriv) {
781  Word_t idx = -1;
782  PWord_t pv = NULL;
783  struct clf_rangesimple_data *crd;
784 
785  while (1) {
786  pv = NULL;
787  idx += 1;
788  JLF(pv,clr,idx);
789  if (pv == PJERR)
790  return -1;
791  else if (pv == NULL)
792  return 0;
793  else {
794  crd = (struct clf_rangesimple_data *)*pv;
795 
796  if (handler)
797  handler(crd->start,crd->end,crd->data,hpriv);
798  }
799  }
800 
801  return 0;
802 }
803 
805  void *dtor_data) {
806  struct clf_rangesimple_data *crd = NULL;
807  PWord_t pv;
808  int rci;
809  Word_t index;
810  int bytes_freed;
811 
812  if (!clr)
813  return;
814 
815  /* This stinks -- we have to free each element one by one. */
816  while (1) {
817  index = 0;
818  JLF(pv,clr,index);
819  if (pv == NULL)
820  break;
821  crd = (struct clf_rangesimple_data *)*pv;
822  if (dtor)
823  dtor(crd->start,crd->end,crd->data,dtor_data);
824  free(crd);
825  *pv = (Word_t)NULL;
826  JLD(rci,clr,index);
827  }
828 
829  /*
830  * Man page says bytes_freed should be Word_t (unsigned), but
831  * compiler disagrees!
832  */
833  JLFA(bytes_freed,clr);
834 }
835 
837  return (Pvoid_t) NULL;
838 }
839 
840 /*
841  * This function associates @data with some integer @index. Later, when
842  * you call clfit_find_closest(), you can find the closest index match
843  * to these values. You can associate multiple pieces of data with each
844  * index. If you
845  */
846 int clmatch_add(clmatch_t *clf,Word_t index,void *data) {
847  PWord_t pv = NULL;
848  struct array_list *alist;
849  int created = 0;
850 
851  if (*clf)
852  JLG(pv,*clf,index);
853  if (!pv) {
854  alist = array_list_create(1);
855  created = 1;
856  JLI(pv,*clf,index);
857  if (pv == PJERR) {
858  goto errout;
859  }
860  *pv = (Word_t)alist;
861  }
862  else if (pv == PJERR)
863  goto errout;
864  else
865  alist = (struct array_list *)*pv;
866 
867  array_list_append(alist,data);
868 
869  return 0;
870 
871  errout:
872  if (created)
873  array_list_free(alist);
874  return -1;
875 }
876 
877 /*
878  * This function finds an array_list at the closest previous match. We
879  * return an array_list because there might be multiple things at that
880  * index.
881  */
882 struct array_list *clmatch_find(clmatch_t *clf,Word_t index) {
883  PWord_t pv;
884 
885  if (!clf || !*clf)
886  return NULL;
887 
888  /*
889  * We look for the previous index (including @index itself).
890  */
891  JLL(pv,*clf,index);
892  if (pv == NULL)
893  return NULL;
894  return (struct array_list *)*pv;
895 }
896 
898  PWord_t pv;
899  int rci;
900  Word_t index;
901  int bytes_freed;
902 
903  if (!clf)
904  return;
905 
906  /* This stinks -- we have to free each element one by one. */
907  while (1) {
908  index = 0;
909  JLF(pv,clf,index);
910  if (pv == NULL)
911  break;
912  array_list_free((struct array_list *)*pv);
913  *pv = (Word_t)NULL;
914  JLD(rci,clf,index);
915  }
916 
917  /*
918  * Man page says bytes_freed should be Word_t (unsigned), but
919  * compiler disagrees!
920  */
921  JLFA(bytes_freed,clf);
922 }
923 
925  return (Pvoid_t) NULL;
926 }
927 
928 /*
929  * This function associates @data with some integer @index. Later, when
930  * you call clfit_find_closest(), you can find the closest index match
931  * to these values. You can associate multiple pieces of data with each
932  * index. If you
933  */
934 int clmatchone_add(clmatchone_t *clf,Word_t index,void *data) {
935  PWord_t pv = NULL;
936 
937  if (*clf)
938  JLG(pv,*clf,index);
939  if (!pv) {
940  JLI(pv,*clf,index);
941  if (pv == PJERR) {
942  return -1;
943  }
944  *pv = (Word_t)data;
945  return 0;
946  }
947  else if (pv == PJERR)
948  return -1;
949  else
950  return -1;
951 }
952 
953 int clmatchone_update(clmatchone_t *clf,Word_t index,void *data) {
954  PWord_t pv = NULL;
955 
956  if (*clf)
957  JLG(pv,*clf,index);
958  if (!pv) {
959  JLI(pv,*clf,index);
960  if (pv == PJERR) {
961  return -1;
962  }
963  *pv = (Word_t)data;
964  return 0;
965  }
966  else if (pv == PJERR)
967  return -1;
968  else {
969  *pv = (Word_t)data;
970  return 0;
971  }
972 }
973 
974 /*
975  * This function finds an array_list at the closest previous match.
976  */
977 void *clmatchone_find(clmatchone_t *clf,Word_t index,Word_t *o_index) {
978  PWord_t pv;
979 
980  if (!clf || !*clf)
981  return NULL;
982 
983  /*
984  * We look for the previous index (including @index itself).
985  */
986  JLL(pv,*clf,index);
987  if (pv == NULL)
988  return NULL;
989  if (o_index)
990  *o_index = index;
991  return (void *)*pv;
992 }
993 
995  int bytes_freed;
996 
997  if (!clf)
998  return;
999 
1000  /*
1001  * Man page says bytes_freed should be Word_t (unsigned), but
1002  * compiler disagrees!
1003  */
1004  JLFA(bytes_freed,clf);
1005 }
Word_t start
Definition: clfit.h:37
int clmatch_add(clmatch_t *clf, Word_t index, void *data)
Definition: clfit.c:846
int clmatchone_add(clmatchone_t *clf, Word_t index, void *data)
Definition: clfit.c:934
struct clf_range_data * crd_get_loosest(struct array_list *crdlist, Word_t start, Word_t end, int *contains_saveptr)
Definition: clfit.c:38
Word_t end
Definition: clfit.h:38
static uint64_t unsigned int i
void clmatch_free(clmatch_t clf)
Definition: clfit.c:897
clrange_t clrange_create()
Definition: clfit.c:27
clmatchone_t clmatchone_create()
Definition: clfit.c:924
clrangesimple_t clrangesimple_create(void)
Definition: clfit.c:648
Pvoid_t clrange_t
Definition: clfit.h:34
struct array_list * clrange_find_prev_inc(clrange_t *clf, Word_t index)
Definition: clfit.c:455
#define verror(format,...)
Definition: log.h:30
struct clf_range_data * crd_top_containing_range(struct clf_range_data *crd)
Definition: clfit.c:31
void free(void *ptr)
Definition: debugserver.c:207
int clrangesimple_add(clrangesimple_t *clr, Word_t start, Word_t end, void *data)
Definition: clfit.c:652
void clrange_free(clmatch_t clf)
Definition: clfit.c:572
char * prefix
Definition: output.h:25
#define array_list_foreach(alist, lpc, placeholder)
Definition: alist.h:371
void clrangesimple_free(clrangesimple_t clr, clrangesimple_free_dtor dtor, void *dtor_data)
Definition: clfit.c:804
int clrange_update_end(clrange_t *clf, Word_t start, Word_t end, void *data)
Definition: clfit.c:221
struct clf_range_data * clrange_find_loosest(clrange_t *clf, Word_t index, struct array_list **al_saveptr)
Definition: clfit.c:377
Definition: log.h:68
#define CLRANGE_DATA(crd)
Definition: clfit.h:45
void clrange_dump(clrange_t *clf, struct dump_info *ud, clrange_dumper_t dumper)
Definition: clfit.c:599
Pvoid_t clmatch_t
Definition: clfit.h:129
Pvoid_t clrangesimple_t
Definition: clfit.h:95
struct clf_range_data * crd_get_tightest(struct array_list *crdlist, Word_t start, Word_t end, int *contains_saveptr)
Definition: clfit.c:66
void * clmatchone_find(clmatchone_t *clf, Word_t index, Word_t *o_index)
Definition: clfit.c:977
struct clf_range_data * containing_range
Definition: clfit.h:40
int len
Definition: dumptarget.c:52
Definition: log.h:98
#define vdebug(devel, areas, flags, format,...)
Definition: log.h:302
struct array_list * clrange_find_prev_exc(clrange_t *clf, Word_t index)
Definition: clfit.c:468
FILE * stream
Definition: output.h:26
int clrangesimple_find(clrangesimple_t *clr, Word_t index, Word_t *start, Word_t *end, void **data)
Definition: clfit.c:713
void * data
Definition: clfit.h:39
#define CLRANGE_END(crd)
Definition: clfit.h:44
#define CLRANGE_START(crd)
Definition: clfit.h:43
struct array_list * clmatch_find(clmatch_t *clf, Word_t index)
Definition: clfit.c:882
void(* clrange_dumper_t)(Word_t start, Word_t end, struct dump_info *ud, void *data)
Definition: clfit.h:83
struct array_list * clrange_find_next_inc(clrange_t *clf, Word_t index)
Definition: clfit.c:481
int clmatchone_update(clmatchone_t *clf, Word_t index, void *data)
Definition: clfit.c:953
int(* clrangesimple_foreach_handler)(Word_t start, Word_t end, void *data, void *hpriv)
Definition: clfit.h:114
int clrangesimple_remove(clrangesimple_t *clr, Word_t index, Word_t *end, void **data)
Definition: clfit.c:739
struct clf_range_data * clrange_find_next_loosest(clrange_t *clf, Word_t index, struct array_list **al_saveptr)
Definition: clfit.c:420
void(* clrangesimple_free_dtor)(Word_t start, Word_t end, void *data, void *dtor_data)
Definition: clfit.h:118
struct array_list * clrange_find_next_exc(clrange_t *clf, Word_t index)
Definition: clfit.c:494
#define PRIxADDR
Definition: common.h:67
clmatch_t clmatch_create()
Definition: clfit.c:836
void * malloc(size_t size)
Definition: debugserver.c:214
struct array_list * clrange_find_subranges_inside(clrange_t *clf, Word_t index, unsigned int len)
Definition: clfit.c:507
int clrangesimple_foreach(clrangesimple_t clr, clrangesimple_foreach_handler handler, void *hpriv)
Definition: clfit.c:779
Pvoid_t clmatchone_t
Definition: clfit.h:136
int clrange_add(clrange_t *clf, Word_t start, Word_t end, void *data)
Definition: clfit.c:104
void * clrange_find(clrange_t *clf, Word_t index)
Definition: clfit.c:312
void clmatchone_free(clmatchone_t clf)
Definition: clfit.c:994