aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog7
-rw-r--r--gdb/blockframe.c43
-rw-r--r--gdb/minsyms.c107
-rw-r--r--gdb/testsuite/ChangeLog4
-rw-r--r--gdb/testsuite/gdb.arch/i386-size.c50
-rw-r--r--gdb/testsuite/gdb.arch/i386-size.exp89
6 files changed, 258 insertions, 42 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 5fd306f..ef7d2b9 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,12 @@
2006-07-18 Daniel Jacobowitz <dan@codesourcery.com>
+ * blockframe.c (find_pc_partial_function): Use the minimal symbol
+ size to control the cache entry, if available.
+ * minsyms.c (lookup_minimal_symbol_by_pc_section): Handle minimal
+ symbols with zero and non-zero sizes differently.
+
+2006-07-18 Daniel Jacobowitz <dan@codesourcery.com>
+
* linux-thread-db.c (td_thr_getfpregs_p, td_thr_getgregs_p)
(td_thr_setfpregs_p, td_thr_setgregs_p, thread_db_get_info)
(thread_db_fetch_registers, thread_db_store_registers)
diff --git a/gdb/blockframe.c b/gdb/blockframe.c
index dbb1b43..ba298c3 100644
--- a/gdb/blockframe.c
+++ b/gdb/blockframe.c
@@ -280,27 +280,34 @@ find_pc_partial_function (CORE_ADDR pc, char **name, CORE_ADDR *address,
cache_pc_function_name = DEPRECATED_SYMBOL_NAME (msymbol);
cache_pc_function_section = section;
- /* Use the lesser of the next minimal symbol in the same section, or
- the end of the section, as the end of the function. */
+ /* If the minimal symbol has a size, use it for the cache.
+ Otherwise use the lesser of the next minimal symbol in the same
+ section, or the end of the section, as the end of the
+ function. */
- /* Step over other symbols at this same address, and symbols in
- other sections, to find the next symbol in this section with
- a different address. */
-
- for (i = 1; DEPRECATED_SYMBOL_NAME (msymbol + i) != NULL; i++)
+ if (MSYMBOL_SIZE (msymbol) != 0)
+ cache_pc_function_high = cache_pc_function_low + MSYMBOL_SIZE (msymbol);
+ else
{
- if (SYMBOL_VALUE_ADDRESS (msymbol + i) != SYMBOL_VALUE_ADDRESS (msymbol)
- && SYMBOL_BFD_SECTION (msymbol + i) == SYMBOL_BFD_SECTION (msymbol))
- break;
- }
+ /* Step over other symbols at this same address, and symbols in
+ other sections, to find the next symbol in this section with
+ a different address. */
- if (DEPRECATED_SYMBOL_NAME (msymbol + i) != NULL
- && SYMBOL_VALUE_ADDRESS (msymbol + i) < osect->endaddr)
- cache_pc_function_high = SYMBOL_VALUE_ADDRESS (msymbol + i);
- else
- /* We got the start address from the last msymbol in the objfile.
- So the end address is the end of the section. */
- cache_pc_function_high = osect->endaddr;
+ for (i = 1; DEPRECATED_SYMBOL_NAME (msymbol + i) != NULL; i++)
+ {
+ if (SYMBOL_VALUE_ADDRESS (msymbol + i) != SYMBOL_VALUE_ADDRESS (msymbol)
+ && SYMBOL_BFD_SECTION (msymbol + i) == SYMBOL_BFD_SECTION (msymbol))
+ break;
+ }
+
+ if (DEPRECATED_SYMBOL_NAME (msymbol + i) != NULL
+ && SYMBOL_VALUE_ADDRESS (msymbol + i) < osect->endaddr)
+ cache_pc_function_high = SYMBOL_VALUE_ADDRESS (msymbol + i);
+ else
+ /* We got the start address from the last msymbol in the objfile.
+ So the end address is the end of the section. */
+ cache_pc_function_high = osect->endaddr;
+ }
return_cached_value:
diff --git a/gdb/minsyms.c b/gdb/minsyms.c
index e8ef95e..ae4c23a 100644
--- a/gdb/minsyms.c
+++ b/gdb/minsyms.c
@@ -412,6 +412,8 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section)
if (objfile->minimal_symbol_count > 0)
{
+ int best_zero_sized = -1;
+
msymbol = objfile->msymbols;
lo = 0;
hi = objfile->minimal_symbol_count - 1;
@@ -461,34 +463,91 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section)
== SYMBOL_VALUE_ADDRESS (&msymbol[hi + 1])))
hi++;
+ /* Skip various undesirable symbols. */
+ while (hi >= 0)
+ {
+ /* Skip any absolute symbols. This is apparently
+ what adb and dbx do, and is needed for the CM-5.
+ There are two known possible problems: (1) on
+ ELF, apparently end, edata, etc. are absolute.
+ Not sure ignoring them here is a big deal, but if
+ we want to use them, the fix would go in
+ elfread.c. (2) I think shared library entry
+ points on the NeXT are absolute. If we want
+ special handling for this it probably should be
+ triggered by a special mst_abs_or_lib or some
+ such. */
+
+ if (msymbol[hi].type == mst_abs)
+ {
+ hi--;
+ continue;
+ }
+
+ /* If SECTION was specified, skip any symbol from
+ wrong section. */
+ if (section
+ /* Some types of debug info, such as COFF,
+ don't fill the bfd_section member, so don't
+ throw away symbols on those platforms. */
+ && SYMBOL_BFD_SECTION (&msymbol[hi]) != NULL
+ && SYMBOL_BFD_SECTION (&msymbol[hi]) != section)
+ {
+ hi--;
+ continue;
+ }
+
+ /* If the minimal symbol has a zero size, save it
+ but keep scanning backwards looking for one with
+ a non-zero size. A zero size may mean that the
+ symbol isn't an object or function (e.g. a
+ label), or it may just mean that the size was not
+ specified. */
+ if (MSYMBOL_SIZE (&msymbol[hi]) == 0
+ && best_zero_sized == -1)
+ {
+ best_zero_sized = hi;
+ hi--;
+ continue;
+ }
+
+ /* Otherwise, this symbol must be as good as we're going
+ to get. */
+ break;
+ }
+
+ /* If HI has a zero size, and best_zero_sized is set,
+ then we had two or more zero-sized symbols; prefer
+ the first one we found (which may have a higher
+ address). Also, if we ran off the end, be sure
+ to back up. */
+ if (best_zero_sized != -1
+ && (hi < 0 || MSYMBOL_SIZE (&msymbol[hi]) == 0))
+ hi = best_zero_sized;
+
+ /* If the minimal symbol has a non-zero size, and this
+ PC appears to be outside the symbol's contents, then
+ refuse to use this symbol. If we found a zero-sized
+ symbol with an address greater than this symbol's,
+ use that instead. We assume that if symbols have
+ specified sizes, they do not overlap. */
+
+ if (hi >= 0
+ && MSYMBOL_SIZE (&msymbol[hi]) != 0
+ && pc >= (SYMBOL_VALUE_ADDRESS (&msymbol[hi])
+ + MSYMBOL_SIZE (&msymbol[hi])))
+ {
+ if (best_zero_sized != -1)
+ hi = best_zero_sized;
+ else
+ /* Go on to the next object file. */
+ continue;
+ }
+
/* 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. */
- /* Skip any absolute symbols. This is apparently what adb
- and dbx do, and is needed for the CM-5. There are two
- known possible problems: (1) on ELF, apparently end, edata,
- etc. are absolute. Not sure ignoring them here is a big
- deal, but if we want to use them, the fix would go in
- elfread.c. (2) I think shared library entry points on the
- NeXT are absolute. If we want special handling for this
- it probably should be triggered by a special
- mst_abs_or_lib or some such. */
- while (hi >= 0
- && msymbol[hi].type == mst_abs)
- --hi;
-
- /* If "section" specified, skip any symbol from wrong section */
- /* This is the new code that distinguishes it from the old function */
- if (section)
- while (hi >= 0
- /* Some types of debug info, such as COFF,
- don't fill the bfd_section member, so don't
- throw away symbols on those platforms. */
- && SYMBOL_BFD_SECTION (&msymbol[hi]) != NULL
- && SYMBOL_BFD_SECTION (&msymbol[hi]) != section)
- --hi;
-
if (hi >= 0
&& ((best_symbol == NULL) ||
(SYMBOL_VALUE_ADDRESS (best_symbol) <
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 7f49b3d..0a50407 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,5 +1,9 @@
2006-07-18 Daniel Jacobowitz <dan@codesourcery.com>
+ * gdb.arch/i386-size.c, gdb.arch/i386-size.exp: New files.
+
+2006-07-18 Daniel Jacobowitz <dan@codesourcery.com>
+
* gdb.threads/print-threads.exp: Use gdb_breakpoint.
2006-07-17 Mark Kettenis <kettenis@gnu.org>
diff --git a/gdb/testsuite/gdb.arch/i386-size.c b/gdb/testsuite/gdb.arch/i386-size.c
new file mode 100644
index 0000000..80357dd
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/i386-size.c
@@ -0,0 +1,50 @@
+/* Symbol size test program.
+
+ Copyright 2006 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifdef SYMBOL_PREFIX
+#define SYMBOL(str) SYMBOL_PREFIX #str
+#else
+#define SYMBOL(str) #str
+#endif
+
+void
+trap (void)
+{
+ asm ("int $0x03");
+}
+
+/* Jump from a function with its symbol size set, to a function
+ named by a local label. If GDB does not look at the sizes of
+ symbols, we will still appear to be in the first function. */
+
+asm(".text\n"
+ " .align 8\n"
+ " .globl " SYMBOL (main) "\n"
+ SYMBOL (main) ":\n"
+ " pushl %ebp\n"
+ " mov %esp, %ebp\n"
+ " call .Lfunc\n"
+ " ret\n"
+ " .size " SYMBOL (main) ", .-" SYMBOL (main) "\n"
+ ".Lfunc:\n"
+ " pushl %ebp\n"
+ " mov %esp, %ebp\n"
+ " call " SYMBOL (trap) "\n");
diff --git a/gdb/testsuite/gdb.arch/i386-size.exp b/gdb/testsuite/gdb.arch/i386-size.exp
new file mode 100644
index 0000000..dcf67e9
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/i386-size.exp
@@ -0,0 +1,89 @@
+# Copyright 2006 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@gnu.org
+
+# This file is part of the gdb testsuite.
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+# Test that GDB can see the sizes of symbols.
+
+if ![istarget "i?86-*-*"] then {
+ verbose "Skipping i386 unwinder tests."
+ return
+}
+
+set testfile "i386-size"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+# some targets have leading underscores on assembly symbols.
+# TODO: detect this automatically
+set additional_flags ""
+if [istarget "i?86-*-cygwin*"] then {
+ set additional_flags "additional_flags=-DSYMBOL_PREFIX=\"_\""
+}
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
+ executable [list debug $additional_flags]] != "" } {
+ untested "i386-size"
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# We use gdb_run_cmd so this stands a chance to work for remote
+# targets too.
+gdb_run_cmd
+
+gdb_expect {
+ -re "Program received signal SIGTRAP.*$gdb_prompt $" {
+ pass "run past main"
+ }
+ -re ".*$gdb_prompt $" {
+ fail "run past main"
+ }
+ timeout {
+ fail "run past main (timeout)"
+ }
+}
+
+set message "backtrace shows no function"
+gdb_test_multiple "backtrace 10" $message {
+ -re "#1\[ \t]*$hex in main.*$gdb_prompt $" {
+ fail $message
+ }
+ -re "#1\[ \t]*$hex in \\?\\? \\(\\).*$gdb_prompt $" {
+ pass $message
+ }
+}
+
+set message "disassemble stops at end of main"
+gdb_test_multiple "disassemble main" $message {
+ -re "call.*<trap>.*$gdb_prompt $" {
+ fail $message
+ }
+ -re "<main\\+8>:\[ \t\]+ret\[ \t\r\n\]+End of.*$gdb_prompt $" {
+ pass $message
+ }
+}