Support lexical blocks and function bodies that occupy
non-contiguous address ranges. * addrmap.c, addrmap.h: New files. * block.h (struct addrmap): New forward declaration. (struct blockvector): New member, 'map'. (BLOCKVECTOR_MAP): New accessor macro. * block.c: #include "addrmap.h" (blockvector_for_pc_sect): If the blockvector we've found has an address map, use it instead of searching the blocks. * buildsym.c: #include "addrmap.h" (pending_addrmap_obstack, pending_addrmap_interesting): New static variables. (really_free_pendings): If we have a pending addrmap, free it too. (record_block_range): New function. (make_blockvector): If we have an interesting pending addrmap, record it in the new blockvector. (start_symtab, buildsym_init): Assert that there is no pending addrmap now; we should have cleaned up any addrmaps we'd built previously. (end_symtab): If there is a pending addrmap left over that didn't get included in the blockvector, free it. * buildsym.h (struct addrmap): New forward declaration. (record_block_range): New prototype. * objfiles.c: #include "addrmap.h". (objfile_relocate): Relocate the blockvector's address map, if present. * dwarf2read.c (dwarf2_record_block_ranges): New function. (read_func_scope, read_lexical_block_scope): Call it. * Makefile.in (SFILES): Add addrmap.c. (addrmap_h): New header dependency variable. (COMMON_OBS): Add addrmap.o. (addrmap.o): New rule.l (block.o, objfiles.o, buildsym.o): Depend on $(addrmap_h). * block.c (blockvector_for_pc, blockvector_for_pc_sect): Return a pointer to the block, not its index in the blockvector. (block_for_pc_sect): Use the returned block, instead of looking it up ourselves. * block.h (blockvector_for_pc, blockvector_for_pc_sect): Update declarations. * breakpoint.c (resolve_sal_pc): Use returned block, instead of looking it up ourselves. * stack.c (print_frame_label_vars): Disable function, which depends on the block's index. * buildsym.c (finish_block): Return the block we've built. * buildsym.h (finish_block): Update prototype. * defs.h (CORE_ADDR_MAX): New constant.
This commit is contained in:
parent
c420411fe8
commit
801e3a5b56
13 changed files with 947 additions and 32 deletions
|
@ -43,6 +43,7 @@
|
|||
#include "block.h"
|
||||
#include "cp-support.h"
|
||||
#include "dictionary.h"
|
||||
#include "addrmap.h"
|
||||
|
||||
/* Ask buildsym.h to define the vars it normally declares `extern'. */
|
||||
#define EXTERN
|
||||
|
@ -67,6 +68,23 @@ static struct pending *free_pendings;
|
|||
otherwise empty symtab from being tossed. */
|
||||
|
||||
static int have_line_numbers;
|
||||
|
||||
/* The mutable address map for the compilation unit whose symbols
|
||||
we're currently reading. The symtabs' shared blockvector will
|
||||
point to a fixed copy of this. */
|
||||
static struct addrmap *pending_addrmap;
|
||||
|
||||
/* The obstack on which we allocate pending_addrmap.
|
||||
If pending_addrmap is NULL, this is uninitialized; otherwise, it is
|
||||
initialized (and holds pending_addrmap). */
|
||||
static struct obstack pending_addrmap_obstack;
|
||||
|
||||
/* Non-zero if we recorded any ranges in the addrmap that are
|
||||
different from those in the blockvector already. We set this to
|
||||
zero when we start processing a symfile, and if it's still zero at
|
||||
the end, then we just toss the addrmap. */
|
||||
static int pending_addrmap_interesting;
|
||||
|
||||
|
||||
static int compare_line_numbers (const void *ln1p, const void *ln2p);
|
||||
|
||||
|
@ -195,6 +213,12 @@ really_free_pendings (void *dummy)
|
|||
|
||||
if (pending_macros)
|
||||
free_macro_table (pending_macros);
|
||||
|
||||
if (pending_addrmap)
|
||||
{
|
||||
obstack_free (&pending_addrmap_obstack, NULL);
|
||||
pending_addrmap = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* This function is called to discard any pending blocks. */
|
||||
|
@ -211,7 +235,7 @@ free_pending_blocks (void)
|
|||
the order the symbols have in the list (reversed from the input
|
||||
file). Put the block on the list of pending blocks. */
|
||||
|
||||
void
|
||||
struct block *
|
||||
finish_block (struct symbol *symbol, struct pending **listhead,
|
||||
struct pending_block *old_blocks,
|
||||
CORE_ADDR start, CORE_ADDR end,
|
||||
|
@ -423,6 +447,8 @@ finish_block (struct symbol *symbol, struct pending **listhead,
|
|||
}
|
||||
|
||||
record_pending_block (objfile, block, opblock);
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
|
||||
|
@ -454,6 +480,38 @@ record_pending_block (struct objfile *objfile, struct block *block,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* Record that the range of addresses from START to END_INCLUSIVE
|
||||
(inclusive, like it says) belongs to BLOCK. BLOCK's start and end
|
||||
addresses must be set already. You must apply this function to all
|
||||
BLOCK's children before applying it to BLOCK.
|
||||
|
||||
If a call to this function complicates the picture beyond that
|
||||
already provided by BLOCK_START and BLOCK_END, then we create an
|
||||
address map for the block. */
|
||||
void
|
||||
record_block_range (struct block *block,
|
||||
CORE_ADDR start, CORE_ADDR end_inclusive)
|
||||
{
|
||||
/* If this is any different from the range recorded in the block's
|
||||
own BLOCK_START and BLOCK_END, then note that the address map has
|
||||
become interesting. Note that even if this block doesn't have
|
||||
any "interesting" ranges, some later block might, so we still
|
||||
need to record this block in the addrmap. */
|
||||
if (start != BLOCK_START (block)
|
||||
|| end_inclusive + 1 != BLOCK_END (block))
|
||||
pending_addrmap_interesting = 1;
|
||||
|
||||
if (! pending_addrmap)
|
||||
{
|
||||
obstack_init (&pending_addrmap_obstack);
|
||||
pending_addrmap = addrmap_create_mutable (&pending_addrmap_obstack);
|
||||
}
|
||||
|
||||
addrmap_set_empty (pending_addrmap, start, end_inclusive, block);
|
||||
}
|
||||
|
||||
|
||||
static struct blockvector *
|
||||
make_blockvector (struct objfile *objfile)
|
||||
{
|
||||
|
@ -486,6 +544,14 @@ make_blockvector (struct objfile *objfile)
|
|||
|
||||
free_pending_blocks ();
|
||||
|
||||
/* If we needed an address map for this symtab, record it in the
|
||||
blockvector. */
|
||||
if (pending_addrmap && pending_addrmap_interesting)
|
||||
BLOCKVECTOR_MAP (blockvector)
|
||||
= addrmap_create_fixed (pending_addrmap, &objfile->objfile_obstack);
|
||||
else
|
||||
BLOCKVECTOR_MAP (blockvector) = 0;
|
||||
|
||||
/* Some compilers output blocks in the wrong order, but we depend on
|
||||
their being in the right order so we can binary search. Check the
|
||||
order and moan about it. */
|
||||
|
@ -808,6 +874,9 @@ start_symtab (char *name, char *dirname, CORE_ADDR start_addr)
|
|||
}
|
||||
context_stack_depth = 0;
|
||||
|
||||
/* We shouldn't have any address map at this point. */
|
||||
gdb_assert (! pending_addrmap);
|
||||
|
||||
/* Set up support for C++ namespace support, in case we need it. */
|
||||
|
||||
cp_initialize_namespace ();
|
||||
|
@ -1083,6 +1152,11 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
|
|||
last_source_file = NULL;
|
||||
current_subfile = NULL;
|
||||
pending_macros = NULL;
|
||||
if (pending_addrmap)
|
||||
{
|
||||
obstack_free (&pending_addrmap_obstack, NULL);
|
||||
pending_addrmap = NULL;
|
||||
}
|
||||
|
||||
return symtab;
|
||||
}
|
||||
|
@ -1196,6 +1270,10 @@ buildsym_init (void)
|
|||
global_symbols = NULL;
|
||||
pending_blocks = NULL;
|
||||
pending_macros = NULL;
|
||||
|
||||
/* We shouldn't have any address map at this point. */
|
||||
gdb_assert (! pending_addrmap);
|
||||
pending_addrmap_interesting = 0;
|
||||
}
|
||||
|
||||
/* Initialize anything that needs initializing when a completely new
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue