/* Handle FR-V (FDPIC) shared libraries for GDB, the GNU Debugger.
- Copyright (C) 2004, 2007, 2008 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2007, 2008, 2009 Free Software Foundation, Inc.
This file is part of GDB.
#include "command.h"
#include "gdbcmd.h"
#include "elf/frv.h"
+#include "exceptions.h"
/* Flag which indicates whether internal debug messages should be printed. */
static int solib_frv_debug;
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);
unsigned int interp_sect_size;
gdb_byte *buf;
bfd *tmp_bfd = NULL;
- int tmp_fd = -1;
- char *tmp_pathname = NULL;
int status;
CORE_ADDR addr, interp_loadmap_addr;
gdb_byte addr_buf[FRV_PTR_SIZE];
struct int_elf32_fdpic_loadmap *ldm;
+ volatile struct gdb_exception ex;
/* Read the contents of the .interp section into a local buffer;
the contents specify the dynamic linker this program uses. */
be trivial on GNU/Linux). Therefore, we have to try an alternate
mechanism to find the dynamic linker's base address. */
- tmp_fd = solib_open (buf, &tmp_pathname);
- if (tmp_fd >= 0)
- tmp_bfd = bfd_fopen (tmp_pathname, gnutarget, FOPEN_RB, tmp_fd);
-
+ TRY_CATCH (ex, RETURN_MASK_ALL)
+ {
+ tmp_bfd = solib_bfd_open (buf);
+ }
if (tmp_bfd == NULL)
{
enable_break_failure_warning ();
return 0;
}
- /* Make sure the dynamic linker is really a useful object. */
- if (!bfd_check_format (tmp_bfd, bfd_object))
- {
- warning (_("Unable to grok dynamic linker %s as an object file"), buf);
- enable_break_failure_warning ();
- bfd_close (tmp_bfd);
- return 0;
- }
-
- status = frv_fdpic_loadmap_addresses (current_gdbarch,
+ status = frv_fdpic_loadmap_addresses (target_gdbarch,
&interp_loadmap_addr, 0);
if (status < 0)
{
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 (current_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;
osect_idx = osect->the_bfd_section->index;
/* Current address of section. */
- addr = osect->addr;
+ addr = obj_section_addr (osect);
/* Offset from where this section started. */
offset = ANOFFSET (symfile_objfile->section_offsets, osect_idx);
/* Original address prior to any past relocations. */