/* IBM RS/6000 native-dependent code for GDB, the GNU debugger.
- Copyright 1986, 1987, 1989, 1991, 1992, 1994, 1995, 1996, 1997, 1998
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
This file is part of GDB.
#include "libbfd.h" /* For bfd_cache_lookup (FIXME) */
#include "bfd.h"
#include "gdb-stabs.h"
+#include "regcache.h"
#include <sys/ptrace.h>
#include <sys/reg.h>
if (regno >= FP0_REGNUM && regno <= FPLAST_REGNUM)
{
nr = regno - FP0_REGNUM + FPR0;
- ptrace32 (PT_READ_FPR, inferior_pid, addr, nr, 0);
+ ptrace32 (PT_READ_FPR, PIDGET (inferior_ptid), addr, nr, 0);
}
/* Bogus register number. */
else if (regno > LAST_UISA_SP_REGNUM)
- fprintf_unfiltered (gdb_stderr,
- "gdb error: register no %d not implemented.\n",
- regno);
+ {
+ if (regno >= NUM_REGS)
+ fprintf_unfiltered (gdb_stderr,
+ "gdb error: register no %d not implemented.\n",
+ regno);
+ }
/* Fixed-point registers. */
else
nr = regno;
if (!ARCH64 ())
- *addr = ptrace32 (PT_READ_GPR, inferior_pid, (int *)nr, 0, 0);
+ *addr = ptrace32 (PT_READ_GPR, PIDGET (inferior_ptid), (int *)nr, 0, 0);
else
{
/* PT_READ_GPR requires the buffer parameter to point to long long,
even if the register is really only 32 bits. */
long long buf;
- ptrace64 (PT_READ_GPR, inferior_pid, nr, 0, (int *)&buf);
+ ptrace64 (PT_READ_GPR, PIDGET (inferior_ptid), nr, 0, (int *)&buf);
if (REGISTER_RAW_SIZE (regno) == 8)
memcpy (addr, &buf, 8);
else
if (regno >= FP0_REGNUM && regno <= FPLAST_REGNUM)
{
nr = regno - FP0_REGNUM + FPR0;
- ptrace32 (PT_WRITE_FPR, inferior_pid, addr, nr, 0);
+ ptrace32 (PT_WRITE_FPR, PIDGET (inferior_ptid), addr, nr, 0);
}
/* Bogus register number. */
nr = regno;
if (!ARCH64 ())
- ptrace32 (PT_WRITE_GPR, inferior_pid, (int *)nr, *addr, 0);
+ ptrace32 (PT_WRITE_GPR, PIDGET (inferior_ptid), (int *)nr, *addr, 0);
else
{
/* PT_WRITE_GPR requires the buffer parameter to point to an 8-byte
memcpy (&buf, addr, 8);
else
buf = *addr;
- ptrace64 (PT_WRITE_GPR, inferior_pid, nr, 0, (int *)&buf);
+ ptrace64 (PT_WRITE_GPR, PIDGET (inferior_ptid), nr, 0, (int *)&buf);
}
}
errno = 0;
if (arch64)
- *to = ptrace64 (PT_READ_I, inferior_pid, from, 0, NULL);
+ *to = ptrace64 (PT_READ_I, PIDGET (inferior_ptid), from, 0, NULL);
else
- *to = ptrace32 (PT_READ_I, inferior_pid, (int *)(long) from, 0, NULL);
+ *to = ptrace32 (PT_READ_I, PIDGET (inferior_ptid), (int *)(long) from,
+ 0, NULL);
return !errno;
}
int
child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
- int write, struct target_ops *target)
+ int write, struct mem_attrib *attrib,
+ struct target_ops *target)
{
/* Round starting address down to 32-bit word boundary. */
int mask = sizeof (int) - 1;
/ sizeof (int);
/* Allocate word transfer buffer. */
+ /* FIXME (alloca): This code, cloned from infptrace.c, is unsafe
+ because it uses alloca to allocate a buffer of arbitrary size.
+ For very large xfers, this could crash GDB's stack. */
int *buf = (int *) alloca (count * sizeof (int));
int arch64 = ARCH64 ();
for (i = 0, errno = 0; i < count; i++, addr += sizeof (int))
{
if (arch64)
- ptrace64 (PT_WRITE_D, inferior_pid, addr, buf[i], NULL);
+ ptrace64 (PT_WRITE_D, PIDGET (inferior_ptid), addr, buf[i], NULL);
else
- ptrace32 (PT_WRITE_D, inferior_pid, (int *)(long) addr,
+ ptrace32 (PT_WRITE_D, PIDGET (inferior_ptid), (int *)(long) addr,
buf[i], NULL);
if (errno)
prev_pc = read_pc ();
write_pc (DUMMY_INSN_ADDR);
if (ARCH64 ())
- ret = ptrace64 (PT_CONTINUE, inferior_pid, 1, 0, NULL);
+ ret = ptrace64 (PT_CONTINUE, PIDGET (inferior_ptid), 1, 0, NULL);
else
- ret = ptrace32 (PT_CONTINUE, inferior_pid, (int *)1, 0, NULL);
+ ret = ptrace32 (PT_CONTINUE, PIDGET (inferior_ptid), (int *)1, 0, NULL);
if (ret != 0)
perror ("pt_continue");
{
pid = wait (&status);
}
- while (pid != inferior_pid);
+ while (pid != PIDGET (inferior_ptid));
write_pc (prev_pc);
target_remove_breakpoint (DUMMY_INSN_ADDR, shadow_contents);
return;
objfile = symfile_objfile;
}
+ else if (!vp->loaded)
+ /* If symbols are not yet loaded, offsets are not yet valid. */
+ return;
new_offsets = (struct section_offsets *) alloca (SIZEOF_SECTION_OFFSETS);
for (i = 0; i < objfile->num_sections; ++i)
- ANOFFSET (new_offsets, i) = ANOFFSET (objfile->section_offsets, i);
+ new_offsets->offsets[i] = ANOFFSET (objfile->section_offsets, i);
/* The symbols in the object file are linked to the VMA of the section,
relocate them VMA relative. */
- ANOFFSET (new_offsets, SECT_OFF_TEXT (objfile)) = vp->tstart - vp->tvma;
- ANOFFSET (new_offsets, SECT_OFF_DATA (objfile)) = vp->dstart - vp->dvma;
- ANOFFSET (new_offsets, SECT_OFF_BSS (objfile)) = vp->dstart - vp->dvma;
+ new_offsets->offsets[SECT_OFF_TEXT (objfile)] = vp->tstart - vp->tvma;
+ new_offsets->offsets[SECT_OFF_DATA (objfile)] = vp->dstart - vp->dvma;
+ new_offsets->offsets[SECT_OFF_BSS (objfile)] = vp->dstart - vp->dvma;
objfile_relocate (objfile, new_offsets);
}
return 1;
}
+/* Add symbols for a vmap. Return zero upon error. */
+
+int
+vmap_add_symbols (struct vmap *vp)
+{
+ if (catch_errors (objfile_symbol_add, vp->objfile,
+ "Error while reading shared library symbols:\n",
+ RETURN_MASK_ALL))
+ {
+ /* Note this is only done if symbol reading was successful. */
+ vp->loaded = 1;
+ vmap_symtab (vp);
+ return 1;
+ }
+ return 0;
+}
+
/* Add a new vmap entry based on ldinfo() information.
If ldi->ldinfo_fd is not valid (e.g. this struct ld_info is from a
else
abfd = bfd_fdopenr (objname, gnutarget, fd);
if (!abfd)
- error ("Could not open `%s' as an executable file: %s",
- objname, bfd_errmsg (bfd_get_error ()));
+ {
+ warning ("Could not open `%s' as an executable file: %s",
+ objname, bfd_errmsg (bfd_get_error ()));
+ return NULL;
+ }
/* make sure we have an object file */
if (!last)
{
+ warning ("\"%s\": member \"%s\" missing.", objname, mem);
bfd_close (abfd);
- /* FIXME -- should be error */
- warning ("\"%s\": member \"%s\" missing.", abfd->filename, mem);
- return 0;
+ return NULL;
}
if (!bfd_check_format (last, bfd_object))
{
- bfd_close (last); /* XXX??? */
- goto obj_err;
+ warning ("\"%s\": member \"%s\" not in executable format: %s.",
+ objname, mem, bfd_errmsg (bfd_get_error ()));
+ bfd_close (last);
+ bfd_close (abfd);
+ return NULL;
}
vp = map_vmap (last, abfd);
}
else
{
- obj_err:
+ warning ("\"%s\": not in executable format: %s.",
+ objname, bfd_errmsg (bfd_get_error ()));
bfd_close (abfd);
- error ("\"%s\": not in executable format: %s.",
- objname, bfd_errmsg (bfd_get_error ()));
- /*NOTREACHED */
+ return NULL;
}
obj = allocate_objfile (vp->bfd, 0);
vp->objfile = obj;
-#ifndef SOLIB_SYMBOLS_MANUAL
- if (catch_errors (objfile_symbol_add, obj,
- "Error while reading shared library symbols:\n",
- RETURN_MASK_ALL))
- {
- /* Note this is only done if symbol reading was successful. */
- vmap_symtab (vp);
- vp->loaded = 1;
- }
-#endif
+ /* Always add symbols for the main objfile. */
+ if (vp == vmap || auto_solib_add)
+ vmap_add_symbols (vp);
return vp;
}
\f
running a different copy of the same executable. */
if (symfile_objfile != NULL && !got_exec_file)
{
- warning_begin ();
- fputs_unfiltered ("Symbol file ", gdb_stderr);
- fputs_unfiltered (symfile_objfile->name, gdb_stderr);
- fputs_unfiltered ("\nis not mapped; discarding it.\n\
+ warning ("Symbol file %s\nis not mapped; discarding it.\n\
If in fact that file has symbols which the mapped files listed by\n\
\"info files\" lack, you can load symbols with the \"symbol-file\" or\n\
\"add-symbol-file\" commands (note that you must take care of relocating\n\
-symbols to the proper address).\n", gdb_stderr);
+symbols to the proper address).",
+ symfile_objfile->name);
free_objfile (symfile_objfile);
symfile_objfile = NULL;
}
}
bfd_default_set_arch_mach (&abfd, arch, mach);
- memset (&info, 0, sizeof info);
+ gdbarch_info_init (&info);
info.bfd_arch_info = bfd_get_arch_info (&abfd);
- gdbarch_update (info);
+ if (!gdbarch_update_p (info))
+ {
+ internal_error (__FILE__, __LINE__,
+ "set_host_arch: failed to select architecture");
+ }
}
\f
do
{
size = load_segs * ldisize;
- ldi = (void *) xrealloc (ldi, load_segs * size);
+ ldi = (void *) xrealloc (ldi, size);
#if 0
/* According to my humble theory, AIX has some timing problems and
}
} while (rc == -1);
if (ldi)
- free (ldi);
+ xfree (ldi);
}
\f
/* Core file stuff. */
char *buffer = xmalloc (buffer_size);
struct cleanup *old = make_cleanup (free_current_contents, &buffer);
- /* FIXME, this restriction should not exist. For now, though I'll
- avoid coredumps with error() pending a real fix. */
- if (vmap == NULL)
- error
- ("Can't debug a core file without an executable file (on the RS/6000)");
-
ldinfo_sec = bfd_get_section_by_name (core_bfd, ".ldinfo");
if (ldinfo_sec == NULL)
{
ldi->l32.ldinfo_fd = -1;
/* The first ldinfo is for the exec file, allocated elsewhere. */
- if (offset == 0)
+ if (offset == 0 && vmap != NULL)
vp = vmap;
else
vp = add_vmap (ldi);
+ /* Process next shared library upon error. */
offset += LDI_NEXT (ldi, arch64);
+ if (vp == NULL)
+ continue;
+
vmap_secs (vp, ldi, arch64);
/* Unless this is the exec file,
starting a child process. */
rs6000_set_host_arch_hook = set_host_arch;
- /* For native configurations, where this module is included, inform
- the xcoffsolib module where it can find the function for symbol table
- relocation at runtime. */
- xcoff_relocate_symtab_hook = xcoff_relocate_symtab;
add_core_fns (&rs6000_core_fns);
}