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. */
24 #include "libiberty.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
42 /* Splay tree containing aranges. */
45 /* Lowest address in set. If set is empty, it is ~0. */
48 /* Highest address in set. If set is empty, it is 0. */
51 /* TRUE if aranges in this set have values. */
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. */
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. */
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. */
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. */
93 /* Value associated with this arange. */
94 arange_value_type value
;
96 } arange_value_container_t
;
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. */
110 splay_tree_compare_bfd_vmas (splay_tree_key k1
, splay_tree_key k2
)
112 if ((bfd_vma
) k1
< (bfd_vma
) k2
)
114 else if ((bfd_vma
) k1
> (bfd_vma
) k2
)
120 /* Default memory allocator and deallocator. */
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
);
132 arange_set_deallocate (arange_set set
, void *object
)
134 if (set
->deallocate_fn
)
135 (set
->deallocate_fn
) (object
, set
->data
);
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
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
184 arange_set_new (arange_set_allocate_fn allocate_fn
,
185 arange_set_deallocate_fn deallocate_fn
,
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
,
195 splay_tree_delete_value_fn fn
;
197 /* Allocate space for arange structure. */
199 (*allocate_fn
) (sizeof (struct arange_set_s
), data
);
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
,
209 (deallocate_fn
) (set
, data
);
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
;
227 /* Delete an arange set. */
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. */
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. */
252 arange_set_node_high (arange_set set
, splay_tree_node node
)
254 arange_value_container_t
*container
;
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. */
268 arange_set_node_set_high (arange_set set
, splay_tree_node node
, bfd_vma address
)
270 arange_value_container_t
*container
;
274 container
= (arange_value_container_t
*) node
->value
;
275 container
->high
= address
;
278 node
->value
= (splay_tree_value
) address
;
281 /* Get the low VMA address of a node. */
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
;
299 container
= (arange_value_container_t
*) node
->value
;
300 return container
->value
;
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. */
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
;
318 container
= (arange_value_container_t
*) node
->value
;
319 container
->value
= value
;
323 /* Return TRUE if and only if arange set supports values. */
326 arange_set_has_values_p (arange_set set
)
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. */
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
);
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. */
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. */
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
)
393 /* Find immediate predecessor. */
394 pred
= splay_tree_predecessor (set
->ranges
, (splay_tree_key
) address
);
396 && arange_set_node_high (set
, pred
) >= address
)
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
);
405 /* Also return arange boundaries if caller supplies pointers. */
407 *low_ptr
= arange_set_node_low (node
);
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
);
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
,
426 arange_value_type value
)
428 splay_tree_value sp_value
;
429 arange_value_container_t
*container
;
433 int size
= sizeof (arange_value_container_t
);
434 void *data
= set
->ranges
->allocate_data
;
437 (arange_value_container_t
*) (*set
->ranges
->allocate
) (size
, data
);
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
;
451 sp_value
= (splay_tree_value
) high
;
453 /* Currently splay_tree_insert does not return any status to tell if there
455 return splay_tree_insert (set
->ranges
, (splay_tree_key
) low
, sp_value
);
458 /* Split [low, high] to [low, address) & [address, high]. */
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
;
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
);
477 arange_set_node_set_high (set
, node
, address
- 1);
481 static splay_tree_node
482 arange_set_maybe_merge_with_predecessor (arange_set set
, splay_tree_node node
)
484 splay_tree_node pred
;
487 low
= arange_set_node_low (node
);
488 high
= arange_set_node_high (set
, node
);
490 pred
= splay_tree_predecessor (set
->ranges
, low
);
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
);
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. */
517 arange_set_insert_value (arange_set set
,
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
;
528 arange_set_delete_value (set
, value
);
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
);
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,
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
));
561 succ
= arange_set_maybe_merge_with_predecessor (set
, succ
);
566 succ
= splay_tree_successor (set
->ranges
, low
);
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
);
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
);
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
));
605 succ
= arange_set_maybe_merge_with_predecessor (set
, succ
);
611 arange_set_insert (arange_set set
,
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
;
621 return arange_set_insert_value (set
, low
, high
, value
);
626 pred
= splay_tree_predecessor (tree
, low
);
629 pred_high
= arange_set_node_high (set
, pred
);
631 /* Nothing to be done if predecessor contains new aranges. */
632 if (pred_high
>= high
)
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
)
640 arange_set_node_set_high (set
, node
, high
);
644 /* Try to see if [low,something] is already in splay tree. */
647 node
= splay_tree_lookup (tree
, low
);
650 /* Nothing to be done if node contains new aranges. */
651 if (arange_set_node_high (set
, node
) >= high
)
654 arange_set_node_set_high (set
, node
, high
);
660 node
= arange_set_splay_tree_insert (set
, low
, high
, 0);
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
));
689 struct arange_set_foreach_adapter_data
693 arange_set_foreach_fn foreach_fn
;
696 /* Adaptor to make arange_set_foreach works with splay_tree_foreach. */
699 arange_set_foreach_adapter (splay_tree_node node
, void *data
)
701 struct arange_set_foreach_adapter_data
*adapter_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
),
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
,
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
);