diff options
-rw-r--r-- | gdb/ChangeLog | 10 | ||||
-rw-r--r-- | gdb/block.c | 21 | ||||
-rw-r--r-- | gdb/block.h | 85 |
3 files changed, 116 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index cdc31f8ca7b..82eaa824556 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +2018-08-23 Kevin Buettner <kevinb@redhat.com> + + * 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. + 2018-08-23 Xavier Roirand <roirand@adacore.com> * machoread.c (macho_symfile_read_all_oso): Remove uneeded 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; +} + diff --git a/gdb/block.h b/gdb/block.h index ff127256ad7..0050eacf8dc 100644 --- a/gdb/block.h +++ b/gdb/block.h @@ -31,6 +31,37 @@ struct using_direct; struct obstack; struct addrmap; +/* Blocks can occupy non-contiguous address ranges. When this occurs, + startaddr and endaddr within struct block (still) specify the lowest + and highest addresses of all ranges, but each individual range is + specified by the addresses in struct blockrange. */ + +struct blockrange +{ + blockrange (CORE_ADDR startaddr_, CORE_ADDR endaddr_) + : startaddr (startaddr_), + endaddr (endaddr_) + { + } + + /* Lowest address in this range. */ + + CORE_ADDR startaddr; + + /* One past the highest address in the range. */ + + CORE_ADDR endaddr; +}; + +/* Two or more non-contiguous ranges in the same order as that provided + via the debug info. */ + +struct blockranges +{ + int nranges; + struct blockrange range[1]; +}; + /* All of the name-scope contours of the program are represented by `struct block' objects. All of these objects are pointed to by the blockvector. @@ -86,6 +117,12 @@ struct block using directives and the current namespace scope. */ struct block_namespace_info *namespace_info; + + /* Address ranges for blocks with non-contiguous ranges. If this + is NULL, then there is only one range which is specified by + startaddr and endaddr above. */ + + struct blockranges *ranges; }; /* The global block is singled out so that we can provide a back-link @@ -109,6 +146,49 @@ struct global_block #define BLOCK_DICT(bl) (bl)->dict #define BLOCK_NAMESPACE(bl) (bl)->namespace_info +/* Accessor for ranges field within block BL. */ + +#define BLOCK_RANGES(bl) (bl)->ranges + +/* Number of ranges within a block. */ + +#define BLOCK_NRANGES(bl) (bl)->ranges->nranges + +/* Access range array for block BL. */ + +#define BLOCK_RANGE(bl) (bl)->ranges->range + +/* Are all addresses within a block contiguous? */ + +#define BLOCK_CONTIGUOUS_P(bl) (BLOCK_RANGES (bl) == nullptr \ + || BLOCK_NRANGES (bl) <= 1) + +/* Obtain the start address of the Nth range for block BL. */ + +#define BLOCK_RANGE_START(bl,n) (BLOCK_RANGE (bl)[n].startaddr) + +/* Obtain the end address of the Nth range for block BL. */ + +#define BLOCK_RANGE_END(bl,n) (BLOCK_RANGE (bl)[n].endaddr) + +/* Define the "entry pc" for a block BL to be the lowest (start) address + for the block when all addresses within the block are contiguous. If + non-contiguous, then use the start address for the first range in the + block. + + At the moment, this almost matches what DWARF specifies as the entry + pc. (The missing bit is support for DW_AT_entry_pc which should be + preferred over range data and the low_pc.) + + Once support for DW_AT_entry_pc is added, I expect that an entry_pc + field will be added to one of these data structures. Once that's done, + the entry_pc field can be set from the dwarf reader (and other readers + too). BLOCK_ENTRY_PC can then be redefined to be less DWARF-centric. */ + +#define BLOCK_ENTRY_PC(bl) (BLOCK_CONTIGUOUS_P (bl) \ + ? BLOCK_START (bl) \ + : BLOCK_RANGE_START (bl,0)) + struct blockvector { /* Number of blocks in the list. */ @@ -322,4 +402,9 @@ extern int block_find_non_opaque_type_preferred (struct symbol *sym, (sym) != NULL; \ (sym) = block_iter_match_next ((name), &(iter))) +/* Given a vector of pairs, allocate and build an obstack allocated + blockranges struct for a block. */ +struct blockranges *make_blockranges (struct objfile *objfile, + const std::vector<blockrange> &rangevec); + #endif /* BLOCK_H */ |