* config/rs6000/tm-rs6000.h (IN_SOLIB_RETURN_TRAMPOLINE): Define.

(rs6000_in_solib_return_trampoline): Declare.
	* rs6000-tdep.c (rs6000_in_solib_return_trampoline): New
	function.
	(rs6000_skip_trampoline_code): Skip bigtoc fixup code.
	* xcoffread.c (read_xcoff_symtab): Perform the ISFCN function
	check after the CSECT check rather than before it.  Allocate
	separate symtabs for CSECTs whose names begin with '@'.
	(scan_xcoff_symtab): Don't ignore symbols beginning with '@'.
	Activate the misc_func_recorded mechanism for whose names begin
	with '@'.
This commit is contained in:
Nicholas Duffek 2001-05-01 19:36:11 +00:00
parent f5a6fc0555
commit 977adac5db
4 changed files with 96 additions and 23 deletions

View File

@ -1,3 +1,17 @@
2001-05-01 Nicholas Duffek <nsd@redhat.com>
* config/rs6000/tm-rs6000.h (IN_SOLIB_RETURN_TRAMPOLINE): Define.
(rs6000_in_solib_return_trampoline): Declare.
* rs6000-tdep.c (rs6000_in_solib_return_trampoline): New
function.
(rs6000_skip_trampoline_code): Skip bigtoc fixup code.
* xcoffread.c (read_xcoff_symtab): Perform the ISFCN function
check after the CSECT check rather than before it. Allocate
separate symtabs for CSECTs whose names begin with '@'.
(scan_xcoff_symtab): Don't ignore symbols beginning with '@'.
Activate the misc_func_recorded mechanism for whose names begin
with '@'.
2001-04-30 J.T. Conklin <jtc@redback.com>
* ppcnbsd-nat.c (fetch_inferior_registers)

View File

@ -32,6 +32,13 @@
#undef CPLUS_MARKER
#define CPLUS_MARKER '.'
/* Return whether PC in function NAME is in code that should be skipped when
single-stepping. */
#define IN_SOLIB_RETURN_TRAMPOLINE(pc, name) \
rs6000_in_solib_return_trampoline (pc, name)
extern int rs6000_in_solib_return_trampoline (CORE_ADDR, char *);
/* If PC is in some function-call trampoline code, return the PC
where the function itself actually starts. If not, return NULL. */

View File

