* 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:
Kevin Buettner 2008-11-19 21:17:07 +00:00
parent d0107bb6ae
commit 9bc7b6c67c
3 changed files with 96 additions and 3 deletions

View file

@ -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>
* xtensa-config.c (rmap): Remove entries for ar32 through ar63. Add

View file

@ -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 *
frv_frame_unwind_cache (struct frame_info *this_frame,
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_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_adjust_breakpoint_address
(gdbarch, frv_adjust_breakpoint_address);

View file

@ -124,6 +124,9 @@ fetch_loadmap (CORE_ADDR ldmaddr)
nsegs = extract_unsigned_integer (ext_ldmbuf_partial.nsegs,
sizeof ext_ldmbuf_partial.nsegs);
if (nsegs <= 0)
return NULL;
/* Allocate space for the complete (external) loadmap. */
ext_ldmbuf_size = sizeof (struct ext_elf32_fdpic_loadmap)
+ (nsegs - 1) * sizeof (struct ext_elf32_fdpic_loadseg);
@ -860,16 +863,17 @@ static void
frv_relocate_main_executable (void)
{
int status;
CORE_ADDR exec_addr;
CORE_ADDR exec_addr, interp_addr;
struct int_elf32_fdpic_loadmap *ldm;
struct cleanup *old_chain;
struct section_offsets *new_offsets;
int changed;
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. */
return;