aboutsummaryrefslogtreecommitdiff
path: root/gdb/buildsym.c
diff options
context:
space:
mode:
authorJim Blandy <jimb@codesourcery.com>2007-12-04 23:43:57 +0000
committerJim Blandy <jimb@codesourcery.com>2007-12-04 23:43:57 +0000
commit801e3a5b5681c44b2fec1b392dddec386870647c (patch)
treefc5540169fef73f5721542765234f47023c7763d /gdb/buildsym.c
parentc420411fe81ad583b2154fd9338fd0076761d99d (diff)
downloadgdb-801e3a5b5681c44b2fec1b392dddec386870647c.zip
gdb-801e3a5b5681c44b2fec1b392dddec386870647c.tar.gz
gdb-801e3a5b5681c44b2fec1b392dddec386870647c.tar.bz2
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.
Diffstat (limited to 'gdb/buildsym.c')
-rw-r--r--gdb/buildsym.c80
1 files changed, 79 insertions, 1 deletions
diff --git a/gdb/buildsym.c b/gdb/buildsym.c
index 0bba94a..42fc78e 100644
--- a/gdb/buildsym.c
+++ b/gdb/buildsym.c
@@ -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