xref: /dflybsd-src/contrib/gdb-7/gdb/memrange.c (revision de8e141f24382815c10a4012d209bbbf7abf1112)
1c50c785cSJohn Marino /* Memory ranges
2c50c785cSJohn Marino 
3*ef5ccd6cSJohn Marino    Copyright (C) 2010-2013 Free Software Foundation, Inc.
4c50c785cSJohn Marino 
5c50c785cSJohn Marino    This file is part of GDB.
6c50c785cSJohn Marino 
7c50c785cSJohn Marino    This program is free software; you can redistribute it and/or modify
8c50c785cSJohn Marino    it under the terms of the GNU General Public License as published by
9c50c785cSJohn Marino    the Free Software Foundation; either version 3 of the License, or
10c50c785cSJohn Marino    (at your option) any later version.
11c50c785cSJohn Marino 
12c50c785cSJohn Marino    This program is distributed in the hope that it will be useful,
13c50c785cSJohn Marino    but WITHOUT ANY WARRANTY; without even the implied warranty of
14c50c785cSJohn Marino    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15c50c785cSJohn Marino    GNU General Public License for more details.
16c50c785cSJohn Marino 
17c50c785cSJohn Marino    You should have received a copy of the GNU General Public License
18c50c785cSJohn Marino    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19c50c785cSJohn Marino 
20c50c785cSJohn Marino #include "defs.h"
21c50c785cSJohn Marino #include "memrange.h"
22c50c785cSJohn Marino 
23c50c785cSJohn Marino int
mem_ranges_overlap(CORE_ADDR start1,int len1,CORE_ADDR start2,int len2)24c50c785cSJohn Marino mem_ranges_overlap (CORE_ADDR start1, int len1,
25c50c785cSJohn Marino 		    CORE_ADDR start2, int len2)
26c50c785cSJohn Marino {
27c50c785cSJohn Marino   ULONGEST h, l;
28c50c785cSJohn Marino 
29c50c785cSJohn Marino   l = max (start1, start2);
30c50c785cSJohn Marino   h = min (start1 + len1, start2 + len2);
31c50c785cSJohn Marino   return (l < h);
32c50c785cSJohn Marino }
33c50c785cSJohn Marino 
34c50c785cSJohn Marino /* qsort comparison function, that compares mem_ranges.  Ranges are
35c50c785cSJohn Marino    sorted in ascending START order.  */
36c50c785cSJohn Marino 
37c50c785cSJohn Marino static int
compare_mem_ranges(const void * ap,const void * bp)38c50c785cSJohn Marino compare_mem_ranges (const void *ap, const void *bp)
39c50c785cSJohn Marino {
40c50c785cSJohn Marino   const struct mem_range *r1 = ap;
41c50c785cSJohn Marino   const struct mem_range *r2 = bp;
42c50c785cSJohn Marino 
43c50c785cSJohn Marino   if (r1->start > r2->start)
44c50c785cSJohn Marino     return 1;
45c50c785cSJohn Marino   else if (r1->start < r2->start)
46c50c785cSJohn Marino     return -1;
47c50c785cSJohn Marino   else
48c50c785cSJohn Marino     return 0;
49c50c785cSJohn Marino }
50c50c785cSJohn Marino 
51c50c785cSJohn Marino void
normalize_mem_ranges(VEC (mem_range_s)* ranges)52c50c785cSJohn Marino normalize_mem_ranges (VEC(mem_range_s) *ranges)
53c50c785cSJohn Marino {
54c50c785cSJohn Marino   /* This function must not use any VEC operation on RANGES that
55c50c785cSJohn Marino      reallocates the memory block as that invalidates the RANGES
56c50c785cSJohn Marino      pointer, which callers expect to remain valid.  */
57c50c785cSJohn Marino 
58c50c785cSJohn Marino   if (!VEC_empty (mem_range_s, ranges))
59c50c785cSJohn Marino     {
60c50c785cSJohn Marino       struct mem_range *ra, *rb;
61c50c785cSJohn Marino       int a, b;
62c50c785cSJohn Marino 
63c50c785cSJohn Marino       qsort (VEC_address (mem_range_s, ranges),
64c50c785cSJohn Marino 	     VEC_length (mem_range_s, ranges),
65c50c785cSJohn Marino 	     sizeof (mem_range_s),
66c50c785cSJohn Marino 	     compare_mem_ranges);
67c50c785cSJohn Marino 
68c50c785cSJohn Marino       a = 0;
69c50c785cSJohn Marino       ra = VEC_index (mem_range_s, ranges, a);
70c50c785cSJohn Marino       for (b = 1; VEC_iterate (mem_range_s, ranges, b, rb); b++)
71c50c785cSJohn Marino 	{
72c50c785cSJohn Marino 	  /* If mem_range B overlaps or is adjacent to mem_range A,
73c50c785cSJohn Marino 	     merge them.  */
74c50c785cSJohn Marino 	  if (rb->start <= ra->start + ra->length)
75c50c785cSJohn Marino 	    {
76c50c785cSJohn Marino 	      ra->length = max (ra->length,
77c50c785cSJohn Marino 				(rb->start - ra->start) + rb->length);
78c50c785cSJohn Marino 	      continue;		/* next b, same a */
79c50c785cSJohn Marino 	    }
80c50c785cSJohn Marino 	  a++;			/* next a */
81c50c785cSJohn Marino 	  ra = VEC_index (mem_range_s, ranges, a);
82c50c785cSJohn Marino 
83c50c785cSJohn Marino 	  if (a != b)
84c50c785cSJohn Marino 	    *ra = *rb;
85c50c785cSJohn Marino 	}
86c50c785cSJohn Marino       VEC_truncate (mem_range_s, ranges, a + 1);
87c50c785cSJohn Marino     }
88c50c785cSJohn Marino }
89