forked from Imagelibrary/binutils-gdb
Move definition of some prologue-related functions to a better location.
gdb/ChangeLog: * symtab.c (in_prologue): Move definition to better spot. (skip_prologue_using_sal): Ditto.
This commit is contained in:
@@ -1,3 +1,8 @@
|
||||
2014-08-28 Doug Evans <dje@google.com>
|
||||
|
||||
* symtab.c (in_prologue): Move definition to better spot.
|
||||
(skip_prologue_using_sal): Ditto.
|
||||
|
||||
2014-08-28 Doug Evans <dje@google.com>
|
||||
|
||||
* symtab.c (find_function_start_sal): Move definition to better spot.
|
||||
|
||||
374
gdb/symtab.c
374
gdb/symtab.c
@@ -3034,6 +3034,193 @@ skip_prologue_sal (struct symtab_and_line *sal)
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine if PC is in the prologue of a function. The prologue is the area
|
||||
between the first instruction of a function, and the first executable line.
|
||||
Returns 1 if PC *might* be in prologue, 0 if definately *not* in prologue.
|
||||
|
||||
If non-zero, func_start is where we think the prologue starts, possibly
|
||||
by previous examination of symbol table information. */
|
||||
|
||||
int
|
||||
in_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR func_start)
|
||||
{
|
||||
struct symtab_and_line sal;
|
||||
CORE_ADDR func_addr, func_end;
|
||||
|
||||
/* We have several sources of information we can consult to figure
|
||||
this out.
|
||||
- Compilers usually emit line number info that marks the prologue
|
||||
as its own "source line". So the ending address of that "line"
|
||||
is the end of the prologue. If available, this is the most
|
||||
reliable method.
|
||||
- The minimal symbols and partial symbols, which can usually tell
|
||||
us the starting and ending addresses of a function.
|
||||
- If we know the function's start address, we can call the
|
||||
architecture-defined gdbarch_skip_prologue function to analyze the
|
||||
instruction stream and guess where the prologue ends.
|
||||
- Our `func_start' argument; if non-zero, this is the caller's
|
||||
best guess as to the function's entry point. At the time of
|
||||
this writing, handle_inferior_event doesn't get this right, so
|
||||
it should be our last resort. */
|
||||
|
||||
/* Consult the partial symbol table, to find which function
|
||||
the PC is in. */
|
||||
if (! find_pc_partial_function (pc, NULL, &func_addr, &func_end))
|
||||
{
|
||||
CORE_ADDR prologue_end;
|
||||
|
||||
/* We don't even have minsym information, so fall back to using
|
||||
func_start, if given. */
|
||||
if (! func_start)
|
||||
return 1; /* We *might* be in a prologue. */
|
||||
|
||||
prologue_end = gdbarch_skip_prologue (gdbarch, func_start);
|
||||
|
||||
return func_start <= pc && pc < prologue_end;
|
||||
}
|
||||
|
||||
/* If we have line number information for the function, that's
|
||||
usually pretty reliable. */
|
||||
sal = find_pc_line (func_addr, 0);
|
||||
|
||||
/* Now sal describes the source line at the function's entry point,
|
||||
which (by convention) is the prologue. The end of that "line",
|
||||
sal.end, is the end of the prologue.
|
||||
|
||||
Note that, for functions whose source code is all on a single
|
||||
line, the line number information doesn't always end up this way.
|
||||
So we must verify that our purported end-of-prologue address is
|
||||
*within* the function, not at its start or end. */
|
||||
if (sal.line == 0
|
||||
|| sal.end <= func_addr
|
||||
|| func_end <= sal.end)
|
||||
{
|
||||
/* We don't have any good line number info, so use the minsym
|
||||
information, together with the architecture-specific prologue
|
||||
scanning code. */
|
||||
CORE_ADDR prologue_end = gdbarch_skip_prologue (gdbarch, func_addr);
|
||||
|
||||
return func_addr <= pc && pc < prologue_end;
|
||||
}
|
||||
|
||||
/* We have line number info, and it looks good. */
|
||||
return func_addr <= pc && pc < sal.end;
|
||||
}
|
||||
|
||||
/* Given PC at the function's start address, attempt to find the
|
||||
prologue end using SAL information. Return zero if the skip fails.
|
||||
|
||||
A non-optimized prologue traditionally has one SAL for the function
|
||||
and a second for the function body. A single line function has
|
||||
them both pointing at the same line.
|
||||
|
||||
An optimized prologue is similar but the prologue may contain
|
||||
instructions (SALs) from the instruction body. Need to skip those
|
||||
while not getting into the function body.
|
||||
|
||||
The functions end point and an increasing SAL line are used as
|
||||
indicators of the prologue's endpoint.
|
||||
|
||||
This code is based on the function refine_prologue_limit
|
||||
(found in ia64). */
|
||||
|
||||
CORE_ADDR
|
||||
skip_prologue_using_sal (struct gdbarch *gdbarch, CORE_ADDR func_addr)
|
||||
{
|
||||
struct symtab_and_line prologue_sal;
|
||||
CORE_ADDR start_pc;
|
||||
CORE_ADDR end_pc;
|
||||
const struct block *bl;
|
||||
|
||||
/* Get an initial range for the function. */
|
||||
find_pc_partial_function (func_addr, NULL, &start_pc, &end_pc);
|
||||
start_pc += gdbarch_deprecated_function_start_offset (gdbarch);
|
||||
|
||||
prologue_sal = find_pc_line (start_pc, 0);
|
||||
if (prologue_sal.line != 0)
|
||||
{
|
||||
/* For languages other than assembly, treat two consecutive line
|
||||
entries at the same address as a zero-instruction prologue.
|
||||
The GNU assembler emits separate line notes for each instruction
|
||||
in a multi-instruction macro, but compilers generally will not
|
||||
do this. */
|
||||
if (prologue_sal.symtab->language != language_asm)
|
||||
{
|
||||
struct linetable *linetable = LINETABLE (prologue_sal.symtab);
|
||||
int idx = 0;
|
||||
|
||||
/* Skip any earlier lines, and any end-of-sequence marker
|
||||
from a previous function. */
|
||||
while (linetable->item[idx].pc != prologue_sal.pc
|
||||
|| linetable->item[idx].line == 0)
|
||||
idx++;
|
||||
|
||||
if (idx+1 < linetable->nitems
|
||||
&& linetable->item[idx+1].line != 0
|
||||
&& linetable->item[idx+1].pc == start_pc)
|
||||
return start_pc;
|
||||
}
|
||||
|
||||
/* If there is only one sal that covers the entire function,
|
||||
then it is probably a single line function, like
|
||||
"foo(){}". */
|
||||
if (prologue_sal.end >= end_pc)
|
||||
return 0;
|
||||
|
||||
while (prologue_sal.end < end_pc)
|
||||
{
|
||||
struct symtab_and_line sal;
|
||||
|
||||
sal = find_pc_line (prologue_sal.end, 0);
|
||||
if (sal.line == 0)
|
||||
break;
|
||||
/* Assume that a consecutive SAL for the same (or larger)
|
||||
line mark the prologue -> body transition. */
|
||||
if (sal.line >= prologue_sal.line)
|
||||
break;
|
||||
/* Likewise if we are in a different symtab altogether
|
||||
(e.g. within a file included via #include). */
|
||||
if (sal.symtab != prologue_sal.symtab)
|
||||
break;
|
||||
|
||||
/* The line number is smaller. Check that it's from the
|
||||
same function, not something inlined. If it's inlined,
|
||||
then there is no point comparing the line numbers. */
|
||||
bl = block_for_pc (prologue_sal.end);
|
||||
while (bl)
|
||||
{
|
||||
if (block_inlined_p (bl))
|
||||
break;
|
||||
if (BLOCK_FUNCTION (bl))
|
||||
{
|
||||
bl = NULL;
|
||||
break;
|
||||
}
|
||||
bl = BLOCK_SUPERBLOCK (bl);
|
||||
}
|
||||
if (bl != NULL)
|
||||
break;
|
||||
|
||||
/* The case in which compiler's optimizer/scheduler has
|
||||
moved instructions into the prologue. We look ahead in
|
||||
the function looking for address ranges whose
|
||||
corresponding line number is less the first one that we
|
||||
found for the function. This is more conservative then
|
||||
refine_prologue_limit which scans a large number of SALs
|
||||
looking for any in the prologue. */
|
||||
prologue_sal = sal;
|
||||
}
|
||||
}
|
||||
|
||||
if (prologue_sal.end < end_pc)
|
||||
/* Return the end of this line, or zero if we could not find a
|
||||
line. */
|
||||
return prologue_sal.end;
|
||||
else
|
||||
/* Don't return END_PC, which is past the end of the function. */
|
||||
return prologue_sal.pc;
|
||||
}
|
||||
|
||||
/* If P is of the form "operator[ \t]+..." where `...' is
|
||||
some legitimate operator text, return a pointer to the
|
||||
beginning of the substring of the operator text.
|
||||
@@ -4827,193 +5014,6 @@ make_source_files_completion_list (const char *text, const char *word)
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/* Determine if PC is in the prologue of a function. The prologue is the area
|
||||
between the first instruction of a function, and the first executable line.
|
||||
Returns 1 if PC *might* be in prologue, 0 if definately *not* in prologue.
|
||||
|
||||
If non-zero, func_start is where we think the prologue starts, possibly
|
||||
by previous examination of symbol table information. */
|
||||
|
||||
int
|
||||
in_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR func_start)
|
||||
{
|
||||
struct symtab_and_line sal;
|
||||
CORE_ADDR func_addr, func_end;
|
||||
|
||||
/* We have several sources of information we can consult to figure
|
||||
this out.
|
||||
- Compilers usually emit line number info that marks the prologue
|
||||
as its own "source line". So the ending address of that "line"
|
||||
is the end of the prologue. If available, this is the most
|
||||
reliable method.
|
||||
- The minimal symbols and partial symbols, which can usually tell
|
||||
us the starting and ending addresses of a function.
|
||||
- If we know the function's start address, we can call the
|
||||
architecture-defined gdbarch_skip_prologue function to analyze the
|
||||
instruction stream and guess where the prologue ends.
|
||||
- Our `func_start' argument; if non-zero, this is the caller's
|
||||
best guess as to the function's entry point. At the time of
|
||||
this writing, handle_inferior_event doesn't get this right, so
|
||||
it should be our last resort. */
|
||||
|
||||
/* Consult the partial symbol table, to find which function
|
||||
the PC is in. */
|
||||
if (! find_pc_partial_function (pc, NULL, &func_addr, &func_end))
|
||||
{
|
||||
CORE_ADDR prologue_end;
|
||||
|
||||
/* We don't even have minsym information, so fall back to using
|
||||
func_start, if given. */
|
||||
if (! func_start)
|
||||
return 1; /* We *might* be in a prologue. */
|
||||
|
||||
prologue_end = gdbarch_skip_prologue (gdbarch, func_start);
|
||||
|
||||
return func_start <= pc && pc < prologue_end;
|
||||
}
|
||||
|
||||
/* If we have line number information for the function, that's
|
||||
usually pretty reliable. */
|
||||
sal = find_pc_line (func_addr, 0);
|
||||
|
||||
/* Now sal describes the source line at the function's entry point,
|
||||
which (by convention) is the prologue. The end of that "line",
|
||||
sal.end, is the end of the prologue.
|
||||
|
||||
Note that, for functions whose source code is all on a single
|
||||
line, the line number information doesn't always end up this way.
|
||||
So we must verify that our purported end-of-prologue address is
|
||||
*within* the function, not at its start or end. */
|
||||
if (sal.line == 0
|
||||
|| sal.end <= func_addr
|
||||
|| func_end <= sal.end)
|
||||
{
|
||||
/* We don't have any good line number info, so use the minsym
|
||||
information, together with the architecture-specific prologue
|
||||
scanning code. */
|
||||
CORE_ADDR prologue_end = gdbarch_skip_prologue (gdbarch, func_addr);
|
||||
|
||||
return func_addr <= pc && pc < prologue_end;
|
||||
}
|
||||
|
||||
/* We have line number info, and it looks good. */
|
||||
return func_addr <= pc && pc < sal.end;
|
||||
}
|
||||
|
||||
/* Given PC at the function's start address, attempt to find the
|
||||
prologue end using SAL information. Return zero if the skip fails.
|
||||
|
||||
A non-optimized prologue traditionally has one SAL for the function
|
||||
and a second for the function body. A single line function has
|
||||
them both pointing at the same line.
|
||||
|
||||
An optimized prologue is similar but the prologue may contain
|
||||
instructions (SALs) from the instruction body. Need to skip those
|
||||
while not getting into the function body.
|
||||
|
||||
The functions end point and an increasing SAL line are used as
|
||||
indicators of the prologue's endpoint.
|
||||
|
||||
This code is based on the function refine_prologue_limit
|
||||
(found in ia64). */
|
||||
|
||||
CORE_ADDR
|
||||
skip_prologue_using_sal (struct gdbarch *gdbarch, CORE_ADDR func_addr)
|
||||
{
|
||||
struct symtab_and_line prologue_sal;
|
||||
CORE_ADDR start_pc;
|
||||
CORE_ADDR end_pc;
|
||||
const struct block *bl;
|
||||
|
||||
/* Get an initial range for the function. */
|
||||
find_pc_partial_function (func_addr, NULL, &start_pc, &end_pc);
|
||||
start_pc += gdbarch_deprecated_function_start_offset (gdbarch);
|
||||
|
||||
prologue_sal = find_pc_line (start_pc, 0);
|
||||
if (prologue_sal.line != 0)
|
||||
{
|
||||
/* For languages other than assembly, treat two consecutive line
|
||||
entries at the same address as a zero-instruction prologue.
|
||||
The GNU assembler emits separate line notes for each instruction
|
||||
in a multi-instruction macro, but compilers generally will not
|
||||
do this. */
|
||||
if (prologue_sal.symtab->language != language_asm)
|
||||
{
|
||||
struct linetable *linetable = LINETABLE (prologue_sal.symtab);
|
||||
int idx = 0;
|
||||
|
||||
/* Skip any earlier lines, and any end-of-sequence marker
|
||||
from a previous function. */
|
||||
while (linetable->item[idx].pc != prologue_sal.pc
|
||||
|| linetable->item[idx].line == 0)
|
||||
idx++;
|
||||
|
||||
if (idx+1 < linetable->nitems
|
||||
&& linetable->item[idx+1].line != 0
|
||||
&& linetable->item[idx+1].pc == start_pc)
|
||||
return start_pc;
|
||||
}
|
||||
|
||||
/* If there is only one sal that covers the entire function,
|
||||
then it is probably a single line function, like
|
||||
"foo(){}". */
|
||||
if (prologue_sal.end >= end_pc)
|
||||
return 0;
|
||||
|
||||
while (prologue_sal.end < end_pc)
|
||||
{
|
||||
struct symtab_and_line sal;
|
||||
|
||||
sal = find_pc_line (prologue_sal.end, 0);
|
||||
if (sal.line == 0)
|
||||
break;
|
||||
/* Assume that a consecutive SAL for the same (or larger)
|
||||
line mark the prologue -> body transition. */
|
||||
if (sal.line >= prologue_sal.line)
|
||||
break;
|
||||
/* Likewise if we are in a different symtab altogether
|
||||
(e.g. within a file included via #include). */
|
||||
if (sal.symtab != prologue_sal.symtab)
|
||||
break;
|
||||
|
||||
/* The line number is smaller. Check that it's from the
|
||||
same function, not something inlined. If it's inlined,
|
||||
then there is no point comparing the line numbers. */
|
||||
bl = block_for_pc (prologue_sal.end);
|
||||
while (bl)
|
||||
{
|
||||
if (block_inlined_p (bl))
|
||||
break;
|
||||
if (BLOCK_FUNCTION (bl))
|
||||
{
|
||||
bl = NULL;
|
||||
break;
|
||||
}
|
||||
bl = BLOCK_SUPERBLOCK (bl);
|
||||
}
|
||||
if (bl != NULL)
|
||||
break;
|
||||
|
||||
/* The case in which compiler's optimizer/scheduler has
|
||||
moved instructions into the prologue. We look ahead in
|
||||
the function looking for address ranges whose
|
||||
corresponding line number is less the first one that we
|
||||
found for the function. This is more conservative then
|
||||
refine_prologue_limit which scans a large number of SALs
|
||||
looking for any in the prologue. */
|
||||
prologue_sal = sal;
|
||||
}
|
||||
}
|
||||
|
||||
if (prologue_sal.end < end_pc)
|
||||
/* Return the end of this line, or zero if we could not find a
|
||||
line. */
|
||||
return prologue_sal.end;
|
||||
else
|
||||
/* Don't return END_PC, which is past the end of the function. */
|
||||
return prologue_sal.pc;
|
||||
}
|
||||
|
||||
/* Track MAIN */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user