* rs6000-tdep.c (BL_MASK, BL_INSTRUCTION, BL_DISPLACEMENT_MASK):

New macros.
 	(rs6000_skip_main_prologue): New function.
 	(rs6000_gdb_arch_init): Register rs6000_skip_main_prologue.
This commit is contained in:
Kevin Buettner 2008-08-12 00:29:35 +00:00
parent 1271d27249
commit 8ab3d180b1
2 changed files with 57 additions and 0 deletions

View file

@ -1,3 +1,10 @@
2008-08-11 Kevin Buettner <kevinb@redhat.com>
* rs6000-tdep.c (BL_MASK, BL_INSTRUCTION, BL_DISPLACEMENT_MASK):
New macros.
(rs6000_skip_main_prologue): New function.
(rs6000_gdb_arch_init): Register rs6000_skip_main_prologue.
2008-08-11 Sandra Loosemore <sandra@codesourcery.com>
* MAINTAINERS (Write After Approval): Add self.

View file

@ -1146,6 +1146,20 @@ bl_to_blrl_insn_p (CORE_ADDR pc, int insn)
return 0;
}
/* Masks for decoding a branch-and-link (bl) instruction.
BL_MASK and BL_INSTRUCTION are used in combination with each other.
The former is anded with the opcode in question; if the result of
this masking operation is equal to BL_INSTRUCTION, then the opcode in
question is a ``bl'' instruction.
BL_DISPLACMENT_MASK is anded with the opcode in order to extract
the branch displacement. */
#define BL_MASK 0xfc000001
#define BL_INSTRUCTION 0x48000001
#define BL_DISPLACEMENT_MASK 0x03fffffc
/* return pc value after skipping a function prologue and also return
information about a function frame.
@ -1769,6 +1783,41 @@ rs6000_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
return pc;
}
/* When compiling for EABI, some versions of GCC emit a call to __eabi
in the prologue of main().
The function below examines the code pointed at by PC and checks to
see if it corresponds to a call to __eabi. If so, it returns the
address of the instruction following that call. Otherwise, it simply
returns PC. */
CORE_ADDR
rs6000_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
gdb_byte buf[4];
unsigned long op;
if (target_read_memory (pc, buf, 4))
return pc;
op = extract_unsigned_integer (buf, 4);
if ((op & BL_MASK) == BL_INSTRUCTION)
{
CORE_ADDR displ = op & BL_DISPLACEMENT_MASK;
CORE_ADDR call_dest = pc + 4 + displ;
struct minimal_symbol *s = lookup_minimal_symbol_by_pc (call_dest);
/* We check for ___eabi (three leading underscores) in addition
to __eabi in case the GCC option "-fleading-underscore" was
used to compile the program. */
if (s != NULL
&& SYMBOL_LINKAGE_NAME (s) != NULL
&& (strcmp (SYMBOL_LINKAGE_NAME (s), "__eabi") == 0
|| strcmp (SYMBOL_LINKAGE_NAME (s), "___eabi") == 0))
pc += 4;
}
return pc;
}
/* All the ABI's require 16 byte alignment. */
static CORE_ADDR
@ -3238,6 +3287,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_skip_prologue (gdbarch, rs6000_skip_prologue);
set_gdbarch_in_function_epilogue_p (gdbarch, rs6000_in_function_epilogue_p);
set_gdbarch_skip_main_prologue (gdbarch, rs6000_skip_main_prologue);
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
set_gdbarch_breakpoint_from_pc (gdbarch, rs6000_breakpoint_from_pc);