2008-01-23 H.J. Lu <hongjiu.lu@intel.com>
[binutils.git] / bfd / arange-set.c
blob0a6c2f0cccd092f742aa4b2f99d7dba73ba4e647
1 /* DWARF 2 Arange-Set.
2 Copyright 2007 Free Software Foundation, Inc.
3 Contributed by Doug Kwan, Google Inc.
5 This file is part of BFD.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or (at
10 your option) any later version.
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
22 #include "sysdep.h"
23 #include "bfd.h"
24 #include "libiberty.h"
25 #include "libbfd.h"
26 #include "arange-set.h"
27 #include "splay-tree.h"
29 /* Implementation of an arange-set. The set is implemented using the
30 splay tree support in libiberty. The advantage of using this is
31 that it has been well tested and is relatively simple to use. The
32 disadvantage is that it is too general and it does not fit our design
33 exactly. So we waste a bit of memory for unneeded generality and work
34 around for mis-match between the splay tree API and the arange-set
35 internals. A specialized implentation of a balanced tree type for
36 arange-set exclusively may speed up things a little and reduce memory
37 consumption. Until there is a pressing need, we stick to the splay
38 tree in libiberty. */
40 struct arange_set_s
42 /* Splay tree containing aranges. */
43 splay_tree ranges;
45 /* Lowest address in set. If set is empty, it is ~0. */
46 bfd_vma lower_bound;
48 /* Highest address in set. If set is empty, it is 0. */
49 bfd_vma upper_bound;
51 /* TRUE if aranges in this set have values. */
52 bfd_boolean value_p;
54 /* Function to compare arange values. */
55 arange_value_equal_fn value_equal_fn;
57 /* Function to copy an arange value. */
58 arange_value_copy_fn value_copy_fn;
60 /* Function to combine arange values. */
61 arange_value_combine_fn value_combine_fn;
63 /* Function to delete an arange value. */
64 arange_value_delete_fn value_delete_fn;
66 /* Function to allocate a piece of memory. */
67 arange_set_allocate_fn allocate_fn;
69 /* Function to deallocate a piece of memory. */
70 arange_set_deallocate_fn deallocate_fn;
72 /* Call back data shared by all callbacks. */
73 void *data;
76 /* Structure for aranges with a value attached. Since a splay tree
77 node can only hold one value, we need to use the container struct
78 to store data associated with an arange and have the splay tree value
79 to be a pointer to this struct. */
81 typedef struct
83 /* High-pc of an arange. This is different from the DWARF2 semantics that
84 the high-pc is really the last location in an arange. */
85 bfd_vma high;
87 /* We need to store a pointer to the set because splay_tree_value_delete
88 only takes a pointer to the value deleted. If we use a deallocator
89 that need extra information like a pointer to the memory pool, we need to
90 look up via the set pointer. This adds one extra pointer per arange. */
91 arange_set set;
93 /* Value associated with this arange. */
94 arange_value_type value;
96 } arange_value_container_t;
100 static void
101 arange_set_delete_value (arange_set set, arange_value_type value)
103 if (set->value_delete_fn)
104 (set->value_delete_fn) (value, set->data);
107 /* Compare two VMAs as keys of splay tree nodes. */
109 static int
110 splay_tree_compare_bfd_vmas (splay_tree_key k1, splay_tree_key k2)
112 if ((bfd_vma) k1 < (bfd_vma) k2)
113 return -1;
114 else if ((bfd_vma) k1 > (bfd_vma) k2)
115 return 1;
117 return 0;
120 /* Default memory allocator and deallocator. */
122 void *
123 arange_set_allocate (arange_set set, int size)
125 if (set->allocate_fn)
126 return (set->allocate_fn) (size, set->data);
128 return xmalloc (size);
131 void
132 arange_set_deallocate (arange_set set, void *object)
134 if (set->deallocate_fn)
135 (set->deallocate_fn) (object, set->data);
136 else
137 free (object);
140 static void
141 arange_set_delete_value_container (splay_tree_value value)
143 arange_value_container_t *container;
145 container = (arange_value_container_t*) value;
146 arange_set_delete_value (container->set, container->value);
147 arange_set_deallocate (container->set, container);
150 /* Create an arange set. Return the new set of NULL if there is any
151 error.
153 allocate_fn is the memory allocator function of this arange set. If
154 it is NULL, the default allocator will be used.
156 deallocate_fn is the memory deallocator function of this arange set. If
157 it is NULL, the default allocator will be used.
159 value_p specifies whether an arange set supports values. If it is
160 TURE. Each arange can be associated with a value of type arange_value_type.
161 If it is FALSE, the following parameters value_equal_fn, value_copy_fn,
162 value_combine_fn and value_delete_fn will be ignored.
164 value_equal_fn is the value equality function. An arange uses it to
165 check if two values are the same. If it is NULL, the default bit-wise
166 equality function will be used.
168 value_copy_fn is the value copy function. An arange uses it to copy
169 values of type arange_value_type. If it is NULL, the default bit-wise
170 copy function will be used.
172 value_combine_fn is the value combine function. An arange uses it to
173 combine values of two identical arange. If it is NULL, the default
174 constant zero function will be used.
176 value_delete_fn is the value deletion function. If it is not NULL,
177 it will be called when an arange deletes a value.
179 data is pointer to an object, which will be passed to all allocate_fn,
180 deallocate_fn, value_equal_fn, value_copy_fn, value_combine_fn and
181 value_delete_fn. */
183 arange_set
184 arange_set_new (arange_set_allocate_fn allocate_fn,
185 arange_set_deallocate_fn deallocate_fn,
186 bfd_boolean value_p,
187 arange_value_equal_fn value_equal_fn,
188 arange_value_copy_fn value_copy_fn,
189 arange_value_combine_fn value_combine_fn,
190 arange_value_delete_fn value_delete_fn,
191 void *data)
193 arange_set set;
194 splay_tree sp;
195 splay_tree_delete_value_fn fn;
197 /* Allocate space for arange structure. */
198 set = (arange_set)
199 (*allocate_fn) (sizeof (struct arange_set_s), data);
200 if (!set)
201 return set;
203 fn = value_p ? arange_set_delete_value_container : NULL;
204 sp = splay_tree_new_with_allocator (splay_tree_compare_bfd_vmas, NULL,
205 fn, allocate_fn, deallocate_fn,
206 data);
207 if (!sp)
209 (deallocate_fn) (set, data);
210 return NULL;
213 set->ranges = sp;
214 set->lower_bound = ~0;
215 set->upper_bound = 0;
216 set->value_p = value_p;
217 set->allocate_fn = allocate_fn;
218 set->deallocate_fn = deallocate_fn;
219 set->value_equal_fn = value_equal_fn;
220 set->value_copy_fn = value_copy_fn;
221 set->value_combine_fn = value_combine_fn;
222 set->value_delete_fn = value_delete_fn;
223 set->data = data;
224 return set;
227 /* Delete an arange set. */
229 void
230 arange_set_delete (arange_set set)
232 splay_tree_delete (set->ranges);
233 (*set->deallocate_fn) (set, set->data);
236 /* Return TRUE if and only if arange set is empty. */
238 bfd_boolean
239 arange_set_empty_p (arange_set set)
241 return set->lower_bound > set->upper_bound;
244 /* Accessors for low and high of an arange.
246 There is no arange_set_node_set_low since the low address is the
247 key of the splay tree node. */
249 /* Get the high VMA address of a node. */
251 static bfd_vma
252 arange_set_node_high (arange_set set, splay_tree_node node)
254 arange_value_container_t *container;
256 if (set->value_p)
258 container = (arange_value_container_t*) node->value;
259 return container->high;
262 return (bfd_vma) node->value;
265 /* Set the high VMA address of a node. */
267 static void
268 arange_set_node_set_high (arange_set set, splay_tree_node node, bfd_vma address)
270 arange_value_container_t *container;
272 if (set->value_p)
274 container = (arange_value_container_t*) node->value;
275 container->high = address;
277 else
278 node->value = (splay_tree_value) address;
281 /* Get the low VMA address of a node. */
283 static bfd_vma
284 arange_set_node_low (splay_tree_node node)
286 return (bfd_vma) node->key;
289 /* If arange set supports values, return value of an arange; otheriwse
290 always return 0 so that it appears that all aranges have the same value. */
292 static arange_value_type
293 arange_set_node_value (arange_set set, splay_tree_node node)
295 arange_value_container_t *container;
297 if (set->value_p)
299 container = (arange_value_container_t*) node->value;
300 return container->value;
303 return 0;
306 /* If arange set supports values, return value of an arange; otheriwse
307 always return 0 so that it appears that all aranges have the same value. */
309 static void
310 arange_set_node_set_value (arange_set set,
311 splay_tree_node node,
312 arange_value_type value)
314 arange_value_container_t *container;
316 if (set->value_p)
318 container = (arange_value_container_t*) node->value;
319 container->value = value;
323 /* Return TRUE if and only if arange set supports values. */
325 bfd_boolean
326 arange_set_has_values_p (arange_set set)
328 return set->value_p;
331 /* Copy a value using the value copying function of an arange set. If
332 the set does not support values or if there is not value copying
333 function specified, it simply returns the input value. */
335 arange_value_type
336 arange_set_copy_value (arange_set set, arange_value_type value)
338 /* If no copy function is specified or set does not support values,
339 default is bit-wise copy. */
340 if (set->value_p && set->value_copy_fn)
341 return (set->value_copy_fn) (value, set->data);
343 return value;
346 static arange_value_type
347 arange_set_combine_value (arange_set set,
348 arange_value_type value1,
349 arange_value_type value2)
351 /* If no combine function is specified or set does not support values,
352 default is returning 0. */
353 if (set->value_p && set->value_combine_fn)
354 return (set->value_combine_fn) (value1, value2, set->data);
356 return (arange_value_type) 0;
359 /* Compares two values for equality. If the arange set does not support values
360 or if no value equality function is specified, this function simply does
361 a bit-wise comparison. */
363 bfd_boolean
364 arange_set_value_equal_p (arange_set set,
365 arange_value_type value1,
366 arange_value_type value2)
368 /* If no equality function is specified or set does not support values,
369 default is bit-wise comparison. */
370 if (set->value_p && set->value_equal_fn)
371 return (set->value_equal_fn) (value1, value2, set->data);
373 return value1 == value2;
376 /* Check to see if a given address is in an arange set. Return TRUE if the
377 address is inside one of the aranges. If low_ptr, high_ptr and value_ptr are
378 used to return lower address, upper address and value associated with a
379 found arounge. If anyone of them is NULL, the corresponding information
380 is not returned. For arange set without values, no information is returned
381 through the pointer value_ptr. */
383 bfd_boolean
384 arange_set_lookup_address (arange_set set, bfd_vma address,
385 bfd_vma *low_ptr, bfd_vma *high_ptr,
386 arange_value_type *value_ptr)
388 splay_tree_node pred, node;
390 if (address < set->lower_bound || address > set->upper_bound)
391 return FALSE;
393 /* Find immediate predecessor. */
394 pred = splay_tree_predecessor (set->ranges, (splay_tree_key) address);
395 if (pred
396 && arange_set_node_high (set, pred) >= address)
397 node = pred;
398 else
399 /* If the predecessor range does not cover this address, the address
400 is in the arange set only if itself starts an arange. */
401 node = splay_tree_lookup (set->ranges, (splay_tree_key) address);
403 if (node)
405 /* Also return arange boundaries if caller supplies pointers. */
406 if (low_ptr)
407 *low_ptr = arange_set_node_low (node);
408 if (high_ptr)
409 *high_ptr = arange_set_node_high (set, node);
410 if (set->value_p && value_ptr)
411 *value_ptr = arange_set_node_value (set, node);
412 return TRUE;
415 return FALSE;
418 /* Insert an arange [low, high] into a set's splay tree. If the set supports
419 value, also insert with the given value. Return the inserted node if there
420 is no error or NULL otherwise. */
422 static splay_tree_node
423 arange_set_splay_tree_insert (arange_set set,
424 bfd_vma low,
425 bfd_vma high,
426 arange_value_type value)
428 splay_tree_value sp_value;
429 arange_value_container_t *container;
431 if (set->value_p)
433 int size = sizeof (arange_value_container_t);
434 void *data = set->ranges->allocate_data;
436 container =
437 (arange_value_container_t*) (*set->ranges->allocate) (size, data);
438 if (!container)
439 return NULL;
440 container->high = high;
442 /* Due to the design of splay tree API, there is no way of passing
443 callback data to the splay tree value delete function. Hence we need
444 to store a pointer to set in every containier! */
445 container->set = set;
447 container->value = value;
448 sp_value = (splay_tree_value) container;
450 else
451 sp_value = (splay_tree_value) high;
453 /* Currently splay_tree_insert does not return any status to tell if there
454 is an error. */
455 return splay_tree_insert (set->ranges, (splay_tree_key) low, sp_value);
458 /* Split [low, high] to [low, address) & [address, high]. */
460 static bfd_boolean
461 arange_set_split_node (arange_set set, splay_tree_node node, bfd_vma address)
463 splay_tree_node node2;
464 arange_value_type value;
465 bfd_vma low, high;
467 low = arange_set_node_low (node);
468 high = arange_set_node_high (set, node);
470 BFD_ASSERT (low < address && address <= high);
472 value = arange_set_copy_value (set, arange_set_node_value (set, node));
473 node2 = arange_set_splay_tree_insert (set, address, high, value);
474 if (!node2)
475 return FALSE;
477 arange_set_node_set_high (set, node, address - 1);
478 return TRUE;
481 static splay_tree_node
482 arange_set_maybe_merge_with_predecessor (arange_set set, splay_tree_node node)
484 splay_tree_node pred;
485 bfd_vma low, high;
487 low = arange_set_node_low (node);
488 high = arange_set_node_high (set, node);
490 pred = splay_tree_predecessor (set->ranges, low);
491 if (! pred)
492 return node;
494 if (arange_set_node_high (set, pred) + 1 == low
495 && arange_set_value_equal_p (set,
496 arange_set_node_value (set, pred),
497 arange_set_node_value (set, node)))
499 splay_tree_remove (set->ranges, arange_set_node_low (node));
500 arange_set_node_set_high (set, pred, high);
501 return arange_set_maybe_merge_with_predecessor (set, pred);
504 return node;
507 /* Insert an arange [low,high] into a set. Return TRUE if and only if there
508 is no error. Note that the address high is also included where as in
509 DWARF2 an address range between low & high means [low,high).
511 This only handles sets with values. For the simpler case of sets without
512 value, it is handled in arange_set_insert(). This function is
513 tail-recurive. It is guaranteed to terminate because it only recurses
514 with a smaller range than it is given. */
516 static bfd_boolean
517 arange_set_insert_value (arange_set set,
518 bfd_vma low,
519 bfd_vma high,
520 arange_value_type value)
522 splay_tree_node succ, pred, node;
523 bfd_vma succ_high, succ_low;
524 arange_value_type combined, old_value;
526 if (low > high)
528 arange_set_delete_value (set, value);
529 return FALSE;
532 pred = splay_tree_predecessor (set->ranges, low);
533 if (pred && arange_set_node_high (set, pred) >= low)
534 arange_set_split_node (set, pred, low);
536 node = splay_tree_lookup (set->ranges, low);
537 if (node)
539 /* Split node if its arange is larger than inserted arange. */
540 if (arange_set_node_high (set, node) > high)
541 arange_set_split_node (set, node, high + 1);
543 old_value = arange_set_node_value (set, node);
544 combined = arange_set_combine_value (set, old_value, value);
545 arange_set_node_set_value (set, node, combined);
546 node = arange_set_maybe_merge_with_predecessor (set, node);
547 arange_set_delete_value (set, old_value);
549 /* Insert remaining arange by tail-recursion. */
550 if (high > arange_set_node_high (set, node))
551 return arange_set_insert_value (set,
552 arange_set_node_high (set, node) + 1,
553 high, value);
554 else
556 /* Node must cover exactly the range. */
557 BFD_ASSERT (high == arange_set_node_high (set, node));
558 arange_set_delete_value (set, value);
559 succ = splay_tree_successor (set->ranges, arange_set_node_low (node));
560 if (succ)
561 succ = arange_set_maybe_merge_with_predecessor (set, succ);
562 return TRUE;
566 succ = splay_tree_successor (set->ranges, low);
567 if (succ)
569 succ_low = arange_set_node_low (succ);
570 succ_high = arange_set_node_high (set, succ);
572 if (succ_low <= high)
574 node = arange_set_splay_tree_insert (set, low, succ_low - 1, value);
575 if (!node)
576 return FALSE;
578 /* Update set lower bound only after insertion is successful. */
579 if (low < set->lower_bound)
580 set->lower_bound = low;
582 node = arange_set_maybe_merge_with_predecessor (set, node);
584 /* Recurse to handle rest of insertion. Note that we have to copy
585 value here since it has already been used in the node above. */
586 return arange_set_insert_value (set, succ_low, high,
587 arange_set_copy_value (set, value));
591 node = arange_set_splay_tree_insert (set, low, high, value);
592 if (!node)
593 return FALSE;
595 /* Update set boundaries only after insertion is successful. */
596 if (low < set->lower_bound)
597 set->lower_bound = low;
598 if (high > set->upper_bound)
599 set->upper_bound = high;
601 node = arange_set_maybe_merge_with_predecessor (set, node);
603 succ = splay_tree_successor (set->ranges, arange_set_node_low (node));
604 if (succ)
605 succ = arange_set_maybe_merge_with_predecessor (set, succ);
607 return TRUE;
610 bfd_boolean
611 arange_set_insert (arange_set set,
612 bfd_vma low,
613 bfd_vma high,
614 arange_value_type value)
616 splay_tree tree = set->ranges;
617 splay_tree_node pred, succ, node = NULL;
618 bfd_vma pred_high, node_low;
620 if (set->value_p)
621 return arange_set_insert_value (set, low, high, value);
623 if (low > high)
624 return FALSE;
626 pred = splay_tree_predecessor (tree, low);
627 if (pred)
629 pred_high = arange_set_node_high (set, pred);
631 /* Nothing to be done if predecessor contains new aranges. */
632 if (pred_high >= high)
633 return TRUE;
635 /* If we can expand predecessor, do so. Test for the case in which
636 predecessor does not contain new arange but touches it. */
637 if (pred_high >= low || pred_high + 1 == low)
639 node = pred;
640 arange_set_node_set_high (set, node, high);
644 /* Try to see if [low,something] is already in splay tree. */
645 if (node == NULL)
647 node = splay_tree_lookup (tree, low);
648 if (node)
650 /* Nothing to be done if node contains new aranges. */
651 if (arange_set_node_high (set, node) >= high)
652 return TRUE;
654 arange_set_node_set_high (set, node, high);
658 if (node == NULL)
660 node = arange_set_splay_tree_insert (set, low, high, 0);
661 if (!node)
662 return FALSE;
665 BFD_ASSERT (node
666 && arange_set_node_low (node) <= low
667 && arange_set_node_high (set, node) >= high);
669 /* Update set upper and lower bounds. */
670 if (low < set->lower_bound)
671 set->lower_bound = low;
672 if (high > set->upper_bound)
673 set->upper_bound = high;
675 /* Merge successor if it overlaps or touches node. */
676 node_low = arange_set_node_low (node);
677 while ((succ = splay_tree_successor (tree, node_low)) != NULL
678 && ((arange_set_node_high (set, node) >= arange_set_node_low (succ))
679 || (arange_set_node_high (set, node) + 1
680 == arange_set_node_low (succ))))
682 if (arange_set_node_high (set, succ) > high)
683 arange_set_node_set_high (set, node, arange_set_node_high (set, succ));
684 splay_tree_remove (tree, arange_set_node_low (succ));
686 return TRUE;
689 struct arange_set_foreach_adapter_data
691 void *data;
692 arange_set set;
693 arange_set_foreach_fn foreach_fn;
696 /* Adaptor to make arange_set_foreach works with splay_tree_foreach. */
698 static int
699 arange_set_foreach_adapter (splay_tree_node node, void *data)
701 struct arange_set_foreach_adapter_data *adapter_data;
702 arange_set set;
704 adapter_data = data;
705 set = adapter_data->set;
706 return (adapter_data->foreach_fn) (arange_set_node_low (node),
707 arange_set_node_high (set, node),
708 arange_set_node_value (set, node),
709 adapter_data->data);
712 /* Traverse aranges in a set. For each arange in ascending order of
713 low addresses, call foreach_fn with arange boundaries and data.
714 If any invocation of foreach_fn returns a non-zero value, stop traversal
715 and return that value. Otherwise, return 0. */
718 arange_set_foreach (arange_set set,
719 arange_set_foreach_fn foreach_fn,
720 void *data)
722 struct arange_set_foreach_adapter_data adapter_data;
724 adapter_data.data = data;
725 adapter_data.foreach_fn = foreach_fn;
726 adapter_data.set = set;
727 return splay_tree_foreach (set->ranges, arange_set_foreach_adapter,
728 (void *) &adapter_data);