* 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.

	* gdb.arch/i386-size.c, gdb.arch/i386-size.exp: New files.
This commit is contained in:
Daniel Jacobowitz 2006-07-19 02:17:23 +00:00
parent 5061a8853b
commit 29e8a84408
6 changed files with 259 additions and 43 deletions

View File

@ -1,3 +1,10 @@
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)

View File

@ -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 (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);
if (MSYMBOL_SIZE (msymbol) != 0)
cache_pc_function_high = cache_pc_function_low + MSYMBOL_SIZE (msymbol);
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;
{
/* 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 (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:

View File

@ -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) <

View File

@ -1,3 +1,7 @@
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.

View File

@ -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");

View File

@ -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
}
}