Add block range data structure for blocks with non-contiguous address ranges
authorKevin Buettner <kevinb@redhat.com>
Sat, 25 Aug 2018 05:22:45 +0000 (22:22 -0700)
committerKevin Buettner <kevinb@redhat.com>
Sat, 25 Aug 2018 05:23:59 +0000 (22:23 -0700)
commit76dae9eb044ab86c242724968f541ee6702851af
tree10c6f5f5f7b35b5fb8de2e284e5a5fe102c70344
parent35f0c5a6147601fda254291153f202bbab53d781
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.
gdb/ChangeLog
gdb/block.c
gdb/block.h