aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Kingdon <jkingdon@engr.sgi.com>1993-09-08 15:51:39 +0000
committerJim Kingdon <jkingdon@engr.sgi.com>1993-09-08 15:51:39 +0000
commit9f1e14f4c90eca1708ef02ad5dddcb9c526fb0e3 (patch)
treed9f2b17c77d2daabab413c8265bf05496c744991
parentbf6608851fb4d101087871abe628a2238e424959 (diff)
downloadgdb-9f1e14f4c90eca1708ef02ad5dddcb9c526fb0e3.zip
gdb-9f1e14f4c90eca1708ef02ad5dddcb9c526fb0e3.tar.gz
gdb-9f1e14f4c90eca1708ef02ad5dddcb9c526fb0e3.tar.bz2
* minsyms.c, symtab.h (lookup_next_minimal_symbol): New function.
* dbxread.c (process_one_symbol): Use it.
-rw-r--r--gdb/dbxread.c15
-rw-r--r--gdb/minsyms.c87
-rw-r--r--gdb/symtab.h2
3 files changed, 97 insertions, 7 deletions
diff --git a/gdb/dbxread.c b/gdb/dbxread.c
index cc0c43e..6c93ef4 100644
--- a/gdb/dbxread.c
+++ b/gdb/dbxread.c
@@ -1933,12 +1933,17 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
if (m && STREQN (SYMBOL_NAME (m), name, l))
/* last_pc_address was in this function */
valu = SYMBOL_VALUE (m);
- else if (m && STREQN (SYMBOL_NAME (m+1), name, l))
- /* last_pc_address was in last function */
- valu = SYMBOL_VALUE (m+1);
else
- /* Not found - use last_pc_address (for finish_block) */
- valu = last_pc_address;
+ {
+ m = lookup_next_minimal_symbol (last_pc_address);
+ if (m && STREQN (SYMBOL_NAME (m), name, l))
+ /* last_pc_address was in last function */
+ valu = SYMBOL_VALUE (m);
+ else
+ /* Not found.
+ Use last_pc_address (for finish_block). */
+ valu = last_pc_address;
+ }
}
last_pc_address = valu; /* Save for SunOS bug circumcision */
diff --git a/gdb/minsyms.c b/gdb/minsyms.c
index 63850aa..2efb96e 100644
--- a/gdb/minsyms.c
+++ b/gdb/minsyms.c
@@ -212,7 +212,7 @@ lookup_minimal_symbol_by_pc (pc)
{
lo = 0;
hi = objfile -> minimal_symbol_count - 1;
-
+
/* This code assumes that the minimal symbols are sorted by
ascending address values. If the pc value is greater than or
equal to the first symbol's address, then some symbol in this
@@ -260,7 +260,90 @@ lookup_minimal_symbol_by_pc (pc)
best_symbol = &msymbol[hi];
}
}
- }
+ }
+ }
+ return (best_symbol);
+}
+
+/* Just like lookup_minimal_symbol_by_pc, but look up the closest minimal
+ symbol > PC, not the one <= PC. */
+
+struct minimal_symbol *
+lookup_next_minimal_symbol (pc)
+ CORE_ADDR pc;
+{
+ register int lo;
+ register int hi;
+ register int new;
+ register struct objfile *objfile;
+ register struct minimal_symbol *msymbol;
+ register struct minimal_symbol *best_symbol = NULL;
+
+ for (objfile = object_files;
+ objfile != NULL;
+ objfile = objfile -> next)
+ {
+ /* If this objfile has a minimal symbol table, go search it using
+ a binary search. Note that a minimal symbol table always consists
+ of at least two symbols, a "real" symbol and the terminating
+ "null symbol". If there are no real symbols, then there is no
+ minimal symbol table at all. */
+
+ if ((msymbol = objfile -> msymbols) != NULL)
+ {
+ lo = 0;
+ hi = objfile -> minimal_symbol_count - 1;
+
+ /* This code assumes that the minimal symbols are sorted by
+ ascending address values. If the pc value is greater than or
+ equal to the first symbol's address, then some symbol in this
+ minimal symbol table is a suitable candidate for being the
+ "best" symbol. This includes the last real symbol, for cases
+ where the pc value is larger than any address in this vector.
+
+ By iterating until the address associated with the current
+ hi index (the endpoint of the test interval) is less than
+ or equal to the desired pc value, we accomplish two things:
+ (1) the case where the pc value is larger than any minimal
+ symbol address is trivially solved, (2) the address associated
+ with the hi index is always the one we want when the interation
+ terminates. In essence, we are iterating the test interval
+ down until the pc value is pushed out of it from the high end.
+
+ Warning: this code is trickier than it would appear at first. */
+
+ /* Intentionally does not check that pc <= start of objfile.
+ dbxread.c:process_one_symbol wants to call this with zero and
+ get the first minimal symbol. */
+ if (pc < SYMBOL_VALUE_ADDRESS (&msymbol[hi]))
+ {
+ while (SYMBOL_VALUE_ADDRESS (&msymbol[lo]) <= pc)
+ {
+ /* pc is still strictly less than highest address */
+ /* Note "new" will always be >= lo */
+ new = (lo + hi) / 2;
+ if ((SYMBOL_VALUE_ADDRESS (&msymbol[new]) < pc) ||
+ (lo == new))
+ {
+ hi = new;
+ }
+ else
+ {
+ lo = new;
+ }
+ }
+ /* The minimal symbol indexed by hi now is the best one in this
+ objfile's minimal symbol table. See if it is the best one
+ overall. */
+
+ if ((best_symbol == NULL) ||
+ (SYMBOL_VALUE_ADDRESS (best_symbol) >
+ SYMBOL_VALUE_ADDRESS (&msymbol[lo])))
+ {
+ best_symbol = &msymbol[lo];
+ }
+ }
+ }
}
return (best_symbol);
}
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 5b47bea..b215168 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -992,6 +992,8 @@ lookup_minimal_symbol PARAMS ((const char *, struct objfile *));
extern struct minimal_symbol *
lookup_minimal_symbol_by_pc PARAMS ((CORE_ADDR));
+extern struct minimal_symbol *lookup_next_minimal_symbol PARAMS ((CORE_ADDR));
+
extern void
init_minimal_symbol_collection PARAMS ((void));