@ -1132,19 +1132,55 @@ rs6000_extract_return_value (struct type *valtype, char *regbuf, char *valbuf)
static CORE_ADDR rs6000_struct_return_address;
/* Indirect function calls use a piece of trampoline code to do context
switching, i.e. to set the new TOC table. Skip such code if we are on
its first instruction (as when we have single-stepped to here).
Also skip shared library trampoline code (which is different from
/* Return whether handle_inferior_event() should proceed through code
starting at PC in function NAME when stepping.
The AIX -bbigtoc linker option generates functions @FIX0, @FIX1, etc. to
handle memory references that are too distant to fit in instructions
generated by the compiler. For example, if 'foo' in the following
instruction:
lwz r9,foo(r2)
is greater than 32767, the linker might replace the lwz with a branch to
somewhere in @FIX1 that does the load in 2 instructions and then branches
back to where execution should continue.
GDB should silently step over @FIX code, just like AIX dbx does.
Unfortunately, the linker uses the "b" instruction for the branches,
meaning that the link register doesn't get set. Therefore, GDB's usual
step_over_function() mechanism won't work.
Instead, use the IN_SOLIB_RETURN_TRAMPOLINE and SKIP_TRAMPOLINE_CODE hooks
in handle_inferior_event() to skip past @FIX code. */
int
rs6000_in_solib_return_trampoline (CORE_ADDR pc, char *name)
{
return name && !strncmp (name, "@FIX", 4);
}
/* Skip code that the user doesn't want to see when stepping:
1. Indirect function calls use a piece of trampoline code to do context
switching, i.e. to set the new TOC table. Skip such code if we are on
its first instruction (as when we have single-stepped to here).
2. Skip shared library trampoline code (which is different from
indirect function call trampolines).
3. Skip bigtoc fixup code.
Result is desired PC to step until, or NULL if we are not in
trampoline code. */
code that should be skipped. */
CORE_ADDR
rs6000_skip_trampoline_code (CORE_ADDR pc)
{
register unsigned int ii, op;
int rel;
CORE_ADDR solib_target_pc;
struct minimal_symbol *msymbol;
static unsigned trampoline_code[] =
{
@ -1158,6 +1194,21 @@ rs6000_skip_trampoline_code (CORE_ADDR pc)
0
};
/* Check for bigtoc fixup code. */
msymbol = lookup_minimal_symbol_by_pc (pc);
if (msymbol && rs6000_in_solib_return_trampoline (pc, SYMBOL_NAME (msymbol)))
{
/* Double-check that the third instruction from PC is relative "b". */
op = read_memory_integer (pc + 8, 4);
if ((op & 0xfc000003) == 0x48000000)
{
/* Extract bits 6-29 as a signed 24-bit relative word address and
add it to the containing PC. */
rel = ((int)(op << 6) >> 6);
return pc + 8 + rel;
}
}
/* If pc is in a shared library trampoline, return its target. */
solib_target_pc = find_solib_trampoline_target (pc);
if (solib_target_pc)

View File

@ -1081,14 +1081,6 @@ read_xcoff_symtab (struct partial_symtab *pst)
/* done with all files, everything from here on is globals */
}
/* if explicitly specified as a function, treat is as one. */
if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF)
{
bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
0, cs->c_naux, &main_aux);
goto function_entry_point;
}
if ((cs->c_sclass == C_EXT || cs->c_sclass == C_HIDEXT)
&& cs->c_naux == 1)
{
@ -1158,7 +1150,8 @@ read_xcoff_symtab (struct partial_symtab *pst)
SECT_OFF_TEXT (objfile));
file_end_addr = file_start_addr + CSECT_LEN (&main_aux);
if (cs->c_name && cs->c_name[0] == '.')
if (cs->c_name && (cs->c_name[0] == '.'
|| cs->c_name[0] == '@'))
{
last_csect_name = cs->c_name;
last_csect_val = cs->c_value;
@ -1232,6 +1225,16 @@ read_xcoff_symtab (struct partial_symtab *pst)
}
}
/* If explicitly specified as a function, treat is as one. This check
evaluates to true for @FIX* bigtoc CSECT symbols, so it must occur
after the above CSECT check. */
if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF)
{
bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
0, cs->c_naux, &main_aux);
goto function_entry_point;
}
switch (cs->c_sclass)
{
@ -2243,14 +2246,8 @@ scan_xcoff_symtab (struct objfile *objfile)
else
csect_aux = main_aux[0];
/* If symbol name starts with ".$" or "$", ignore it.
A symbol like "@FIX1" introduces a section for -bbigtoc jump
tables, which contain anonymous linker-generated code.
Ignore those sections to avoid "pc 0x... in read in psymtab,
but not in symtab" warnings from find_pc_sect_symtab. */
if (namestring[0] == '$' || namestring[0] == '@'
/* If symbol name starts with ".$" or "$", ignore it. */
if (namestring[0] == '$'
|| (namestring[0] == '.' && namestring[1] == '$'))
break;
@ -2296,7 +2293,11 @@ scan_xcoff_symtab (struct objfile *objfile)
objfile->static_psymbols.next);
}
}
if (namestring && namestring[0] == '.')
/* Activate the misc_func_recorded mechanism for
compiler- and linker-generated CSECTs like ".strcmp"
and "@FIX1". */
if (namestring && (namestring[0] == '.'
|| namestring[0] == '@'))
{
last_csect_name = namestring;
last_csect_val = symbol.n_value;