aboutsummaryrefslogtreecommitdiff
path: root/bfd/arange-set.h
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2007-09-21 16:16:18 +0000
committerNick Clifton <nickc@redhat.com>2007-09-21 16:16:18 +0000
commit4ab2002928d0ba68074601d8ac4ea920c916a46c (patch)
tree2fb5255520717f76c1be05003e7338e760f3b37a /bfd/arange-set.h
parentab2e1992cfa13130abcafd4ca81cdb4a81b554cd (diff)
downloadgdb-4ab2002928d0ba68074601d8ac4ea920c916a46c.zip
gdb-4ab2002928d0ba68074601d8ac4ea920c916a46c.tar.gz
gdb-4ab2002928d0ba68074601d8ac4ea920c916a46c.tar.bz2
* Makefile.am (BFD32_LIBS): Add arange-set.lo.
(BFD32_LIBS_CFILES): Add arange-set.c. (SOURCE_HFILES): Add arange-set.h (dwarf2.lo): Add dependency upon arange-set.h. (arange-set.lo): New target. * Makefile.in: Regenerate. * arange-set.c: New file. * arange-set.h: New file. * dwarf2.c: Include arange-set.h. (struct dwarf2_debug) Add new fields comp_unit_count and comp_unit_arange_set. (struct comp_unit) Replace field arange with a new field arange_set. (dwarf2_arange_set_allocate, dwarf2_arange_set_deallocate, (dwarf2_combine_arange_value, dwarf2_arange_set_new, (dwarf2_arange_set_with_value_new, dwarf2_comp_unit_arange_add): New functions to utilize arange set in dwarf2.c. (arange_add): Formatting change for a line longer than 80 characters. (decode_line_info): Replace call target arange_add with (dwarf2_comp_unit_arange_add. (read_rangelist_insert_arange_list, (read_rangelist_comp_unit_arange_add): New functions used as callbacks for read_rangelist. (read_rangelist): Change interface to accept a callback and data to allow caller to select the action peformed on a new range list read. (scan_unit_for_symbols): Use new interface of read_rangelist. (parse_comp_unit): Create an arange set for each new comp unit. Use new interface of read_rangelist. Replace call to arange_add with that to dwarf2_comp_unit_arange_add. (comp_unit_contains_address): Replace sequential search with a call to arange_set_lookup_address, which can handles large set efficiently. (stash_copy_local_aranges, stash_maybe_enable_arange_set, (stash_find_nearest_line_fast): New functions maintaining and using a valued global arange set for all compilation units to speed up bfd_dwarf2_find_nearest_line. (find_line): Use global arange set. Replace sequential search over all compilation units with a call to stash_find_nearest_line_fast. Add book keeping to count number of compilation units. Replace empty arange list test with a call to arange_set_empty_p.
Diffstat (limited to 'bfd/arange-set.h')
-rw-r--r--bfd/arange-set.h187
1 files changed, 187 insertions, 0 deletions
diff --git a/bfd/arange-set.h b/bfd/arange-set.h
new file mode 100644
index 0000000..54f61a8
--- /dev/null
+++ b/bfd/arange-set.h
@@ -0,0 +1,187 @@
+/* DWARF 2 Arange-Set.
+ Copyright 2007 Free Software Foundation, Inc.
+ Contributed by Doug Kwan, Google Inc.
+
+ This file is part of BFD.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+/* Scalable DWARF2 Arange Set.
+
+ The original code in dwarf2.c uses an unsorted singly-linked list to
+ represent aranges in a compilation unit. Looking up for an address
+ became very in-efficient for extremely large binaries with many
+ compilation units, each of which having long list of aranges.
+
+ The arange-set implemented here supports insertion and address
+ containment queries for an arbitrary large collection of aranges in
+ an efficient manner. In addition, it also supports aranges with
+ values.
+
+ Arange insertion with value.
+
+ For valued arange-set, we need to specify 4 operations during set
+ creation. If unspecified, reasonable default behaviours are assumed.
+ The operations define how arange insertion merges two identical aranges
+ with different values. The 4 operations are:
+
+ Equality
+ Copy
+ Combination
+ Deletion
+
+ When arange_set_insert () inserts an arange. It breaks the to-be-inserted
+ arange into smaller aranges using the boundaries of any overlapping
+ aranges as cutting point. In addition, arange_set_insert () may also
+ splilt any existing arange that overlap the ends of the to-be-inserted
+ arange. After such splitting of the new and existing aranges, the
+ to-be-inserted arange becomes a collection of smaller aranges, each of
+ which either does not overlapping with any existing arange or overlapping
+ completely with one existing arange. While splitting aranges, values
+ are copied using the Copy operation specified in the set.
+
+ The for each smaller new arange, arange_set_insert () inserts the new
+ arange according to these rules:
+
+ 1. If there is no overlapping existing arange, insert new arange.
+
+ 2. If there is an overlapping existing arange and its value equals
+ to the inserted value according to the value equality operation
+ of the set, do nothing.
+
+ 3. If there is an overlapping existing arange and its value is not
+ the inserted value according to the value equality operation,
+ combine the inserted value with that of the existing arange using
+ the value combination operation of set.
+
+ If as a result of insertion, there are adjacent aranges with equal values,
+ the adjacent aranges will be merge. */
+
+#ifndef ARANGE_SET_H
+#define ARANGE_SET_H
+
+#include "sysdep.h"
+#include "bfd.h"
+
+/* An arange_set is a pointer to an arange_set_s struct, whose implementation
+ is opaque to clients using the arange set. */
+typedef struct arange_set_s *arange_set;
+
+#ifndef _WIN64
+ typedef unsigned long int arange_set_uhostptr_t;
+#else
+ typedef unsigned long long arange_set_uhostptr_t;
+#endif
+
+/* Type of value attached to an arange. This should be wide enough to be
+ converted from and back to any type without loss. */
+typedef arange_set_uhostptr_t arange_value_type;
+
+/* Type of function that is used to allocate memory for an arange-set. */
+typedef void* (*arange_set_allocate_fn)(int, void*);
+
+/* Type of function that is used to deallocate memory of an arange-set. */
+typedef void (*arange_set_deallocate_fn)(void*, void*);
+
+/* Type of function that is called for each arange during a traversal of
+ the set containing that arange. */
+typedef int (*arange_set_foreach_fn)(bfd_vma, bfd_vma, arange_value_type,
+ void *);
+
+/* Type of function that is called to test equality of range values. */
+typedef bfd_boolean (*arange_value_equal_fn)(arange_value_type,
+ arange_value_type, void *);
+
+/* Type of function that is called to copy a range value. */
+typedef arange_value_type (*arange_value_copy_fn)(arange_value_type, void *);
+
+/* Type of function that is called to combine two range values. */
+typedef arange_value_type (*arange_value_combine_fn)(arange_value_type,
+ arange_value_type,
+ void *);
+
+/* Type of function that is called to delete a range value. */
+typedef void (*arange_value_delete_fn)(arange_value_type, void *);
+
+/* Create an arange set. Return the new set of NULL if there is any
+ error. */
+extern arange_set arange_set_new (arange_set_allocate_fn,
+ arange_set_deallocate_fn,
+ bfd_boolean,
+ arange_value_equal_fn,
+ arange_value_copy_fn,
+ arange_value_combine_fn,
+ arange_value_delete_fn,
+ void *);
+
+/* Delete an arange set. */
+extern void arange_set_delete (arange_set);
+
+/* Return TRUE if an only if arange set is empty. */
+extern bfd_boolean arange_set_empty_p (arange_set);
+
+/* Check to see if a given address is in an arange set. Return TRUE if the
+ address is inside one of the aranges and if also low_ptr and high_ptr are
+ not NULL, return the boundaries of the arange.
+
+ If the address is not in any arange in set, return FALSE. */
+extern bfd_boolean arange_set_lookup_address (arange_set, bfd_vma, bfd_vma *,
+ bfd_vma *, arange_value_type *);
+
+/* Insert an arange [low,high] into a set. Note that the address high is
+ also included where as in DWARF2 an address range between low & high means
+ [low,high).
+
+ If the set is created with no capability of storing values, the value
+ argument is ignored. Otherwise, the value is stored in the inserted range.
+ If there are overlapping ranges, values are combined according to
+ value_combine_fn.
+
+ If value is an object, arange_set_insert () takes ownership of that objec.
+ Caller should not deallocate objects that are passed to arange_set_insert().
+
+ Return TRUE if and only if there is no error. */
+extern bfd_boolean arange_set_insert (arange_set, bfd_vma, bfd_vma,
+ arange_value_type);
+
+/* Return TRUE if and only if arange set supports arang evalues. */
+extern bfd_boolean arange_set_has_values_p (arange_set);
+
+/* Traverse aranges in a set. For each arange in ascending order of
+ low addresses, call foreach_fn with arange boundaries and data.
+ If any invocation of foreach_fn returns a non-zero value, stop traversal
+ and return that value. Otherwise, return 0. */
+extern int arange_set_foreach (arange_set, arange_set_foreach_fn, void *);
+
+/* Return TRUE if two values are considered equal by the value comparison
+ function of an arange_set. If the arange set does not support values or
+ if it has no value equality function specified, this function performs
+ a bit-wise comparison of its input. */
+extern bfd_boolean arange_set_value_equal_p (arange_set, arange_value_type,
+ arange_value_type);
+
+/* Duplicate a value. If the arange set does not support values or if it
+ has no value copying function specified, this function returns the input
+ value. */
+extern arange_value_type arange_set_copy_value (arange_set, arange_value_type);
+
+/* Allocate memory using the allocator of an arange set. */
+extern void * arange_set_allocate (arange_set, int);
+
+/* Deallocate memory allocated from arange_set_allocate (). */
+extern void arange_set_deallocate (arange_set, void *);
+
+#endif /* ARANGE_SET_H */