1 diff -urN binutils-2.18.50.0.4.org/bfd/arange-set.c binutils-2.18.50.0.4/bfd/arange-set.c
2 --- binutils-2.18.50.0.4.org/bfd/arange-set.c 2008-02-08 17:44:56.000000000 +0100
3 +++ binutils-2.18.50.0.4/bfd/arange-set.c 1970-01-01 01:00:00.000000000 +0100
5 -/* DWARF 2 Arange-Set.
6 - Copyright 2007 Free Software Foundation, Inc.
7 - Contributed by Doug Kwan, Google Inc.
9 - This file is part of BFD.
11 - This program is free software; you can redistribute it and/or modify
12 - it under the terms of the GNU General Public License as published by
13 - the Free Software Foundation; either version 3 of the License, or (at
14 - your option) any later version.
16 - This program is distributed in the hope that it will be useful, but
17 - WITHOUT ANY WARRANTY; without even the implied warranty of
18 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 - General Public License for more details.
21 - You should have received a copy of the GNU General Public License
22 - along with this program; if not, write to the Free Software
23 - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
24 - MA 02110-1301, USA. */
28 -#include "libiberty.h"
30 -#include "arange-set.h"
31 -#include "splay-tree.h"
33 -/* Implementation of an arange-set. The set is implemented using the
34 - splay tree support in libiberty. The advantage of using this is
35 - that it has been well tested and is relatively simple to use. The
36 - disadvantage is that it is too general and it does not fit our design
37 - exactly. So we waste a bit of memory for unneeded generality and work
38 - around for mis-match between the splay tree API and the arange-set
39 - internals. A specialized implentation of a balanced tree type for
40 - arange-set exclusively may speed up things a little and reduce memory
41 - consumption. Until there is a pressing need, we stick to the splay
42 - tree in libiberty. */
46 - /* Splay tree containing aranges. */
49 - /* Lowest address in set. If set is empty, it is ~0. */
50 - bfd_vma lower_bound;
52 - /* Highest address in set. If set is empty, it is 0. */
53 - bfd_vma upper_bound;
55 - /* TRUE if aranges in this set have values. */
56 - bfd_boolean value_p;
58 - /* Function to compare arange values. */
59 - arange_value_equal_fn value_equal_fn;
61 - /* Function to copy an arange value. */
62 - arange_value_copy_fn value_copy_fn;
64 - /* Function to combine arange values. */
65 - arange_value_combine_fn value_combine_fn;
67 - /* Function to delete an arange value. */
68 - arange_value_delete_fn value_delete_fn;
70 - /* Function to allocate a piece of memory. */
71 - arange_set_allocate_fn allocate_fn;
73 - /* Function to deallocate a piece of memory. */
74 - arange_set_deallocate_fn deallocate_fn;
76 - /* Call back data shared by all callbacks. */
80 -/* Structure for aranges with a value attached. Since a splay tree
81 - node can only hold one value, we need to use the container struct
82 - to store data associated with an arange and have the splay tree value
83 - to be a pointer to this struct. */
87 - /* High-pc of an arange. This is different from the DWARF2 semantics that
88 - the high-pc is really the last location in an arange. */
91 - /* We need to store a pointer to the set because splay_tree_value_delete
92 - only takes a pointer to the value deleted. If we use a deallocator
93 - that need extra information like a pointer to the memory pool, we need to
94 - look up via the set pointer. This adds one extra pointer per arange. */
97 - /* Value associated with this arange. */
98 - arange_value_type value;
100 -} arange_value_container_t;
105 -arange_set_delete_value (arange_set set, arange_value_type value)
107 - if (set->value_delete_fn)
108 - (set->value_delete_fn) (value, set->data);
111 -/* Compare two VMAs as keys of splay tree nodes. */
114 -splay_tree_compare_bfd_vmas (splay_tree_key k1, splay_tree_key k2)
116 - if ((bfd_vma) k1 < (bfd_vma) k2)
118 - else if ((bfd_vma) k1 > (bfd_vma) k2)
124 -/* Default memory allocator and deallocator. */
127 -arange_set_allocate (arange_set set, int size)
129 - if (set->allocate_fn)
130 - return (set->allocate_fn) (size, set->data);
132 - return xmalloc (size);
136 -arange_set_deallocate (arange_set set, void *object)
138 - if (set->deallocate_fn)
139 - (set->deallocate_fn) (object, set->data);
145 -arange_set_delete_value_container (splay_tree_value value)
147 - arange_value_container_t *container;
149 - container = (arange_value_container_t*) value;
150 - arange_set_delete_value (container->set, container->value);
151 - arange_set_deallocate (container->set, container);
154 -/* Create an arange set. Return the new set of NULL if there is any
157 - allocate_fn is the memory allocator function of this arange set. If
158 - it is NULL, the default allocator will be used.
160 - deallocate_fn is the memory deallocator function of this arange set. If
161 - it is NULL, the default allocator will be used.
163 - value_p specifies whether an arange set supports values. If it is
164 - TURE. Each arange can be associated with a value of type arange_value_type.
165 - If it is FALSE, the following parameters value_equal_fn, value_copy_fn,
166 - value_combine_fn and value_delete_fn will be ignored.
168 - value_equal_fn is the value equality function. An arange uses it to
169 - check if two values are the same. If it is NULL, the default bit-wise
170 - equality function will be used.
172 - value_copy_fn is the value copy function. An arange uses it to copy
173 - values of type arange_value_type. If it is NULL, the default bit-wise
174 - copy function will be used.
176 - value_combine_fn is the value combine function. An arange uses it to
177 - combine values of two identical arange. If it is NULL, the default
178 - constant zero function will be used.
180 - value_delete_fn is the value deletion function. If it is not NULL,
181 - it will be called when an arange deletes a value.
183 - data is pointer to an object, which will be passed to all allocate_fn,
184 - deallocate_fn, value_equal_fn, value_copy_fn, value_combine_fn and
185 - value_delete_fn. */
188 -arange_set_new (arange_set_allocate_fn allocate_fn,
189 - arange_set_deallocate_fn deallocate_fn,
190 - bfd_boolean value_p,
191 - arange_value_equal_fn value_equal_fn,
192 - arange_value_copy_fn value_copy_fn,
193 - arange_value_combine_fn value_combine_fn,
194 - arange_value_delete_fn value_delete_fn,
199 - splay_tree_delete_value_fn fn;
201 - if (sizeof (bfd_vma) > sizeof (splay_tree_key)
202 - || sizeof (bfd_vma) > sizeof (splay_tree_value))
204 - (*_bfd_error_handler)
205 - (_("size of bfd_vma > size of splay_tree types"));
209 - /* Allocate space for arange structure. */
211 - (*allocate_fn) (sizeof (struct arange_set_s), data);
215 - fn = value_p ? arange_set_delete_value_container : NULL;
216 - sp = splay_tree_new_with_allocator (splay_tree_compare_bfd_vmas, NULL,
217 - fn, allocate_fn, deallocate_fn,
221 - (deallocate_fn) (set, data);
226 - set->lower_bound = ~0;
227 - set->upper_bound = 0;
228 - set->value_p = value_p;
229 - set->allocate_fn = allocate_fn;
230 - set->deallocate_fn = deallocate_fn;
231 - set->value_equal_fn = value_equal_fn;
232 - set->value_copy_fn = value_copy_fn;
233 - set->value_combine_fn = value_combine_fn;
234 - set->value_delete_fn = value_delete_fn;
239 -/* Delete an arange set. */
242 -arange_set_delete (arange_set set)
244 - splay_tree_delete (set->ranges);
245 - (*set->deallocate_fn) (set, set->data);
248 -/* Return TRUE if and only if arange set is empty. */
251 -arange_set_empty_p (arange_set set)
253 - return set->lower_bound > set->upper_bound;
256 -/* Accessors for low and high of an arange.
258 - There is no arange_set_node_set_low since the low address is the
259 - key of the splay tree node. */
261 -/* Get the high VMA address of a node. */
264 -arange_set_node_high (arange_set set, splay_tree_node node)
266 - arange_value_container_t *container;
270 - container = (arange_value_container_t*) node->value;
271 - return container->high;
274 - return (bfd_vma) node->value;
277 -/* Set the high VMA address of a node. */
280 -arange_set_node_set_high (arange_set set, splay_tree_node node, bfd_vma address)
282 - arange_value_container_t *container;
286 - container = (arange_value_container_t*) node->value;
287 - container->high = address;
290 - node->value = (splay_tree_value) address;
293 -/* Get the low VMA address of a node. */
296 -arange_set_node_low (splay_tree_node node)
298 - return (bfd_vma) node->key;
301 -/* If arange set supports values, return value of an arange; otheriwse
302 - always return 0 so that it appears that all aranges have the same value. */
304 -static arange_value_type
305 -arange_set_node_value (arange_set set, splay_tree_node node)
307 - arange_value_container_t *container;
311 - container = (arange_value_container_t*) node->value;
312 - return container->value;
318 -/* If arange set supports values, return value of an arange; otheriwse
319 - always return 0 so that it appears that all aranges have the same value. */
322 -arange_set_node_set_value (arange_set set,
323 - splay_tree_node node,
324 - arange_value_type value)
326 - arange_value_container_t *container;
330 - container = (arange_value_container_t*) node->value;
331 - container->value = value;
335 -/* Return TRUE if and only if arange set supports values. */
338 -arange_set_has_values_p (arange_set set)
340 - return set->value_p;
343 -/* Copy a value using the value copying function of an arange set. If
344 - the set does not support values or if there is not value copying
345 - function specified, it simply returns the input value. */
348 -arange_set_copy_value (arange_set set, arange_value_type value)
350 - /* If no copy function is specified or set does not support values,
351 - default is bit-wise copy. */
352 - if (set->value_p && set->value_copy_fn)
353 - return (set->value_copy_fn) (value, set->data);
358 -static arange_value_type
359 -arange_set_combine_value (arange_set set,
360 - arange_value_type value1,
361 - arange_value_type value2)
363 - /* If no combine function is specified or set does not support values,
364 - default is returning 0. */
365 - if (set->value_p && set->value_combine_fn)
366 - return (set->value_combine_fn) (value1, value2, set->data);
368 - return (arange_value_type) 0;
371 -/* Compares two values for equality. If the arange set does not support values
372 - or if no value equality function is specified, this function simply does
373 - a bit-wise comparison. */
376 -arange_set_value_equal_p (arange_set set,
377 - arange_value_type value1,
378 - arange_value_type value2)
380 - /* If no equality function is specified or set does not support values,
381 - default is bit-wise comparison. */
382 - if (set->value_p && set->value_equal_fn)
383 - return (set->value_equal_fn) (value1, value2, set->data);
385 - return value1 == value2;
388 -/* Check to see if a given address is in an arange set. Return TRUE if the
389 - address is inside one of the aranges. If low_ptr, high_ptr and value_ptr are
390 - used to return lower address, upper address and value associated with a
391 - found arounge. If anyone of them is NULL, the corresponding information
392 - is not returned. For arange set without values, no information is returned
393 - through the pointer value_ptr. */
396 -arange_set_lookup_address (arange_set set, bfd_vma address,
397 - bfd_vma *low_ptr, bfd_vma *high_ptr,
398 - arange_value_type *value_ptr)
400 - splay_tree_node pred, node;
402 - if (address < set->lower_bound || address > set->upper_bound)
405 - /* Find immediate predecessor. */
406 - pred = splay_tree_predecessor (set->ranges, (splay_tree_key) address);
408 - && arange_set_node_high (set, pred) >= address)
411 - /* If the predecessor range does not cover this address, the address
412 - is in the arange set only if itself starts an arange. */
413 - node = splay_tree_lookup (set->ranges, (splay_tree_key) address);
417 - /* Also return arange boundaries if caller supplies pointers. */
419 - *low_ptr = arange_set_node_low (node);
421 - *high_ptr = arange_set_node_high (set, node);
422 - if (set->value_p && value_ptr)
423 - *value_ptr = arange_set_node_value (set, node);
430 -/* Insert an arange [low, high] into a set's splay tree. If the set supports
431 - value, also insert with the given value. Return the inserted node if there
432 - is no error or NULL otherwise. */
434 -static splay_tree_node
435 -arange_set_splay_tree_insert (arange_set set,
438 - arange_value_type value)
440 - splay_tree_value sp_value;
441 - arange_value_container_t *container;
445 - int size = sizeof (arange_value_container_t);
446 - void *data = set->ranges->allocate_data;
449 - (arange_value_container_t*) (*set->ranges->allocate) (size, data);
452 - container->high = high;
454 - /* Due to the design of splay tree API, there is no way of passing
455 - callback data to the splay tree value delete function. Hence we need
456 - to store a pointer to set in every containier! */
457 - container->set = set;
459 - container->value = value;
460 - sp_value = (splay_tree_value) container;
463 - sp_value = (splay_tree_value) high;
465 - /* Currently splay_tree_insert does not return any status to tell if there
467 - return splay_tree_insert (set->ranges, (splay_tree_key) low, sp_value);
470 -/* Split [low, high] to [low, address) & [address, high]. */
473 -arange_set_split_node (arange_set set, splay_tree_node node, bfd_vma address)
475 - splay_tree_node node2;
476 - arange_value_type value;
479 - low = arange_set_node_low (node);
480 - high = arange_set_node_high (set, node);
482 - BFD_ASSERT (low < address && address <= high);
484 - value = arange_set_copy_value (set, arange_set_node_value (set, node));
485 - node2 = arange_set_splay_tree_insert (set, address, high, value);
489 - arange_set_node_set_high (set, node, address - 1);
493 -static splay_tree_node
494 -arange_set_maybe_merge_with_predecessor (arange_set set, splay_tree_node node)
496 - splay_tree_node pred;
499 - low = arange_set_node_low (node);
500 - high = arange_set_node_high (set, node);
502 - pred = splay_tree_predecessor (set->ranges, low);
506 - if (arange_set_node_high (set, pred) + 1 == low
507 - && arange_set_value_equal_p (set,
508 - arange_set_node_value (set, pred),
509 - arange_set_node_value (set, node)))
511 - splay_tree_remove (set->ranges, arange_set_node_low (node));
512 - arange_set_node_set_high (set, pred, high);
513 - return arange_set_maybe_merge_with_predecessor (set, pred);
519 -/* Insert an arange [low,high] into a set. Return TRUE if and only if there
520 - is no error. Note that the address high is also included where as in
521 - DWARF2 an address range between low & high means [low,high).
523 - This only handles sets with values. For the simpler case of sets without
524 - value, it is handled in arange_set_insert(). This function is
525 - tail-recurive. It is guaranteed to terminate because it only recurses
526 - with a smaller range than it is given. */
529 -arange_set_insert_value (arange_set set,
532 - arange_value_type value)
534 - splay_tree_node succ, pred, node;
535 - bfd_vma succ_high, succ_low;
536 - arange_value_type combined, old_value;
540 - arange_set_delete_value (set, value);
544 - pred = splay_tree_predecessor (set->ranges, low);
545 - if (pred && arange_set_node_high (set, pred) >= low)
546 - arange_set_split_node (set, pred, low);
548 - node = splay_tree_lookup (set->ranges, low);
551 - /* Split node if its arange is larger than inserted arange. */
552 - if (arange_set_node_high (set, node) > high)
553 - arange_set_split_node (set, node, high + 1);
555 - old_value = arange_set_node_value (set, node);
556 - combined = arange_set_combine_value (set, old_value, value);
557 - arange_set_node_set_value (set, node, combined);
558 - node = arange_set_maybe_merge_with_predecessor (set, node);
559 - arange_set_delete_value (set, old_value);
561 - /* Insert remaining arange by tail-recursion. */
562 - if (high > arange_set_node_high (set, node))
563 - return arange_set_insert_value (set,
564 - arange_set_node_high (set, node) + 1,
568 - /* Node must cover exactly the range. */
569 - BFD_ASSERT (high == arange_set_node_high (set, node));
570 - arange_set_delete_value (set, value);
571 - succ = splay_tree_successor (set->ranges, arange_set_node_low (node));
573 - succ = arange_set_maybe_merge_with_predecessor (set, succ);
578 - succ = splay_tree_successor (set->ranges, low);
581 - succ_low = arange_set_node_low (succ);
582 - succ_high = arange_set_node_high (set, succ);
584 - if (succ_low <= high)
586 - node = arange_set_splay_tree_insert (set, low, succ_low - 1, value);
590 - /* Update set lower bound only after insertion is successful. */
591 - if (low < set->lower_bound)
592 - set->lower_bound = low;
594 - node = arange_set_maybe_merge_with_predecessor (set, node);
596 - /* Recurse to handle rest of insertion. Note that we have to copy
597 - value here since it has already been used in the node above. */
598 - return arange_set_insert_value (set, succ_low, high,
599 - arange_set_copy_value (set, value));
603 - node = arange_set_splay_tree_insert (set, low, high, value);
607 - /* Update set boundaries only after insertion is successful. */
608 - if (low < set->lower_bound)
609 - set->lower_bound = low;
610 - if (high > set->upper_bound)
611 - set->upper_bound = high;
613 - node = arange_set_maybe_merge_with_predecessor (set, node);
615 - succ = splay_tree_successor (set->ranges, arange_set_node_low (node));
617 - succ = arange_set_maybe_merge_with_predecessor (set, succ);
623 -arange_set_insert (arange_set set,
626 - arange_value_type value)
628 - splay_tree tree = set->ranges;
629 - splay_tree_node pred, succ, node = NULL;
630 - bfd_vma pred_high, node_low;
633 - return arange_set_insert_value (set, low, high, value);
638 - pred = splay_tree_predecessor (tree, low);
641 - pred_high = arange_set_node_high (set, pred);
643 - /* Nothing to be done if predecessor contains new aranges. */
644 - if (pred_high >= high)
647 - /* If we can expand predecessor, do so. Test for the case in which
648 - predecessor does not contain new arange but touches it. */
649 - if (pred_high >= low || pred_high + 1 == low)
652 - arange_set_node_set_high (set, node, high);
656 - /* Try to see if [low,something] is already in splay tree. */
659 - node = splay_tree_lookup (tree, low);
662 - /* Nothing to be done if node contains new aranges. */
663 - if (arange_set_node_high (set, node) >= high)
666 - arange_set_node_set_high (set, node, high);
672 - node = arange_set_splay_tree_insert (set, low, high, 0);
678 - && arange_set_node_low (node) <= low
679 - && arange_set_node_high (set, node) >= high);
681 - /* Update set upper and lower bounds. */
682 - if (low < set->lower_bound)
683 - set->lower_bound = low;
684 - if (high > set->upper_bound)
685 - set->upper_bound = high;
687 - /* Merge successor if it overlaps or touches node. */
688 - node_low = arange_set_node_low (node);
689 - while ((succ = splay_tree_successor (tree, node_low)) != NULL
690 - && ((arange_set_node_high (set, node) >= arange_set_node_low (succ))
691 - || (arange_set_node_high (set, node) + 1
692 - == arange_set_node_low (succ))))
694 - if (arange_set_node_high (set, succ) > high)
695 - arange_set_node_set_high (set, node, arange_set_node_high (set, succ));
696 - splay_tree_remove (tree, arange_set_node_low (succ));
701 -struct arange_set_foreach_adapter_data
705 - arange_set_foreach_fn foreach_fn;
708 -/* Adaptor to make arange_set_foreach works with splay_tree_foreach. */
711 -arange_set_foreach_adapter (splay_tree_node node, void *data)
713 - struct arange_set_foreach_adapter_data *adapter_data;
716 - adapter_data = data;
717 - set = adapter_data->set;
718 - return (adapter_data->foreach_fn) (arange_set_node_low (node),
719 - arange_set_node_high (set, node),
720 - arange_set_node_value (set, node),
721 - adapter_data->data);
724 -/* Traverse aranges in a set. For each arange in ascending order of
725 - low addresses, call foreach_fn with arange boundaries and data.
726 - If any invocation of foreach_fn returns a non-zero value, stop traversal
727 - and return that value. Otherwise, return 0. */
730 -arange_set_foreach (arange_set set,
731 - arange_set_foreach_fn foreach_fn,
734 - struct arange_set_foreach_adapter_data adapter_data;
736 - adapter_data.data = data;
737 - adapter_data.foreach_fn = foreach_fn;
738 - adapter_data.set = set;
739 - return splay_tree_foreach (set->ranges, arange_set_foreach_adapter,
740 - (void *) &adapter_data);
742 diff -urN binutils-2.18.50.0.4.org/bfd/arange-set.h binutils-2.18.50.0.4/bfd/arange-set.h
743 --- binutils-2.18.50.0.4.org/bfd/arange-set.h 2007-10-03 17:52:57.000000000 +0200
744 +++ binutils-2.18.50.0.4/bfd/arange-set.h 1970-01-01 01:00:00.000000000 +0100
746 -/* DWARF 2 Arange-Set.
747 - Copyright 2007 Free Software Foundation, Inc.
748 - Contributed by Doug Kwan, Google Inc.
750 - This file is part of BFD.
752 - This program is free software; you can redistribute it and/or modify
753 - it under the terms of the GNU General Public License as published by
754 - the Free Software Foundation; either version 3 of the License, or (at
755 - your option) any later version.
757 - This program is distributed in the hope that it will be useful, but
758 - WITHOUT ANY WARRANTY; without even the implied warranty of
759 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
760 - General Public License for more details.
762 - You should have received a copy of the GNU General Public License
763 - along with this program; if not, write to the Free Software
764 - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
765 - MA 02110-1301, USA. */
767 -/* Scalable DWARF2 Arange Set.
769 - The original code in dwarf2.c uses an unsorted singly-linked list to
770 - represent aranges in a compilation unit. Looking up for an address
771 - became very in-efficient for extremely large binaries with many
772 - compilation units, each of which having long list of aranges.
774 - The arange-set implemented here supports insertion and address
775 - containment queries for an arbitrary large collection of aranges in
776 - an efficient manner. In addition, it also supports aranges with
779 - Arange insertion with value.
781 - For valued arange-set, we need to specify 4 operations during set
782 - creation. If unspecified, reasonable default behaviours are assumed.
783 - The operations define how arange insertion merges two identical aranges
784 - with different values. The 4 operations are:
791 - When arange_set_insert () inserts an arange. It breaks the to-be-inserted
792 - arange into smaller aranges using the boundaries of any overlapping
793 - aranges as cutting point. In addition, arange_set_insert () may also
794 - splilt any existing arange that overlap the ends of the to-be-inserted
795 - arange. After such splitting of the new and existing aranges, the
796 - to-be-inserted arange becomes a collection of smaller aranges, each of
797 - which either does not overlapping with any existing arange or overlapping
798 - completely with one existing arange. While splitting aranges, values
799 - are copied using the Copy operation specified in the set.
801 - The for each smaller new arange, arange_set_insert () inserts the new
802 - arange according to these rules:
804 - 1. If there is no overlapping existing arange, insert new arange.
806 - 2. If there is an overlapping existing arange and its value equals
807 - to the inserted value according to the value equality operation
808 - of the set, do nothing.
810 - 3. If there is an overlapping existing arange and its value is not
811 - the inserted value according to the value equality operation,
812 - combine the inserted value with that of the existing arange using
813 - the value combination operation of set.
815 - If as a result of insertion, there are adjacent aranges with equal values,
816 - the adjacent aranges will be merge. */
818 -#ifndef ARANGE_SET_H
819 -#define ARANGE_SET_H
824 -/* An arange_set is a pointer to an arange_set_s struct, whose implementation
825 - is opaque to clients using the arange set. */
826 -typedef struct arange_set_s *arange_set;
829 - typedef unsigned long int arange_set_uhostptr_t;
831 - typedef unsigned long long arange_set_uhostptr_t;
834 -/* Type of value attached to an arange. This should be wide enough to be
835 - converted from and back to any type without loss. */
836 -typedef arange_set_uhostptr_t arange_value_type;
838 -/* Type of function that is used to allocate memory for an arange-set. */
839 -typedef void* (*arange_set_allocate_fn)(int, void*);
841 -/* Type of function that is used to deallocate memory of an arange-set. */
842 -typedef void (*arange_set_deallocate_fn)(void*, void*);
844 -/* Type of function that is called for each arange during a traversal of
845 - the set containing that arange. */
846 -typedef int (*arange_set_foreach_fn)(bfd_vma, bfd_vma, arange_value_type,
849 -/* Type of function that is called to test equality of range values. */
850 -typedef bfd_boolean (*arange_value_equal_fn)(arange_value_type,
851 - arange_value_type, void *);
853 -/* Type of function that is called to copy a range value. */
854 -typedef arange_value_type (*arange_value_copy_fn)(arange_value_type, void *);
856 -/* Type of function that is called to combine two range values. */
857 -typedef arange_value_type (*arange_value_combine_fn)(arange_value_type,
861 -/* Type of function that is called to delete a range value. */
862 -typedef void (*arange_value_delete_fn)(arange_value_type, void *);
864 -/* Create an arange set. Return the new set of NULL if there is any
866 -extern arange_set arange_set_new (arange_set_allocate_fn,
867 - arange_set_deallocate_fn,
869 - arange_value_equal_fn,
870 - arange_value_copy_fn,
871 - arange_value_combine_fn,
872 - arange_value_delete_fn,
875 -/* Delete an arange set. */
876 -extern void arange_set_delete (arange_set);
878 -/* Return TRUE if an only if arange set is empty. */
879 -extern bfd_boolean arange_set_empty_p (arange_set);
881 -/* Check to see if a given address is in an arange set. Return TRUE if the
882 - address is inside one of the aranges and if also low_ptr and high_ptr are
883 - not NULL, return the boundaries of the arange.
885 - If the address is not in any arange in set, return FALSE. */
886 -extern bfd_boolean arange_set_lookup_address (arange_set, bfd_vma, bfd_vma *,
887 - bfd_vma *, arange_value_type *);
889 -/* Insert an arange [low,high] into a set. Note that the address high is
890 - also included where as in DWARF2 an address range between low & high means
893 - If the set is created with no capability of storing values, the value
894 - argument is ignored. Otherwise, the value is stored in the inserted range.
895 - If there are overlapping ranges, values are combined according to
898 - If value is an object, arange_set_insert () takes ownership of that objec.
899 - Caller should not deallocate objects that are passed to arange_set_insert().
901 - Return TRUE if and only if there is no error. */
902 -extern bfd_boolean arange_set_insert (arange_set, bfd_vma, bfd_vma,
903 - arange_value_type);
905 -/* Return TRUE if and only if arange set supports arang evalues. */
906 -extern bfd_boolean arange_set_has_values_p (arange_set);
908 -/* Traverse aranges in a set. For each arange in ascending order of
909 - low addresses, call foreach_fn with arange boundaries and data.
910 - If any invocation of foreach_fn returns a non-zero value, stop traversal
911 - and return that value. Otherwise, return 0. */
912 -extern int arange_set_foreach (arange_set, arange_set_foreach_fn, void *);
914 -/* Return TRUE if two values are considered equal by the value comparison
915 - function of an arange_set. If the arange set does not support values or
916 - if it has no value equality function specified, this function performs
917 - a bit-wise comparison of its input. */
918 -extern bfd_boolean arange_set_value_equal_p (arange_set, arange_value_type,
919 - arange_value_type);
921 -/* Duplicate a value. If the arange set does not support values or if it
922 - has no value copying function specified, this function returns the input
924 -extern arange_value_type arange_set_copy_value (arange_set, arange_value_type);
926 -/* Allocate memory using the allocator of an arange set. */
927 -extern void * arange_set_allocate (arange_set, int);
929 -/* Deallocate memory allocated from arange_set_allocate (). */
930 -extern void arange_set_deallocate (arange_set, void *);
932 -#endif /* ARANGE_SET_H */
933 diff -urN binutils-2.18.50.0.4.org/bfd/dwarf2.c binutils-2.18.50.0.4/bfd/dwarf2.c
934 --- binutils-2.18.50.0.4.org/bfd/dwarf2.c 2008-02-08 17:44:55.000000000 +0100
935 +++ binutils-2.18.50.0.4/bfd/dwarf2.c 2008-02-16 21:39:52.643275415 +0100
938 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
939 - 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
940 + 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
942 Adapted from gdb/dwarf2read.c by Gavin Koch of Cygnus Solutions
947 #include "elf/dwarf2.h"
948 -#include "arange-set.h"
950 /* The data in the .debug_line statement prologue looks like this. */
953 /* Last comp unit in list above. */
954 struct comp_unit *last_comp_unit;
956 - /* Number of comp units. */
957 - int comp_unit_count;
959 /* The next unread compilation unit within the .debug_info section.
960 Zero indicates that the .debug_info section has not been loaded
961 into a buffer yet. */
962 @@ -167,33 +163,11 @@
963 #define STASH_INFO_HASH_OFF 0
964 #define STASH_INFO_HASH_ON 1
965 #define STASH_INFO_HASH_DISABLED 2
967 - /* Arange-set for fast lookup. The aranges in this set have pointers
968 - to compilation units containing them. In the unlikely case that there
969 - are multiple compilation units associated with an arange, the arange-set
970 - is a NULL pointer and we need to fall back to sequential search. */
971 - arange_set comp_unit_arange_set;
973 - /* Status of global arange set. */
974 - int arange_set_status;
975 -#define STASH_ARANGE_SET_OFF 0
976 -#define STASH_ARANGE_SET_ON 1
977 -#define STASH_ARANGE_SET_DISABLED 2
979 - /* Build a whole binary arange-set for compilation unit look-up
980 - if there are at least this many compilation units. */
981 -#define STASH_ARANGE_SET_TRIGGER 500
984 -/* Simple singly linked list for aranges. We now use a more scalable
985 - arange-set for aranges in compilation units. For functions, we still
986 - use this since it is more efficient for simple cases. */
991 - /* The lowest and highest addresses contained a compilation
992 - unit as specified in the compilation unit's header. */
997 /* Keep the bfd convenient (for memory allocation). */
1000 - /* The set of aranges in a compilation unit. */
1001 - arange_set arange_set;
1002 + /* The lowest and highest addresses contained in this compilation
1003 + unit as specified in the compilation unit header. */
1004 + struct arange arange;
1006 /* The DW_AT_name attribute (for error messages). */
1011 struct fileinfo* files;
1012 - struct line_info* last_line; /* Largest VMA. */
1013 - struct line_info* lcl_head; /* Local head; used in 'add_line_info'. */
1014 + struct line_info* last_line; /* largest VMA */
1015 + struct line_info* lcl_head; /* local head; used in 'add_line_info' */
1018 /* Remember some information about each function. If the function is
1019 @@ -906,121 +881,35 @@
1023 - struct funcinfo *prev_func; /* Pointer to previous function in list of all functions. */
1024 - struct funcinfo *caller_func; /* Pointer to function one scope higher. */
1025 - char *caller_file; /* Source location file name where caller_func inlines this func. */
1026 - int caller_line; /* Source location line number where caller_func inlines this func. */
1027 - char *file; /* Source location file name. */
1028 - int line; /* Source location line number. */
1029 + struct funcinfo *prev_func; /* Pointer to previous function in list of all functions */
1030 + struct funcinfo *caller_func; /* Pointer to function one scope higher */
1031 + char *caller_file; /* Source location file name where caller_func inlines this func */
1032 + int caller_line; /* Source location line number where caller_func inlines this func */
1033 + char *file; /* Source location file name */
1034 + int line; /* Source location line number */
1037 struct arange arange;
1038 - asection *sec; /* Where the symbol is defined. */
1039 + asection *sec; /* Where the symbol is defined */
1044 - /* Pointer to previous variable in list of all variables. */
1045 + /* Pointer to previous variable in list of all variables */
1046 struct varinfo *prev_var;
1047 - /* Source location file name. */
1048 + /* Source location file name */
1050 - /* Source location line number. */
1051 + /* Source location line number */
1056 - /* Where the symbol is defined. */
1057 + /* Where the symbol is defined */
1059 - /* Is this a stack variable? */
1060 + /* Is this a stack variable? */
1061 unsigned int stack: 1;
1066 - To handle extremely large binaries, we want to use a more efficient data
1067 - structure than a singly-linked list to represent aranges. So instead we
1068 - use an arange-set, which supports efficient insertions and queries. We
1069 - use a simple arange-set with no values attached to represent the aranges
1070 - in a compilation unit and we also use a global arange-set to store all
1071 - the aranges in all the compilation units. The global arange-set stores
1072 - values which are pointers to the compilation units.
1074 - Normally aranges in the global set do not overlap, but this can happen.
1075 - To simplify things and to prevent excessive memory usage, an arange in
1076 - the global set can only point to at most one compilation unit. In case
1077 - of an overlap, the pointer is set to NULL, meaning that there are more
1078 - than one compilation units containing that arange. Code that looks up
1079 - the global set should fall back to searching all compilation units if
1082 -/* Allocate memory for an arange set. */
1085 -dwarf2_arange_set_allocate (int size, void *data)
1087 - return bfd_alloc ((bfd *) data, size);
1090 -/* Deallocate memory of an arange set. */
1093 -dwarf2_arange_set_deallocate (void *object ATTRIBUTE_UNUSED,
1094 - void *data ATTRIBUTE_UNUSED)
1096 - /* Do nothing. Let BFD clean up when it's done. */
1099 -/* Combine two comp unit pointers. If they are the same,
1100 - return either one, otherwise return NULL. */
1102 -static arange_value_type
1103 -dwarf2_combine_arange_value (arange_value_type value1,
1104 - arange_value_type value2,
1105 - void *data ATTRIBUTE_UNUSED)
1107 - return ((value1 == value2) ? value1 : 0);
1110 -/* Create a simple arange set that does not store values. */
1113 -dwarf2_arange_set_new (bfd *abfd)
1115 - return arange_set_new (dwarf2_arange_set_allocate,
1116 - dwarf2_arange_set_deallocate,
1117 - FALSE, NULL, NULL, NULL, NULL, (void *) abfd);
1120 -/* Create an arange set that stores pointers to compilation units. */
1123 -dwarf2_arange_set_with_value_new (bfd *abfd)
1125 - return arange_set_new (dwarf2_arange_set_allocate,
1126 - dwarf2_arange_set_deallocate,
1127 - TRUE, NULL, NULL, dwarf2_combine_arange_value,
1128 - NULL, (void *) abfd);
1131 -/* Add an arange to a compilation unit. Add the arange to both the
1132 - unit's valueless arange set and the global arange set. */
1135 -dwarf2_comp_unit_arange_add (struct comp_unit *unit,
1139 - /* Add arange to unit's local arange set. */
1140 - arange_set_insert (unit->arange_set, low, high - 1, 0);
1142 - if (unit->stash->arange_set_status == STASH_ARANGE_SET_ON)
1144 - BFD_ASSERT (unit->stash->comp_unit_arange_set);
1145 - arange_set_insert (unit->stash->comp_unit_arange_set, low, high - 1,
1146 - (arange_value_type) unit);
1150 /* Return TRUE if NEW_LINE should sort after LINE. */
1152 static inline bfd_boolean
1153 @@ -1046,7 +935,7 @@
1156 bfd_size_type amt = sizeof (struct line_info);
1157 - struct line_info * info = bfd_alloc (table->abfd, amt);
1158 + struct line_info* info = bfd_alloc (table->abfd, amt);
1160 /* Set member data of 'info'. */
1161 info->address = address;
1162 @@ -1090,9 +979,9 @@
1163 table->last_line = info;
1165 else if (!table->last_line
1166 - || new_line_sorts_after (info, table->last_line))
1167 + || new_line_sorts_after (info, table->last_line))
1169 - /* Normal case: add 'info' to the beginning of the list. */
1170 + /* Normal case: add 'info' to the beginning of the list */
1171 info->prev_line = table->last_line;
1172 table->last_line = info;
1174 @@ -1112,7 +1001,7 @@
1176 /* Abnormal and hard: Neither 'last_line' nor 'lcl_head' are valid
1177 heads for 'info'. Reset 'lcl_head'. */
1178 - struct line_info* li2 = table->last_line; /* Always non-NULL. */
1179 + struct line_info* li2 = table->last_line; /* always non-NULL */
1180 struct line_info* li1 = li2->prev_line;
1183 @@ -1121,7 +1010,7 @@
1184 && new_line_sorts_after (info, li1))
1187 - li2 = li1; /* Always non-NULL. */
1188 + li2 = li1; /* always non-NULL */
1189 li1 = li1->prev_line;
1191 table->lcl_head = li2;
1192 @@ -1195,12 +1084,11 @@
1196 -arange_add (bfd *abfd, struct arange *first_arange, bfd_vma low_pc,
1198 +arange_add (bfd *abfd, struct arange *first_arange, bfd_vma low_pc, bfd_vma high_pc)
1200 struct arange *arange;
1202 - /* If the first arange is empty, use it. */
1203 + /* If the first arange is empty, use it. */
1204 if (first_arange->high == 0)
1206 first_arange->low = low_pc;
1207 @@ -1227,7 +1115,7 @@
1210 /* Need to allocate a new arange and insert it into the arange list.
1211 - Order isn't significant, so just insert after the first arange. */
1212 + Order isn't significant, so just insert after the first arange. */
1213 arange = bfd_zalloc (abfd, sizeof (*arange));
1214 arange->low = low_pc;
1215 arange->high = high_pc;
1216 @@ -1462,7 +1350,7 @@
1218 if (address > high_pc)
1220 - dwarf2_comp_unit_arange_add (unit, low_pc, high_pc);
1221 + arange_add (unit->abfd, &unit->arange, low_pc, high_pc);
1223 case DW_LNE_set_address:
1224 address = read_address (unit, line_ptr);
1225 @@ -1893,44 +1781,11 @@
1232 -/* Type of callback function used in read_rangelist below. */
1234 -typedef void (*read_rangelist_callback_t)(struct comp_unit*, bfd_vma,
1237 -/* Call back to add an arange to the old-style arange list. */
1240 -read_rangelist_insert_arange_list (struct comp_unit *unit,
1245 - arange_add (unit->abfd, (struct arange*) data, low, high);
1249 -/* Callback to add an arange in the arange set of a compilation unit. */
1252 -read_rangelist_comp_unit_arange_add (struct comp_unit *unit,
1255 - void *data ATTRIBUTE_UNUSED)
1257 - dwarf2_comp_unit_arange_add (unit, low, high);
1260 -/* Read ARANGE list of a compilation unit. For each read arange,
1261 - call the supplied callback function for further processing. */
1264 -read_rangelist (struct comp_unit *unit,
1265 - bfd_uint64_t offset,
1266 - read_rangelist_callback_t callback,
1267 - void *callback_data)
1268 +read_rangelist (struct comp_unit *unit, struct arange *arange, bfd_uint64_t offset)
1270 bfd_byte *ranges_ptr;
1271 bfd_vma base_address = unit->base_address;
1272 @@ -1966,9 +1821,7 @@
1273 if (low_pc == -1UL && high_pc != -1UL)
1274 base_address = high_pc;
1276 - /* Call callback to process new arange. */
1277 - (callback) (unit, base_address + low_pc, base_address + high_pc,
1279 + arange_add (unit->abfd, arange, base_address + low_pc, base_address + high_pc);
1283 @@ -2101,9 +1954,7 @@
1287 - read_rangelist (unit, attr.u.val,
1288 - read_rangelist_insert_arange_list,
1290 + read_rangelist (unit, &func->arange, attr.u.val);
1293 case DW_AT_decl_file:
1294 @@ -2305,7 +2156,6 @@
1295 unit->end_ptr = end_ptr;
1296 unit->stash = stash;
1297 unit->info_ptr_unit = info_ptr_unit;
1298 - unit->arange_set = dwarf2_arange_set_new (abfd);
1300 for (i = 0; i < abbrev->num_attrs; ++i)
1302 @@ -2337,14 +2187,12 @@
1306 - read_rangelist (unit, attr.u.val,
1307 - read_rangelist_comp_unit_arange_add, NULL);
1308 + read_rangelist (unit, &unit->arange, attr.u.val);
1311 case DW_AT_comp_dir:
1313 char *comp_dir = attr.u.str;
1317 /* Irix 6.2 native cc prepends <machine>.: to the compilation
1318 @@ -2362,9 +2210,10 @@
1324 - dwarf2_comp_unit_arange_add (unit, low_pc, high_pc);
1326 + arange_add (unit->abfd, &unit->arange, low_pc, high_pc);
1329 unit->first_child_die_ptr = info_ptr;
1331 @@ -2379,7 +2228,21 @@
1333 comp_unit_contains_address (struct comp_unit *unit, bfd_vma addr)
1335 - return arange_set_lookup_address (unit->arange_set, addr, NULL, NULL, NULL);
1336 + struct arange *arange;
1341 + arange = &unit->arange;
1344 + if (addr >= arange->low && addr < arange->high)
1346 + arange = arange->next;
1353 /* If UNIT contains ADDR, set the output parameters to the values for
1354 @@ -2951,107 +2814,6 @@
1355 filename_ptr, linenumber_ptr);
1360 - struct dwarf2_debug * stash;
1362 - struct comp_unit * unit;
1363 -} stash_copy_local_aranges_data_t;
1366 -stash_copy_local_aranges (bfd_vma low,
1368 - arange_value_type data ATTRIBUTE_UNUSED,
1371 - bfd_boolean status;
1373 - stash_copy_local_aranges_data_t *copy_data = info;
1374 - status = arange_set_insert (copy_data->set, low, high,
1375 - (arange_value_type) copy_data->unit);
1377 - return status ? 0 : 1;
1381 -stash_maybe_enable_arange_set (bfd *abfd, struct dwarf2_debug *stash)
1383 - struct comp_unit *unit;
1384 - stash_copy_local_aranges_data_t copy_data;
1386 - if (stash->arange_set_status != STASH_ARANGE_SET_OFF)
1389 - if (stash->comp_unit_count < STASH_ARANGE_SET_TRIGGER)
1392 - if (stash->comp_unit_arange_set == NULL)
1394 - stash->comp_unit_arange_set =
1395 - dwarf2_arange_set_with_value_new (abfd);
1396 - if (!stash->comp_unit_arange_set)
1398 - stash->arange_set_status = STASH_ARANGE_SET_DISABLED;
1403 - copy_data.stash = stash;
1404 - copy_data.set = stash->comp_unit_arange_set;
1405 - for (unit = stash->all_comp_units; unit; unit = unit->next_unit)
1407 - copy_data.unit = unit;
1408 - if (arange_set_foreach (unit->arange_set, stash_copy_local_aranges,
1411 - stash->arange_set_status = STASH_ARANGE_SET_DISABLED;
1415 - stash->arange_set_status = STASH_ARANGE_SET_ON;
1419 -/* Find the nearest line to a given address and record filename,
1420 - function name and line number if found. Return TRUE if a line is
1421 - found or FALSE otherwise. */
1423 -static bfd_boolean ATTRIBUTE_UNUSED
1424 -stash_find_nearest_line_fast (struct dwarf2_debug *stash,
1426 - const char **filename_ptr,
1427 - const char **functionname_ptr,
1428 - unsigned int *linenumber_ptr)
1430 - arange_value_type value;
1431 - struct comp_unit *unit;
1433 - /* Try looking up global arange set first. */
1434 - if (stash->arange_set_status == STASH_ARANGE_SET_ON
1435 - && arange_set_lookup_address (stash->comp_unit_arange_set, addr, NULL,
1438 - if ((unit = (struct comp_unit *) value) != NULL)
1439 - /* There is only one compilation unit containing this address. */
1440 - return comp_unit_find_nearest_line (unit, addr, filename_ptr,
1441 - functionname_ptr, linenumber_ptr,
1445 - /* The arange set is not available or there are multiple compilation
1446 - units containing this address. Search all compilation units. */
1447 - for (unit = stash->all_comp_units; unit; unit = unit->next_unit)
1449 - if (comp_unit_contains_address (unit, addr)
1450 - && comp_unit_find_nearest_line (unit, addr, filename_ptr,
1452 - linenumber_ptr, stash))
1459 /* Find the source code location of SYMBOL. If SYMBOL is NULL
1460 then find the nearest source code location corresponding to
1461 the address SECTION + OFFSET.
1462 @@ -3306,13 +3068,17 @@
1466 - if (stash->arange_set_status == STASH_ARANGE_SET_OFF)
1467 - stash_maybe_enable_arange_set (abfd, stash);
1469 - found = stash_find_nearest_line_fast (stash, addr, filename_ptr,
1470 - functionname_ptr, linenumber_ptr);
1473 + for (each = stash->all_comp_units; each; each = each->next_unit)
1475 + found = (comp_unit_contains_address (each, addr)
1476 + && comp_unit_find_nearest_line (each, addr,
1486 /* The DWARF2 spec says that the initial length field, and the
1487 @@ -3386,22 +3152,22 @@
1489 each->next_unit = stash->all_comp_units;
1490 stash->all_comp_units = each;
1491 - stash->comp_unit_count++;
1493 /* DW_AT_low_pc and DW_AT_high_pc are optional for
1494 - compilation units. If we don't have them, we need to
1495 - consult the line info table to see if a compilation unit
1496 - contains the given address. */
1497 + compilation units. If we don't have them (i.e.,
1498 + unit->high == 0), we need to consult the line info
1499 + table to see if a compilation unit contains the given
1502 found = (((symbol->flags & BSF_FUNCTION) == 0
1503 - || arange_set_empty_p (each->arange_set)
1504 + || each->arange.high == 0
1505 || comp_unit_contains_address (each, addr))
1506 && comp_unit_find_line (each, symbol, addr,
1511 - found = ((arange_set_empty_p (each->arange_set)
1512 + found = ((each->arange.high == 0
1513 || comp_unit_contains_address (each, addr))
1514 && comp_unit_find_nearest_line (each, addr,
1516 diff -urN binutils-2.18.50.0.4.org/bfd/Makefile.am binutils-2.18.50.0.4/bfd/Makefile.am
1517 --- binutils-2.18.50.0.4.org/bfd/Makefile.am 2008-02-08 17:44:09.000000000 +0100
1518 +++ binutils-2.18.50.0.4/bfd/Makefile.am 2008-02-16 21:39:52.643275415 +0100
1520 format.lo init.lo libbfd.lo opncls.lo reloc.lo \
1521 section.lo syms.lo targets.lo hash.lo linker.lo \
1522 srec.lo binary.lo tekhex.lo ihex.lo stabs.lo stab-syms.lo \
1523 - merge.lo dwarf2.lo simple.lo arange-set.lo
1524 + merge.lo dwarf2.lo simple.lo
1526 BFD64_LIBS = archive64.lo
1529 format.c init.c libbfd.c opncls.c reloc.c \
1530 section.c syms.c targets.c hash.c linker.c \
1531 srec.c binary.c tekhex.c ihex.c stabs.c stab-syms.c \
1532 - merge.c dwarf2.c simple.c arange-set.c
1533 + merge.c dwarf2.c simple.c
1535 BFD64_LIBS_CFILES = archive64.c
1539 ## This is a list of all .h files which are in the source tree.
1541 - arange-set.h aout-target.h aoutf1.h aoutx.h coffcode.h coffswap.h \
1542 - ecoffswap.h elf-bfd.h elf-hppa.h elf32-hppa.h \
1543 + aout-target.h aoutf1.h aoutx.h coffcode.h coffswap.h ecoffswap.h \
1544 + elf-bfd.h elf-hppa.h elf32-hppa.h \
1545 elf64-hppa.h elfcode.h elfcore.h \
1546 freebsd.h genlink.h go32stub.h \
1547 libaout.h libbfd.h libcoff.h libecoff.h libhppa.h libieee.h \
1548 @@ -1049,11 +1049,9 @@
1549 dwarf2.lo: dwarf2.c $(INCDIR)/filenames.h $(INCDIR)/libiberty.h \
1550 $(INCDIR)/hashtab.h elf-bfd.h $(INCDIR)/elf/common.h \
1551 $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h $(INCDIR)/bfdlink.h \
1552 - $(INCDIR)/elf/dwarf2.h arange-set.h
1553 + $(INCDIR)/elf/dwarf2.h
1554 simple.lo: simple.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
1556 -arange-set.lo: arange-set.c $(INCDIR)/filenames.h $(INCDIR)/libiberty.h \
1557 - $(INCDIR)/hashtab.h arange-set.h $(INCDIR)/splay-tree.h
1558 archive64.lo: archive64.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
1560 cpu-alpha.lo: cpu-alpha.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
1561 diff -urN binutils-2.18.50.0.4.org/bfd/po/SRC-POTFILES.in binutils-2.18.50.0.4/bfd/po/SRC-POTFILES.in
1562 --- binutils-2.18.50.0.4.org/bfd/po/SRC-POTFILES.in 2007-11-03 21:40:36.000000000 +0100
1563 +++ binutils-2.18.50.0.4/bfd/po/SRC-POTFILES.in 2008-02-16 21:39:52.643275415 +0100