summaryrefslogtreecommitdiff
path: root/gdb/block.c
diff options
context:
space:
mode:
authorKevin Buettner <kevinb@redhat.com>2018-08-23 16:00:48 -0700
committerKevin Buettner <kevinb@redhat.com>2018-08-23 16:10:52 -0700
commit26457a9cf3c0ae49a3a2d0d0d0f25e2658b5f0d4 (patch)
tree1a5e81cb2b0399522453c03f3b4f1b39ca3f46dc /gdb/block.c
parentbfb218e3e404a6168888df51c03827eacde9ceea (diff)
downloadbinutils-gdb-26457a9cf3c0ae49a3a2d0d0d0f25e2658b5f0d4.tar.gz
Add block range data structure for blocks with non-contiguous address ranges
This patch does the following: - Introduces a block range data structure which is accessed via a new field in struct block. - Defines several macros for accessing block ranges. - Defines a new function, make_blockrange, which is responsible for creating the new data structure. It should be noted that some support for non-contiguous ranges already existed in GDB in the form of blockvector addrmaps. This support allowed GDB to quickly find a block containing a particular address even when the block consists of non-contiguous addresses. See find_block_in_blockvector() in block.c, dwarf2_record_block_ranges() in dwarf2read.c, and record_block_range() in buildsym.c. Addrmaps do not provide a convenient way to examine address ranges associated with a particular block. This data structure (and its interface) is set up for quickly finding the value (which in this case is a block) associated with a particular address. The interface does not include a method for doing a reverse mapping from blocks to addresses. A linear time mapping might be attempted via use of the addrmap's foreach method, but this is not as straightforward as it might first appear due to the fact that blocks corresponding to inline function instances and lexical blocks w/ variables end up getting interspersed in in the set of transitions. Note: If this approach is deemed to be too expensive in terms of space, an alternate approach might be to attempt the linear time mapping noted above. find_pc_partial_function() needs to be able to quickly know whether there are discontiguous ranges, so a flag for this property would have to be added to struct block. Also integral to this set of changes is the concept of an "entry pc" which might be different from the block's start address. An entry_pc field would also need to be added to struct block. This does not result in any space savings in struct block though since the space for the flag and entry_pc use more space than the blockranges struct pointer that I've added. There would, however, be some space savings due to the fact that the new data structures that I've added for this patch would not need to be allocated. (I happen to like the approach I've come up with, but I wanted to mention another possibility just in case someone does not.) gdb/ChangeLog: * block.h (blockrange, blockranges): New struct declarations. (struct block): Add new field named `ranges'. (BLOCK_RANGES, BLOCK_NRANGES, BLOCK_RANGE, BLOCK_CONTIGUOUS_P) (BLOCK_RANGE_START, BLOCK_RANGE_END, BLOCK_ENTRY_PC): New macros for accessing ranges in struct block. (make_blockranges): New declaration. block.c (make_blockranges): New function.
Diffstat (limited to 'gdb/block.c')
-rw-r--r--gdb/block.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/gdb/block.c b/gdb/block.c
index f26d169a7d5..85e6c618d7c 100644
--- a/gdb/block.c
+++ b/gdb/block.c
@@ -807,3 +807,24 @@ block_find_non_opaque_type_preferred (struct symbol *sym, void *data)
*best = sym;
return 0;
}
+
+/* See block.h. */
+
+struct blockranges *
+make_blockranges (struct objfile *objfile,
+ const std::vector<blockrange> &rangevec)
+{
+ struct blockranges *blr;
+ size_t n = rangevec.size();
+
+ blr = (struct blockranges *)
+ obstack_alloc (&objfile->objfile_obstack,
+ sizeof (struct blockranges)
+ + (n - 1) * sizeof (struct blockrange));
+
+ blr->nranges = n;
+ for (int i = 0; i < n; i++)
+ blr->range[i] = rangevec[i];
+ return blr;
+}
+