* frv-tdep.c (frv_skip_main_prologue): New function.
(frv_gdbarch_init): Register frv_skip_main_prologue. * solib-frv.c (fetch_loadmap): Return early when no segments are found. (frv_relocate_main_executable): Return early when both interpreter and executable loadmap addresses are zero.
This commit is contained in:
parent
d0107bb6ae
commit
9bc7b6c67c
3 changed files with 96 additions and 3 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
2008-11-19 Kevin Buettner <kevinb@redhat.com>
|
||||||
|
|
||||||
|
* frv-tdep.c (frv_skip_main_prologue): New function.
|
||||||
|
(frv_gdbarch_init): Register frv_skip_main_prologue.
|
||||||
|
* solib-frv.c (fetch_loadmap): Return early when no segments are
|
||||||
|
found.
|
||||||
|
(frv_relocate_main_executable): Return early when both interpreter
|
||||||
|
and executable loadmap addresses are zero.
|
||||||
|
|
||||||
2008-11-19 Bob Wilson <bob.wilson@acm.org>
|
2008-11-19 Bob Wilson <bob.wilson@acm.org>
|
||||||
|
|
||||||
* xtensa-config.c (rmap): Remove entries for ar32 through ar63. Add
|
* xtensa-config.c (rmap): Remove entries for ar32 through ar63. Add
|
||||||
|
|
|
@ -999,6 +999,85 @@ frv_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Examine the instruction pointed to by PC. If it corresponds to
|
||||||
|
a call to __main, return the address of the next instruction.
|
||||||
|
Otherwise, return PC. */
|
||||||
|
|
||||||
|
static CORE_ADDR
|
||||||
|
frv_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
|
||||||
|
{
|
||||||
|
gdb_byte buf[4];
|
||||||
|
unsigned long op;
|
||||||
|
CORE_ADDR orig_pc = pc;
|
||||||
|
|
||||||
|
if (target_read_memory (pc, buf, 4))
|
||||||
|
return pc;
|
||||||
|
op = extract_unsigned_integer (buf, 4);
|
||||||
|
|
||||||
|
/* In PIC code, GR15 may be loaded from some offset off of FP prior
|
||||||
|
to the call instruction.
|
||||||
|
|
||||||
|
Skip over this instruction if present. It won't be present in
|
||||||
|
non-PIC code, and even in PIC code, it might not be present.
|
||||||
|
(This is due to the fact that GR15, the FDPIC register, already
|
||||||
|
contains the correct value.)
|
||||||
|
|
||||||
|
The general form of the LDI is given first, followed by the
|
||||||
|
specific instruction with the GRi and GRk filled in as FP and
|
||||||
|
GR15.
|
||||||
|
|
||||||
|
ldi @(GRi, d12), GRk
|
||||||
|
P KKKKKK 0110010 IIIIII SSSSSSSSSSSS = 0x00c80000
|
||||||
|
0 000000 1111111 000000 000000000000 = 0x01fc0000
|
||||||
|
. . . . . . . .
|
||||||
|
ldi @(FP, d12), GR15
|
||||||
|
P KKKKKK 0110010 IIIIII SSSSSSSSSSSS = 0x1ec82000
|
||||||
|
0 001111 1111111 000010 000000000000 = 0x7ffff000
|
||||||
|
. . . . . . . . */
|
||||||
|
|
||||||
|
if ((op & 0x7ffff000) == 0x1ec82000)
|
||||||
|
{
|
||||||
|
pc += 4;
|
||||||
|
if (target_read_memory (pc, buf, 4))
|
||||||
|
return orig_pc;
|
||||||
|
op = extract_unsigned_integer (buf, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The format of an FRV CALL instruction is as follows:
|
||||||
|
|
||||||
|
call label24
|
||||||
|
P HHHHHH 0001111 LLLLLLLLLLLLLLLLLL = 0x003c0000
|
||||||
|
0 000000 1111111 000000000000000000 = 0x01fc0000
|
||||||
|
. . . . . . . .
|
||||||
|
|
||||||
|
where label24 is constructed by concatenating the H bits with the
|
||||||
|
L bits. The call target is PC + (4 * sign_ext(label24)). */
|
||||||
|
|
||||||
|
if ((op & 0x01fc0000) == 0x003c0000)
|
||||||
|
{
|
||||||
|
LONGEST displ;
|
||||||
|
CORE_ADDR call_dest;
|
||||||
|
struct minimal_symbol *s;
|
||||||
|
|
||||||
|
displ = ((op & 0xfe000000) >> 7) | (op & 0x0003ffff);
|
||||||
|
if ((displ & 0x00800000) != 0)
|
||||||
|
displ |= ~((LONGEST) 0x00ffffff);
|
||||||
|
|
||||||
|
call_dest = pc + 4 * displ;
|
||||||
|
s = lookup_minimal_symbol_by_pc (call_dest);
|
||||||
|
|
||||||
|
if (s != NULL
|
||||||
|
&& SYMBOL_LINKAGE_NAME (s) != NULL
|
||||||
|
&& strcmp (SYMBOL_LINKAGE_NAME (s), "__main") == 0)
|
||||||
|
{
|
||||||
|
pc += 4;
|
||||||
|
return pc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return orig_pc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct frv_unwind_cache *
|
static struct frv_unwind_cache *
|
||||||
frv_frame_unwind_cache (struct frame_info *this_frame,
|
frv_frame_unwind_cache (struct frame_info *this_frame,
|
||||||
void **this_prologue_cache)
|
void **this_prologue_cache)
|
||||||
|
@ -1501,6 +1580,7 @@ frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
|
||||||
set_gdbarch_pseudo_register_write (gdbarch, frv_pseudo_register_write);
|
set_gdbarch_pseudo_register_write (gdbarch, frv_pseudo_register_write);
|
||||||
|
|
||||||
set_gdbarch_skip_prologue (gdbarch, frv_skip_prologue);
|
set_gdbarch_skip_prologue (gdbarch, frv_skip_prologue);
|
||||||
|
set_gdbarch_skip_main_prologue (gdbarch, frv_skip_main_prologue);
|
||||||
set_gdbarch_breakpoint_from_pc (gdbarch, frv_breakpoint_from_pc);
|
set_gdbarch_breakpoint_from_pc (gdbarch, frv_breakpoint_from_pc);
|
||||||
set_gdbarch_adjust_breakpoint_address
|
set_gdbarch_adjust_breakpoint_address
|
||||||
(gdbarch, frv_adjust_breakpoint_address);
|
(gdbarch, frv_adjust_breakpoint_address);
|
||||||
|
|
|
@ -124,6 +124,9 @@ fetch_loadmap (CORE_ADDR ldmaddr)
|
||||||
nsegs = extract_unsigned_integer (ext_ldmbuf_partial.nsegs,
|
nsegs = extract_unsigned_integer (ext_ldmbuf_partial.nsegs,
|
||||||
sizeof ext_ldmbuf_partial.nsegs);
|
sizeof ext_ldmbuf_partial.nsegs);
|
||||||
|
|
||||||
|
if (nsegs <= 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
/* Allocate space for the complete (external) loadmap. */
|
/* Allocate space for the complete (external) loadmap. */
|
||||||
ext_ldmbuf_size = sizeof (struct ext_elf32_fdpic_loadmap)
|
ext_ldmbuf_size = sizeof (struct ext_elf32_fdpic_loadmap)
|
||||||
+ (nsegs - 1) * sizeof (struct ext_elf32_fdpic_loadseg);
|
+ (nsegs - 1) * sizeof (struct ext_elf32_fdpic_loadseg);
|
||||||
|
@ -860,16 +863,17 @@ static void
|
||||||
frv_relocate_main_executable (void)
|
frv_relocate_main_executable (void)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
CORE_ADDR exec_addr;
|
CORE_ADDR exec_addr, interp_addr;
|
||||||
struct int_elf32_fdpic_loadmap *ldm;
|
struct int_elf32_fdpic_loadmap *ldm;
|
||||||
struct cleanup *old_chain;
|
struct cleanup *old_chain;
|
||||||
struct section_offsets *new_offsets;
|
struct section_offsets *new_offsets;
|
||||||
int changed;
|
int changed;
|
||||||
struct obj_section *osect;
|
struct obj_section *osect;
|
||||||
|
|
||||||
status = frv_fdpic_loadmap_addresses (target_gdbarch, 0, &exec_addr);
|
status = frv_fdpic_loadmap_addresses (target_gdbarch,
|
||||||
|
&interp_addr, &exec_addr);
|
||||||
|
|
||||||
if (status < 0)
|
if (status < 0 || (exec_addr == 0 && interp_addr == 0))
|
||||||
{
|
{
|
||||||
/* Not using FDPIC ABI, so do nothing. */
|
/* Not using FDPIC ABI, so do nothing. */
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue