diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 3216a62f60..3f5f0554a7 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,20 @@ +Fri Feb 11 16:11:38 1994 Stu Grossman (grossman at cygnus.com) + + * configure.in: Add Lynx/rs6000 support. + * lynx-nat.c: Clean up some Sparc stuff. Clean up ptrace error + messages. Add rs6000 support. Don't try to modify unwritable + registers. + * rs6000-nat.c: Move lots of native dependent stuff (like core + file support) from rs6000-tdep.c & xcoffexec.c to here. + * rs6000-tdep.c: Move native dependent stuff to nat.c. + * xcoffexec.c: Move native dependent stuff to nat.c. + * config/rs6000/nm-rs6000.h: Move defs of SOLIB_* macros to here + from tm file. + * config/rs6000/tm-rs6000.h: Remove defs of SOLIB_* funcs, cuz they're + really native. + * config/rs6000/tm-rs6000lynx.h, config/rs6000/xm-rs6000lynx.h: + New files to support Lynx/rs6000. + Tue Feb 8 00:32:28 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) * README: Remove note about gcc warnings on alpha, these should be diff --git a/gdb/config/rs6000/.Sanitize b/gdb/config/rs6000/.Sanitize index a820c678ac..afe94b11d9 100644 --- a/gdb/config/rs6000/.Sanitize +++ b/gdb/config/rs6000/.Sanitize @@ -22,10 +22,15 @@ Do-first: Things-to-keep: nm-rs6000.h +nm-rs6000lynx.h rs6000.mh +rs6000lynx.mh rs6000.mt +rs6000lynx.mt tm-rs6000.h +tm-rs6000lynx.h xm-rs6000.h +xm-rs6000lynx.h Things-to-lose: diff --git a/gdb/config/rs6000/nm-rs6000lynx.h b/gdb/config/rs6000/nm-rs6000lynx.h new file mode 100644 index 0000000000..0c9701c946 --- /dev/null +++ b/gdb/config/rs6000/nm-rs6000lynx.h @@ -0,0 +1,25 @@ +/* Native-dependent definitions for RS6000 running LynxOS. + Copyright 1993 Free Software Foundation, Inc. + +This file is part of GDB. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef NM_RS6000LYNX_H +#define NM_RS6000LYNX_H + +#include "nm-lynx.h" + +#endif /* NM_RS6000LYNX_H */ diff --git a/gdb/config/rs6000/tm-rs6000lynx.h b/gdb/config/rs6000/tm-rs6000lynx.h new file mode 100644 index 0000000000..cab514d759 --- /dev/null +++ b/gdb/config/rs6000/tm-rs6000lynx.h @@ -0,0 +1,32 @@ +/* Macro definitions for RS6000 running under LynxOS. + Copyright 1993 Free Software Foundation, Inc. + +This file is part of GDB. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef TM_RS6000LYNX_H +#define TM_RS6000LYNX_H + +#include "tm-lynx.h" + +/* Use generic RS6000 definitions. */ +#include "rs6000/tm-rs6000.h" + +#undef PC_LOAD_SEGMENT + +#define CANNOT_STORE_REGISTER(regno) (regno == PS_REGNUM) + +#endif /* TM_RS6000LYNX_H */ diff --git a/gdb/config/rs6000/xm-rs6000lynx.h b/gdb/config/rs6000/xm-rs6000lynx.h new file mode 100644 index 0000000000..035d21826e --- /dev/null +++ b/gdb/config/rs6000/xm-rs6000lynx.h @@ -0,0 +1,29 @@ +/* Host-dependent definitions for RS6000 running LynxOS, for GDB. + Copyright 1993 Free Software Foundation, Inc. + +This file is part of GDB. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef XM_RS6000LYNX_H +#define XM_RS6000LYNX_H + +#define HOST_BYTE_ORDER BIG_ENDIAN + +/* Get generic LynxOS host definitions. */ + +#include "xm-lynx.h" + +#endif /* XM_RS6000LYNX_H */ diff --git a/gdb/configure.in b/gdb/configure.in index 3c2021e258..2547d8b7bc 100644 --- a/gdb/configure.in +++ b/gdb/configure.in @@ -107,6 +107,7 @@ pyramid-*-*) gdb_host=pyramid ;; romp-*-*) gdb_host=rtbsd ;; +rs6000-*-lynxos*) gdb_host=rs6000lynx ;; rs6000-*-*) gdb_host=rs6000 ;; sparc-*-lynxos*) gdb_host=sparclynx ;; @@ -280,6 +281,7 @@ pn-*-*) gdb_target=pn ;; pyramid-*-*) gdb_target=pyramid ;; +rs6000-*-lynxos*) gdb_target=rs6000lynx ;; rs6000-*-*) gdb_target=rs6000 ;; sparc-*-aout*) gdb_target=sparc-em ;; diff --git a/gdb/lynx-nat.c b/gdb/lynx-nat.c index 78cfecbb77..1b40cbdb76 100644 --- a/gdb/lynx-nat.c +++ b/gdb/lynx-nat.c @@ -96,78 +96,86 @@ static int regmap[] = }; #endif -#ifdef SPARC -/* Mappings from tm-sparc.h */ - -#define FX(ENTRY)(offsetof(struct fcontext, ENTRY)) +#ifdef rs6000 static int regmap[] = { - -1, /* g0 */ - X(g1), - X(g2), - X(g3), - X(g4), - -1, /* g5->g7 aren't saved by Lynx */ - -1, - -1, + X(iregs[0]), /* r0 */ + X(iregs[1]), + X(iregs[2]), + X(iregs[3]), + X(iregs[4]), + X(iregs[5]), + X(iregs[6]), + X(iregs[7]), + X(iregs[8]), + X(iregs[9]), + X(iregs[10]), + X(iregs[11]), + X(iregs[12]), + X(iregs[13]), + X(iregs[14]), + X(iregs[15]), + X(iregs[16]), + X(iregs[17]), + X(iregs[18]), + X(iregs[19]), + X(iregs[20]), + X(iregs[21]), + X(iregs[22]), + X(iregs[23]), + X(iregs[24]), + X(iregs[25]), + X(iregs[26]), + X(iregs[27]), + X(iregs[28]), + X(iregs[29]), + X(iregs[30]), + X(iregs[31]), - X(o[0]), - X(o[1]), - X(o[2]), - X(o[3]), - X(o[4]), - X(o[5]), - X(o[6]), /* sp */ - X(o[7]), /* ra */ + X(fregs[0]), /* f0 */ + X(fregs[1]), + X(fregs[2]), + X(fregs[3]), + X(fregs[4]), + X(fregs[5]), + X(fregs[6]), + X(fregs[7]), + X(fregs[8]), + X(fregs[9]), + X(fregs[10]), + X(fregs[11]), + X(fregs[12]), + X(fregs[13]), + X(fregs[14]), + X(fregs[15]), + X(fregs[16]), + X(fregs[17]), + X(fregs[18]), + X(fregs[19]), + X(fregs[20]), + X(fregs[21]), + X(fregs[22]), + X(fregs[23]), + X(fregs[24]), + X(fregs[25]), + X(fregs[26]), + X(fregs[27]), + X(fregs[28]), + X(fregs[29]), + X(fregs[30]), + X(fregs[31]), - -1,-1,-1,-1,-1,-1,-1,-1, /* l0 -> l7 */ - - -1,-1,-1,-1,-1,-1,-1,-1, /* i0 -> i7 */ - - FX(f.fregs[0]), /* f0 */ - FX(f.fregs[1]), - FX(f.fregs[2]), - FX(f.fregs[3]), - FX(f.fregs[4]), - FX(f.fregs[5]), - FX(f.fregs[6]), - FX(f.fregs[7]), - FX(f.fregs[8]), - FX(f.fregs[9]), - FX(f.fregs[10]), - FX(f.fregs[11]), - FX(f.fregs[12]), - FX(f.fregs[13]), - FX(f.fregs[14]), - FX(f.fregs[15]), - FX(f.fregs[16]), - FX(f.fregs[17]), - FX(f.fregs[18]), - FX(f.fregs[19]), - FX(f.fregs[20]), - FX(f.fregs[21]), - FX(f.fregs[22]), - FX(f.fregs[23]), - FX(f.fregs[24]), - FX(f.fregs[25]), - FX(f.fregs[26]), - FX(f.fregs[27]), - FX(f.fregs[28]), - FX(f.fregs[29]), - FX(f.fregs[30]), - FX(f.fregs[31]), - - X(y), - X(psr), - X(wim), - X(tbr), - X(pc), - X(npc), - FX(fsr), /* fpsr */ - -1, /* cpsr */ + X(srr0), /* IAR (PC) */ + X(srr1), /* MSR (PS) */ + X(cr), /* CR */ + X(lr), /* LR */ + X(ctr), /* CTR */ + X(xer), /* XER */ + X(mq) /* MQ */ }; -#endif + +#endif /* rs6000 */ #ifdef SPARC @@ -205,7 +213,7 @@ fetch_inferior_registers (regno) retval = ptrace (PTRACE_GETREGS, inferior_pid, (PTRACE_ARG3_TYPE) &ec, 0); if (errno) - perror_with_name ("Sparc fetch_inferior_registers(ptrace)"); + perror_with_name ("ptrace(PTRACE_GETREGS)"); memset (buf, 0, REGISTER_RAW_SIZE (G0_REGNUM)); supply_register (G0_REGNUM, buf); @@ -258,7 +266,7 @@ fetch_inferior_registers (regno) retval = ptrace (PTRACE_GETFPREGS, inferior_pid, (PTRACE_ARG3_TYPE) &fc, 0); if (errno) - perror_with_name ("Sparc fetch_inferior_registers(ptrace)"); + perror_with_name ("ptrace(PTRACE_GETFPREGS)"); memcpy (®isters[REGISTER_BYTE (FP0_REGNUM)], fc.f.fregs, 32 * REGISTER_RAW_SIZE (FP0_REGNUM)); @@ -315,7 +323,7 @@ store_inferior_registers (regno) retval = ptrace (PTRACE_SETREGS, inferior_pid, (PTRACE_ARG3_TYPE) &ec, 0); if (errno) - perror_with_name ("Sparc fetch_inferior_registers(ptrace)"); + perror_with_name ("ptrace(PTRACE_SETREGS)"); } if (whatregs & WHATREGS_STACK) @@ -362,7 +370,7 @@ store_inferior_registers (regno) retval = ptrace (PTRACE_GETFPREGS, inferior_pid, (PTRACE_ARG3_TYPE) &fc, 0); if (errno) - perror_with_name ("Sparc fetch_inferior_registers(ptrace)"); + perror_with_name ("ptrace(PTRACE_GETFPREGS)"); memcpy (fc.f.fregs, ®isters[REGISTER_BYTE (FP0_REGNUM)], 32 * REGISTER_RAW_SIZE (FP0_REGNUM)); @@ -373,12 +381,12 @@ store_inferior_registers (regno) retval = ptrace (PTRACE_SETFPREGS, inferior_pid, (PTRACE_ARG3_TYPE) &fc, 0); if (errno) - perror_with_name ("Sparc fetch_inferior_registers(ptrace)"); + perror_with_name ("ptrace(PTRACE_SETFPREGS)"); } } #endif /* SPARC */ -#ifndef SPARC +#if defined (I386) || defined (M68K) || defined (rs6000) /* Return the offset relative to the start of the per-thread data to the saved context block. */ @@ -395,12 +403,12 @@ registers_addr(pid) stblock = (CORE_ADDR) ptrace (PTRACE_THREADUSER, pid, (PTRACE_ARG3_TYPE)0, 0); if (errno) - perror_with_name ("registers_addr(PTRACE_THREADUSER)"); + perror_with_name ("ptrace(PTRACE_THREADUSER)"); ecp = (CORE_ADDR) ptrace (PTRACE_PEEKTHREAD, pid, (PTRACE_ARG3_TYPE)ecpoff, 0); if (errno) - perror_with_name ("registers_addr(PTRACE_PEEKTHREAD)"); + perror_with_name ("ptrace(PTRACE_PEEKTHREAD)"); return ecp - stblock; } @@ -432,7 +440,7 @@ fetch_inferior_registers (regno) char buf[MAX_REGISTER_RAW_SIZE]; int ptrace_fun = PTRACE_PEEKTHREAD; -#ifdef PTRACE_PEEKUSP +#ifdef M68K ptrace_fun = regno == SP_REGNUM ? PTRACE_PEEKUSP : PTRACE_PEEKTHREAD; #endif @@ -444,7 +452,7 @@ fetch_inferior_registers (regno) reg = ptrace (ptrace_fun, inferior_pid, (PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), 0); if (errno) - perror_with_name ("fetch_inferior_registers(ptrace)"); + perror_with_name ("ptrace(PTRACE_PEEKUSP)"); *(int *)&buf[i] = reg; } @@ -478,7 +486,10 @@ store_inferior_registers (regno) { int ptrace_fun = PTRACE_POKEUSER; -#ifdef PTRACE_POKEUSP + if (CANNOT_STORE_REGISTER (regno)) + continue; + +#ifdef M68K ptrace_fun = regno == SP_REGNUM ? PTRACE_POKEUSP : PTRACE_POKEUSER; #endif @@ -492,11 +503,11 @@ store_inferior_registers (regno) ptrace (ptrace_fun, inferior_pid, (PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), reg); if (errno) - perror_with_name ("PTRACE_POKEUSER"); + perror_with_name ("ptrace(PTRACE_POKEUSP)"); } } } -#endif /* ifndef SPARC */ +#endif /* defined (I386) || defined (M68K) || defined (rs6000) */ /* Wait for child to do something. Return pid of child, or -1 in case of error; store status through argument pointer OURSTATUS. */ diff --git a/gdb/rs6000-nat.c b/gdb/rs6000-nat.c index 4ffc48c17d..db8c580aa8 100644 --- a/gdb/rs6000-nat.c +++ b/gdb/rs6000-nat.c @@ -20,6 +20,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "defs.h" #include "inferior.h" #include "target.h" +#include "gdbcore.h" +#include "xcoffsolib.h" +#include "symfile.h" +#include "objfiles.h" +#include "libbfd.h" /* BFD internals (sigh!) FIXME */ +#include "bfd.h" #include #include @@ -35,12 +41,19 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include +#include extern int errno; +extern struct vmap * map_vmap PARAMS ((bfd *bf, bfd *arch)); + +extern struct target_ops exec_ops; static void exec_one_dummy_insn PARAMS ((void)); +extern void +add_text_to_loadinfo PARAMS ((CORE_ADDR textaddr, CORE_ADDR dataaddr)); + /* Conversion from gdb-to-system special purpose register numbers.. */ static int special_regs[] = { @@ -246,3 +259,490 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr) else fprintf_unfiltered (gdb_stderr, "Gdb error: unknown parameter to fetch_core_registers().\n"); } + +/* vmap_symtab - handle symbol translation on vmapping */ + +static void +vmap_symtab (vp) + register struct vmap *vp; +{ + register struct objfile *objfile; + asection *textsec; + asection *datasec; + asection *bsssec; + CORE_ADDR text_delta; + CORE_ADDR data_delta; + CORE_ADDR bss_delta; + struct section_offsets *new_offsets; + int i; + + objfile = vp->objfile; + if (objfile == NULL) + { + /* OK, it's not an objfile we opened ourselves. + Currently, that can only happen with the exec file, so + relocate the symbols for the symfile. */ + if (symfile_objfile == NULL) + return; + objfile = symfile_objfile; + } + + new_offsets = alloca + (sizeof (struct section_offsets) + + sizeof (new_offsets->offsets) * objfile->num_sections); + + for (i = 0; i < objfile->num_sections; ++i) + ANOFFSET (new_offsets, i) = ANOFFSET (objfile->section_offsets, i); + + textsec = bfd_get_section_by_name (vp->bfd, ".text"); + text_delta = + vp->tstart - ANOFFSET (objfile->section_offsets, textsec->target_index); + ANOFFSET (new_offsets, textsec->target_index) = vp->tstart; + + datasec = bfd_get_section_by_name (vp->bfd, ".data"); + data_delta = + vp->dstart - ANOFFSET (objfile->section_offsets, datasec->target_index); + ANOFFSET (new_offsets, datasec->target_index) = vp->dstart; + + bsssec = bfd_get_section_by_name (vp->bfd, ".bss"); + bss_delta = + vp->dstart - ANOFFSET (objfile->section_offsets, bsssec->target_index); + ANOFFSET (new_offsets, bsssec->target_index) = vp->dstart; + + objfile_relocate (objfile, new_offsets); + + { + struct obj_section *s; + for (s = objfile->sections; s < objfile->sections_end; ++s) + { + if (s->sec_ptr->target_index == textsec->target_index) + { + s->addr += text_delta; + s->endaddr += text_delta; + } + else if (s->sec_ptr->target_index == datasec->target_index) + { + s->addr += data_delta; + s->endaddr += data_delta; + } + else if (s->sec_ptr->target_index == bsssec->target_index) + { + s->addr += bss_delta; + s->endaddr += bss_delta; + } + } + } + + if (text_delta != 0) + /* breakpoints need to be relocated as well. */ + fixup_breakpoints (0, TEXT_SEGMENT_BASE, text_delta); +} + +/* Add symbols for an objfile. */ +static int +objfile_symbol_add (arg) + char *arg; +{ + struct objfile *obj = (struct objfile *) arg; + syms_from_objfile (obj, 0, 0, 0); + new_symfile_objfile (obj, 0, 0); + return 1; +} + +/* 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 + core file), the caller should set it to -1, and we will open the file. + + Return the vmap new entry. */ +static struct vmap * +add_vmap(ldi) + register struct ld_info *ldi; +{ + bfd *abfd, *last; + register char *mem, *objname; + struct objfile *obj; + struct vmap *vp; + + /* This ldi structure was allocated using alloca() in + xcoff_relocate_symtab(). Now we need to have persistent object + and member names, so we should save them. */ + + mem = ldi->ldinfo_filename + strlen(ldi->ldinfo_filename) + 1; + mem = savestring (mem, strlen (mem)); + objname = savestring (ldi->ldinfo_filename, strlen (ldi->ldinfo_filename)); + + if (ldi->ldinfo_fd < 0) + /* Note that this opens it once for every member; a possible + enhancement would be to only open it once for every object. */ + abfd = bfd_openr (objname, gnutarget); + else + abfd = bfd_fdopenr(objname, gnutarget, ldi->ldinfo_fd); + if (!abfd) + error("Could not open `%s' as an executable file: %s", + objname, bfd_errmsg(bfd_error)); + + + /* make sure we have an object file */ + + if (bfd_check_format(abfd, bfd_object)) + vp = map_vmap (abfd, 0); + + else if (bfd_check_format(abfd, bfd_archive)) { + last = 0; + /* + * FIXME??? am I tossing BFDs? bfd? + */ + while (last = bfd_openr_next_archived_file(abfd, last)) + if (STREQ(mem, last->filename)) + break; + + if (!last) { + bfd_close(abfd); + /* FIXME -- should be error */ + warning("\"%s\": member \"%s\" missing.", abfd->filename, mem); + return; + } + + if (!bfd_check_format(last, bfd_object)) { + bfd_close(last); /* XXX??? */ + goto obj_err; + } + + vp = map_vmap (last, abfd); + } + else { + obj_err: + bfd_close(abfd); + error ("\"%s\": not in executable format: %s.", + objname, bfd_errmsg(bfd_error)); + /*NOTREACHED*/ + } + obj = allocate_objfile (vp->bfd, 0); + vp->objfile = obj; + +#ifndef SOLIB_SYMBOLS_MANUAL + if (catch_errors (objfile_symbol_add, (char *)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 + return vp; +} + +/* + * vmap_ldinfo - update VMAP info with ldinfo() information + * + * Input: + * ldi - ^ to ldinfo() results. + */ + +static void +vmap_ldinfo(ldi) + register struct ld_info *ldi; +{ + struct stat ii, vi; + register struct vmap *vp; + register got_one, retried; + CORE_ADDR ostart; + + /* + * for each *ldi, see if we have a corresponding *vp + * if so, update the mapping, and symbol table. + * if not, add an entry and symbol table. + */ + do { + char *name = ldi->ldinfo_filename; + char *memb = name + strlen(name) + 1; + + retried = 0; + + if (fstat(ldi->ldinfo_fd, &ii) < 0) + fatal("cannot fstat(%d) on %s" + , ldi->ldinfo_fd + , name); +retry: + for (got_one = 0, vp = vmap; vp; vp = vp->nxt) { + FILE *io; + + /* First try to find a `vp', which is the same as in ldinfo. + If not the same, just continue and grep the next `vp'. If same, + relocate its tstart, tend, dstart, dend values. If no such `vp' + found, get out of this for loop, add this ldi entry as a new vmap + (add_vmap) and come back, fins its `vp' and so on... */ + + /* The filenames are not always sufficient to match on. */ + + if ((name[0] == '/' && !STREQ(name, vp->name)) + || (memb[0] && !STREQ(memb, vp->member))) + continue; + + io = bfd_cache_lookup(vp->bfd); /* totally opaque! */ + if (!io) + fatal("cannot find BFD's iostream for %s", vp->name); + + /* see if we are referring to the same file */ + + if (fstat(fileno(io), &vi) < 0) + fatal("cannot fstat BFD for %s", vp->name); + + if (ii.st_dev != vi.st_dev || ii.st_ino != vi.st_ino) + continue; + + if (!retried) + close(ldi->ldinfo_fd); + + ++got_one; + + /* found a corresponding VMAP. remap! */ + ostart = vp->tstart; + + /* We can assume pointer == CORE_ADDR, this code is native only. */ + vp->tstart = (CORE_ADDR) ldi->ldinfo_textorg; + vp->tend = vp->tstart + ldi->ldinfo_textsize; + vp->dstart = (CORE_ADDR) ldi->ldinfo_dataorg; + vp->dend = vp->dstart + ldi->ldinfo_datasize; + + if (vp->tadj) { + vp->tstart += vp->tadj; + vp->tend += vp->tadj; + } + + /* relocate symbol table(s). */ + vmap_symtab (vp); + + /* there may be more, so we don't break out of the loop. */ + } + + /* if there was no matching *vp, we must perforce create the sucker(s) */ + if (!got_one && !retried) { + add_vmap(ldi); + ++retried; + goto retry; + } + } while (ldi->ldinfo_next + && (ldi = (void *) (ldi->ldinfo_next + (char *) ldi))); + +} + +/* As well as symbol tables, exec_sections need relocation. After + the inferior process' termination, there will be a relocated symbol + table exist with no corresponding inferior process. At that time, we + need to use `exec' bfd, rather than the inferior process's memory space + to look up symbols. + + `exec_sections' need to be relocated only once, as long as the exec + file remains unchanged. +*/ + +static void +vmap_exec () +{ + static bfd *execbfd; + int i; + + if (execbfd == exec_bfd) + return; + + execbfd = exec_bfd; + + if (!vmap || !exec_ops.to_sections) + error ("vmap_exec: vmap or exec_ops.to_sections == 0\n"); + + for (i=0; &exec_ops.to_sections[i] < exec_ops.to_sections_end; i++) + { + if (STREQ(".text", exec_ops.to_sections[i].sec_ptr->name)) + { + exec_ops.to_sections[i].addr += vmap->tstart; + exec_ops.to_sections[i].endaddr += vmap->tstart; + } + else if (STREQ(".data", exec_ops.to_sections[i].sec_ptr->name)) + { + exec_ops.to_sections[i].addr += vmap->dstart; + exec_ops.to_sections[i].endaddr += vmap->dstart; + } + } +} + +/* xcoff_relocate_symtab - hook for symbol table relocation. + also reads shared libraries.. */ + +xcoff_relocate_symtab (pid) +unsigned int pid; +{ +#define MAX_LOAD_SEGS 64 /* maximum number of load segments */ + + struct ld_info *ldi; + int temp; + + ldi = (void *) alloca(MAX_LOAD_SEGS * sizeof (*ldi)); + + /* According to my humble theory, AIX has some timing problems and + when the user stack grows, kernel doesn't update stack info in time + and ptrace calls step on user stack. That is why we sleep here a little, + and give kernel to update its internals. */ + + usleep (36000); + + errno = 0; + ptrace(PT_LDINFO, pid, (PTRACE_ARG3_TYPE) ldi, + MAX_LOAD_SEGS * sizeof(*ldi), ldi); + if (errno) { + perror_with_name ("ptrace ldinfo"); + return 0; + } + + vmap_ldinfo(ldi); + + do { + /* We are allowed to assume CORE_ADDR == pointer. This code is + native only. */ + add_text_to_loadinfo ((CORE_ADDR) ldi->ldinfo_textorg, + (CORE_ADDR) ldi->ldinfo_dataorg); + } while (ldi->ldinfo_next + && (ldi = (void *) (ldi->ldinfo_next + (char *) ldi))); + +#if 0 + /* Now that we've jumbled things around, re-sort them. */ + sort_minimal_symbols (); +#endif + + /* relocate the exec and core sections as well. */ + vmap_exec (); +} + +/* Core file stuff. */ + +/* Relocate symtabs and read in shared library info, based on symbols + from the core file. */ +void +xcoff_relocate_core () +{ +/* Offset of member MEMBER in a struct of type TYPE. */ +#ifndef offsetof +#define offsetof(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER) +#endif + +/* Size of a struct ld_info except for the variable-length filename. */ +#define LDINFO_SIZE (offsetof (struct ld_info, ldinfo_filename)) + + sec_ptr ldinfo_sec; + int offset = 0; + struct ld_info *ldip; + struct vmap *vp; + + /* Allocated size of buffer. */ + int buffer_size = LDINFO_SIZE; + 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) + { +bfd_err: + fprintf_filtered (gdb_stderr, "Couldn't get ldinfo from core file: %s\n", + bfd_errmsg (bfd_error)); + do_cleanups (old); + return; + } + do + { + int i; + int names_found = 0; + + /* Read in everything but the name. */ + if (bfd_get_section_contents (core_bfd, ldinfo_sec, buffer, + offset, LDINFO_SIZE) == 0) + goto bfd_err; + + /* Now the name. */ + i = LDINFO_SIZE; + do + { + if (i == buffer_size) + { + buffer_size *= 2; + buffer = xrealloc (buffer, buffer_size); + } + if (bfd_get_section_contents (core_bfd, ldinfo_sec, &buffer[i], + offset + i, 1) == 0) + goto bfd_err; + if (buffer[i++] == '\0') + ++names_found; + } while (names_found < 2); + + ldip = (struct ld_info *)buffer; + + /* Can't use a file descriptor from the core file; need to open it. */ + ldip->ldinfo_fd = -1; + + /* The first ldinfo is for the exec file, allocated elsewhere. */ + if (offset == 0) + vp = vmap; + else + vp = add_vmap (ldip); + + offset += ldip->ldinfo_next; + + /* We can assume pointer == CORE_ADDR, this code is native only. */ + vp->tstart = (CORE_ADDR) ldip->ldinfo_textorg; + vp->tend = vp->tstart + ldip->ldinfo_textsize; + vp->dstart = (CORE_ADDR) ldip->ldinfo_dataorg; + vp->dend = vp->dstart + ldip->ldinfo_datasize; + + if (vp->tadj != 0) { + vp->tstart += vp->tadj; + vp->tend += vp->tadj; + } + + /* Unless this is the exec file, + add our sections to the section table for the core target. */ + if (vp != vmap) + { + int count; + struct section_table *stp; + + count = core_ops.to_sections_end - core_ops.to_sections; + count += 2; + core_ops.to_sections = (struct section_table *) + xrealloc (core_ops.to_sections, + sizeof (struct section_table) * count); + core_ops.to_sections_end = core_ops.to_sections + count; + stp = core_ops.to_sections_end - 2; + + /* "Why do we add bfd_section_vma?", I hear you cry. + Well, the start of the section in the file is actually + that far into the section as the struct vmap understands it. + So for text sections, bfd_section_vma tends to be 0x200, + and if vp->tstart is 0xd0002000, then the first byte of + the text section on disk corresponds to address 0xd0002200. */ + stp->bfd = vp->bfd; + stp->sec_ptr = bfd_get_section_by_name (stp->bfd, ".text"); + stp->addr = bfd_section_vma (stp->bfd, stp->sec_ptr) + vp->tstart; + stp->endaddr = bfd_section_vma (stp->bfd, stp->sec_ptr) + vp->tend; + stp++; + + stp->bfd = vp->bfd; + stp->sec_ptr = bfd_get_section_by_name (stp->bfd, ".data"); + stp->addr = bfd_section_vma (stp->bfd, stp->sec_ptr) + vp->dstart; + stp->endaddr = bfd_section_vma (stp->bfd, stp->sec_ptr) + vp->dend; + } + + vmap_symtab (vp); + + add_text_to_loadinfo ((CORE_ADDR)ldip->ldinfo_textorg, + (CORE_ADDR)ldip->ldinfo_dataorg); + } while (ldip->ldinfo_next != 0); + vmap_exec (); + do_cleanups (old); +} diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index fd68f53d50..50a5ee2cce 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -26,19 +26,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "xcoffsolib.h" -#include -#include -#include -#include -#include -#include - #include -#include -#include -#include -#include - extern struct obstack frame_cache_obstack; @@ -515,7 +503,6 @@ pop_frame () set_current_frame (create_new_frame (prev_sp, lr)); } - /* fixup the call sequence of a dummy function, with the real function address. its argumets will be passed by gdb. */ @@ -1108,54 +1095,6 @@ rs6000_frame_chain (thisframe) return fp; } - - -/* xcoff_relocate_symtab - hook for symbol table relocation. - also reads shared libraries.. */ - -xcoff_relocate_symtab (pid) -unsigned int pid; -{ -#define MAX_LOAD_SEGS 64 /* maximum number of load segments */ - - struct ld_info *ldi; - int temp; - - ldi = (void *) alloca(MAX_LOAD_SEGS * sizeof (*ldi)); - - /* According to my humble theory, AIX has some timing problems and - when the user stack grows, kernel doesn't update stack info in time - and ptrace calls step on user stack. That is why we sleep here a little, - and give kernel to update its internals. */ - - usleep (36000); - - errno = 0; - ptrace(PT_LDINFO, pid, (PTRACE_ARG3_TYPE) ldi, - MAX_LOAD_SEGS * sizeof(*ldi), ldi); - if (errno) { - perror_with_name ("ptrace ldinfo"); - return 0; - } - - vmap_ldinfo(ldi); - - do { - /* We are allowed to assume CORE_ADDR == pointer. This code is - native only. */ - add_text_to_loadinfo ((CORE_ADDR) ldi->ldinfo_textorg, - (CORE_ADDR) ldi->ldinfo_dataorg); - } while (ldi->ldinfo_next - && (ldi = (void *) (ldi->ldinfo_next + (char *) ldi))); - -#if 0 - /* Now that we've jumbled things around, re-sort them. */ - sort_minimal_symbols (); -#endif - - /* relocate the exec and core sections as well. */ - vmap_exec (); -} /* Keep an array of load segment information and their TOC table addresses. This info will be useful when calling a shared library function by hand. */ @@ -1212,7 +1151,6 @@ xcoff_add_toc_to_loadinfo (unsigned long tocoff) loadinfo [loadinfotocindex++].toc_offset = tocoff; } - void add_text_to_loadinfo (textaddr, dataaddr) CORE_ADDR textaddr; diff --git a/gdb/xcoffexec.c b/gdb/xcoffexec.c index 074df77a2f..fb2aea1594 100644 --- a/gdb/xcoffexec.c +++ b/gdb/xcoffexec.c @@ -29,7 +29,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include -#include #include "frame.h" #include "inferior.h" @@ -39,7 +38,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "symfile.h" #include "objfiles.h" -#include "libbfd.h" /* BFD internals (sigh!) FIXME */ #include "bfd.h" #include "xcoffsolib.h" @@ -51,7 +49,7 @@ file_command PARAMS ((char *, int)); static void exec_close PARAMS ((int)); -static struct vmap * +struct vmap * map_vmap PARAMS ((bfd *, bfd *)); struct section_table *exec_sections, *exec_sections_end; @@ -73,7 +71,6 @@ struct vmap *vmap; /* current vmap */ extern struct target_ops exec_ops; - /* exec_close - done with exec file, clean up all resources. */ static void @@ -124,8 +121,9 @@ exec_close(quitting) * exec_file_command - handle the "exec" command, &c. */ void -exec_file_command(filename, from_tty) -char *filename; +exec_file_command (filename, from_tty) + char *filename; + int from_tty; { target_preopen(from_tty); @@ -134,58 +132,59 @@ char *filename; /* Now open and digest the file the user requested, if any. */ - if (filename) { - char *scratch_pathname; - int scratch_chan; + if (filename) + { + char *scratch_pathname; + int scratch_chan; - filename = tilde_expand(filename); - make_cleanup (free, filename); + filename = tilde_expand(filename); + make_cleanup (free, filename); - scratch_chan = openp(getenv("PATH"), 1, filename, - write_files? O_RDWR: O_RDONLY, 0, - &scratch_pathname); - if (scratch_chan < 0) - perror_with_name(filename); + scratch_chan = openp(getenv("PATH"), 1, filename, + write_files? O_RDWR: O_RDONLY, 0, + &scratch_pathname); + if (scratch_chan < 0) + perror_with_name(filename); - exec_bfd = bfd_fdopenr(scratch_pathname, gnutarget, scratch_chan); - if (!exec_bfd) - error("Could not open `%s' as an executable file: %s" - , scratch_pathname, bfd_errmsg(bfd_error)); + exec_bfd = bfd_fdopenr(scratch_pathname, gnutarget, scratch_chan); + if (!exec_bfd) + error("Could not open `%s' as an executable file: %s", + scratch_pathname, bfd_errmsg(bfd_error)); - /* make sure we have an object file */ + /* make sure we have an object file */ - if (!bfd_check_format(exec_bfd, bfd_object)) - error("\"%s\": not in executable format: %s.", - scratch_pathname, bfd_errmsg(bfd_error)); + if (!bfd_check_format(exec_bfd, bfd_object)) + error("\"%s\": not in executable format: %s.", scratch_pathname, + bfd_errmsg(bfd_error)); + /* setup initial vmap */ - /* setup initial vmap */ + map_vmap (exec_bfd, 0); + if (!vmap) + error("Can't find the file sections in `%s': %s", exec_bfd->filename, + bfd_errmsg(bfd_error)); - map_vmap (exec_bfd, 0); - if (!vmap) - error("Can't find the file sections in `%s': %s", - exec_bfd->filename, bfd_errmsg(bfd_error)); + if (build_section_table (exec_bfd, &exec_ops.to_sections, + &exec_ops.to_sections_end)) + error ("Can't find the file sections in `%s': %s", exec_bfd->filename, + bfd_errmsg (bfd_error)); - if (build_section_table (exec_bfd, &exec_ops.to_sections, - &exec_ops.to_sections_end)) - error ("Can't find the file sections in `%s': %s", - exec_bfd->filename, bfd_errmsg (bfd_error)); + /* make sure core, if present, matches */ + validate_files(); - /* make sure core, if present, matches */ - validate_files(); + push_target(&exec_ops); - push_target(&exec_ops); + /* Tell display code(if any) about the changed file name. */ - /* Tell display code(if any) about the changed file name. */ - - if (exec_file_display_hook) - (*exec_file_display_hook)(filename); - } - else { - exec_close(0); /* just in case */ - if (from_tty) - printf_unfiltered("No exec file now.\n"); - } + if (exec_file_display_hook) + (*exec_file_display_hook)(filename); + } + else + { + exec_close(0); /* just in case */ + if (from_tty) + printf_unfiltered("No exec file now.\n"); + } } /* Set both the exec file and the symbol file, in one command. What a @@ -247,8 +246,11 @@ build_section_table (some_bfd, start, end) return 0; } -void -sex_to_vmap(bfd *bf, sec_ptr sex, PTR arg3) +static void +bfdsec_to_vmap(bf, sect, arg3) + bfd *bf; + sec_ptr sect; + PTR arg3; { struct vmap_and_bfd *vmap_bfd = (struct vmap_and_bfd *)arg3; register struct vmap *vp, **vpp; @@ -256,34 +258,37 @@ sex_to_vmap(bfd *bf, sec_ptr sex, PTR arg3) bfd *arch = vmap_bfd->pbfd; vp = vmap_bfd->pvmap; - if ((bfd_get_section_flags(bf, sex) & SEC_LOAD) == 0) + if ((bfd_get_section_flags(bf, sect) & SEC_LOAD) == 0) return; - if (STREQ(bfd_section_name(bf, sex), ".text")) { - vp->tstart = 0; - vp->tend = vp->tstart + bfd_section_size(bf, sex); + if (STREQ(bfd_section_name(bf, sect), ".text")) + { + vp->tstart = 0; + vp->tend = vp->tstart + bfd_section_size(bf, sect); - /* When it comes to this adjustment value, in contrast to our previous - belief shared objects should behave the same as the main load segment. - This is the offset from the beginning of text section to the first - real instruction. */ + /* When it comes to this adjustment value, in contrast to our previous + belief shared objects should behave the same as the main load segment. + This is the offset from the beginning of text section to the first + real instruction. */ - vp->tadj = sex->filepos - bfd_section_vma(bf, sex); - } - - else if (STREQ(bfd_section_name(bf, sex), ".data")) { - vp->dstart = 0; - vp->dend = vp->dstart + bfd_section_size(bf, sex); - } - - else if (STREQ(bfd_section_name(bf, sex), ".bss")) /* FIXMEmgo */ + vp->tadj = sect->filepos - bfd_section_vma(bf, sect); + } + else if (STREQ(bfd_section_name(bf, sect), ".data")) + { + vp->dstart = 0; + vp->dend = vp->dstart + bfd_section_size(bf, sect); + } + else if (STREQ(bfd_section_name(bf, sect), ".bss")) /* FIXMEmgo */ printf_unfiltered ("bss section in exec! Don't know what the heck to do!\n"); } /* Make a vmap for the BFD "bf", which might be a member of the archive BFD "arch". Return the new vmap. */ + struct vmap * -map_vmap (bfd *bf, bfd *arch) +map_vmap (bf, arch) + bfd *bf; + bfd *arch; { struct vmap_and_bfd vmap_bfd; struct vmap *vp, **vpp; @@ -298,7 +303,7 @@ map_vmap (bfd *bf, bfd *arch) vmap_bfd.pbfd = arch; vmap_bfd.pvmap = vp; - bfd_map_over_sections (bf, sex_to_vmap, &vmap_bfd); + bfd_map_over_sections (bf, bfdsec_to_vmap, &vmap_bfd); /* find the end of the list, and append. */ for (vpp = &vmap; *vpp; vpp = &(*vpp)->nxt) @@ -308,349 +313,6 @@ map_vmap (bfd *bf, bfd *arch) return vp; } - -/* vmap_symtab - handle symbol translation on vmapping */ - -static void -vmap_symtab (vp) - register struct vmap *vp; -{ - register struct objfile *objfile; - asection *textsec; - asection *datasec; - asection *bsssec; - CORE_ADDR text_delta; - CORE_ADDR data_delta; - CORE_ADDR bss_delta; - struct section_offsets *new_offsets; - int i; - - objfile = vp->objfile; - if (objfile == NULL) - { - /* OK, it's not an objfile we opened ourselves. - Currently, that can only happen with the exec file, so - relocate the symbols for the symfile. */ - if (symfile_objfile == NULL) - return; - objfile = symfile_objfile; - } - - new_offsets = alloca - (sizeof (struct section_offsets) - + sizeof (new_offsets->offsets) * objfile->num_sections); - - for (i = 0; i < objfile->num_sections; ++i) - ANOFFSET (new_offsets, i) = ANOFFSET (objfile->section_offsets, i); - - textsec = bfd_get_section_by_name (vp->bfd, ".text"); - text_delta = - vp->tstart - ANOFFSET (objfile->section_offsets, textsec->target_index); - ANOFFSET (new_offsets, textsec->target_index) = vp->tstart; - - datasec = bfd_get_section_by_name (vp->bfd, ".data"); - data_delta = - vp->dstart - ANOFFSET (objfile->section_offsets, datasec->target_index); - ANOFFSET (new_offsets, datasec->target_index) = vp->dstart; - - bsssec = bfd_get_section_by_name (vp->bfd, ".bss"); - bss_delta = - vp->dstart - ANOFFSET (objfile->section_offsets, bsssec->target_index); - ANOFFSET (new_offsets, bsssec->target_index) = vp->dstart; - - objfile_relocate (objfile, new_offsets); - - { - struct obj_section *s; - for (s = objfile->sections; s < objfile->sections_end; ++s) - { - if (s->sec_ptr->target_index == textsec->target_index) - { - s->addr += text_delta; - s->endaddr += text_delta; - } - else if (s->sec_ptr->target_index == datasec->target_index) - { - s->addr += data_delta; - s->endaddr += data_delta; - } - else if (s->sec_ptr->target_index == bsssec->target_index) - { - s->addr += bss_delta; - s->endaddr += bss_delta; - } - } - } - - if (text_delta != 0) - /* breakpoints need to be relocated as well. */ - fixup_breakpoints (0, TEXT_SEGMENT_BASE, text_delta); -} - -/* Add symbols for an objfile. */ -static int -objfile_symbol_add (arg) - char *arg; -{ - struct objfile *obj = (struct objfile *) arg; - syms_from_objfile (obj, 0, 0, 0); - new_symfile_objfile (obj, 0, 0); - return 1; -} - -static struct vmap *add_vmap PARAMS ((struct ld_info *)); - -/* 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 - core file), the caller should set it to -1, and we will open the file. - - Return the vmap new entry. */ -static struct vmap * -add_vmap(ldi) - register struct ld_info *ldi; -{ - bfd *abfd, *last; - register char *mem, *objname; - struct objfile *obj; - struct vmap *vp; - - /* This ldi structure was allocated using alloca() in - xcoff_relocate_symtab(). Now we need to have persistent object - and member names, so we should save them. */ - - mem = ldi->ldinfo_filename + strlen(ldi->ldinfo_filename) + 1; - mem = savestring (mem, strlen (mem)); - objname = savestring (ldi->ldinfo_filename, strlen (ldi->ldinfo_filename)); - - if (ldi->ldinfo_fd < 0) - /* Note that this opens it once for every member; a possible - enhancement would be to only open it once for every object. */ - abfd = bfd_openr (objname, gnutarget); - else - abfd = bfd_fdopenr(objname, gnutarget, ldi->ldinfo_fd); - if (!abfd) - error("Could not open `%s' as an executable file: %s", - objname, bfd_errmsg(bfd_error)); - - - /* make sure we have an object file */ - - if (bfd_check_format(abfd, bfd_object)) - vp = map_vmap (abfd, 0); - - else if (bfd_check_format(abfd, bfd_archive)) { - last = 0; - /* - * FIXME??? am I tossing BFDs? bfd? - */ - while (last = bfd_openr_next_archived_file(abfd, last)) - if (STREQ(mem, last->filename)) - break; - - if (!last) { - bfd_close(abfd); - /* FIXME -- should be error */ - warning("\"%s\": member \"%s\" missing.", abfd->filename, mem); - return; - } - - if (!bfd_check_format(last, bfd_object)) { - bfd_close(last); /* XXX??? */ - goto obj_err; - } - - vp = map_vmap (last, abfd); - } - else { - obj_err: - bfd_close(abfd); - error ("\"%s\": not in executable format: %s.", - objname, bfd_errmsg(bfd_error)); - /*NOTREACHED*/ - } - obj = allocate_objfile (vp->bfd, 0); - vp->objfile = obj; - -#ifndef SOLIB_SYMBOLS_MANUAL - if (catch_errors (objfile_symbol_add, (char *)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 - return vp; -} - - -/* As well as symbol tables, exec_sections need relocation. After - the inferior process' termination, there will be a relocated symbol - table exist with no corresponding inferior process. At that time, we - need to use `exec' bfd, rather than the inferior process's memory space - to look up symbols. - - `exec_sections' need to be relocated only once, as long as the exec - file remains unchanged. -*/ -vmap_exec () -{ - static bfd *execbfd; - int i; - - if (execbfd == exec_bfd) - return; - - execbfd = exec_bfd; - - if (!vmap || !exec_ops.to_sections) - error ("vmap_exec: vmap or exec_ops.to_sections == 0\n"); - - for (i=0; &exec_ops.to_sections[i] < exec_ops.to_sections_end; i++) - { - if (STREQ(".text", exec_ops.to_sections[i].sec_ptr->name)) - { - exec_ops.to_sections[i].addr += vmap->tstart; - exec_ops.to_sections[i].endaddr += vmap->tstart; - } - else if (STREQ(".data", exec_ops.to_sections[i].sec_ptr->name)) - { - exec_ops.to_sections[i].addr += vmap->dstart; - exec_ops.to_sections[i].endaddr += vmap->dstart; - } - } -} - -#if 0 -/* This was for the old, half-assed, core file support. */ -int -text_adjustment (abfd) -bfd *abfd; -{ - static bfd *execbfd; - static int adjustment; - sec_ptr sect; - - if (exec_bfd == execbfd) - return adjustment; - - sect = bfd_get_section_by_name (abfd, ".text"); - if (sect) - adjustment = sect->filepos - sect->vma; - else - adjustment = 0x200; /* just a wild assumption */ - - return adjustment; -} -#endif - -/* - * vmap_ldinfo - update VMAP info with ldinfo() information - * - * Input: - * ldi - ^ to ldinfo() results. - */ -vmap_ldinfo(ldi) -register struct ld_info *ldi; -{ - struct stat ii, vi; - register struct vmap *vp; - register got_one, retried; - CORE_ADDR ostart; - - /* - * for each *ldi, see if we have a corresponding *vp - * if so, update the mapping, and symbol table. - * if not, add an entry and symbol table. - */ - do { - char *name = ldi->ldinfo_filename; - char *memb = name + strlen(name) + 1; - - retried = 0; - - if (fstat(ldi->ldinfo_fd, &ii) < 0) - fatal("cannot fstat(%d) on %s" - , ldi->ldinfo_fd - , name); -retry: - for (got_one = 0, vp = vmap; vp; vp = vp->nxt) { - FILE *io; - - /* First try to find a `vp', which is the same as in ldinfo. - If not the same, just continue and grep the next `vp'. If same, - relocate its tstart, tend, dstart, dend values. If no such `vp' - found, get out of this for loop, add this ldi entry as a new vmap - (add_vmap) and come back, fins its `vp' and so on... */ - - /* The filenames are not always sufficient to match on. */ - - if ((name[0] == '/' && !STREQ(name, vp->name)) - || (memb[0] && !STREQ(memb, vp->member))) - continue; - - io = bfd_cache_lookup(vp->bfd); /* totally opaque! */ - if (!io) - fatal("cannot find BFD's iostream for %s", vp->name); - - /* see if we are referring to the same file */ - - if (fstat(fileno(io), &vi) < 0) - fatal("cannot fstat BFD for %s", vp->name); - - if (ii.st_dev != vi.st_dev || ii.st_ino != vi.st_ino) - continue; - - if (!retried) - close(ldi->ldinfo_fd); - - ++got_one; - - /* found a corresponding VMAP. remap! */ - ostart = vp->tstart; - - /* We can assume pointer == CORE_ADDR, this code is native only. */ - vp->tstart = (CORE_ADDR) ldi->ldinfo_textorg; - vp->tend = vp->tstart + ldi->ldinfo_textsize; - vp->dstart = (CORE_ADDR) ldi->ldinfo_dataorg; - vp->dend = vp->dstart + ldi->ldinfo_datasize; - - if (vp->tadj) { - vp->tstart += vp->tadj; - vp->tend += vp->tadj; - } - - /* relocate symbol table(s). */ - vmap_symtab (vp); - - /* there may be more, so we don't break out of the loop. */ - } - - /* if there was no matching *vp, we must perforce create the sucker(s) */ - if (!got_one && !retried) { - add_vmap(ldi); - ++retried; - goto retry; - } - } while (ldi->ldinfo_next - && (ldi = (void *) (ldi->ldinfo_next + (char *) ldi))); - -} - -/* - * vmap_inferior - print VMAP info for inferior - */ -vmap_inferior() { - - if (inferior_pid == 0) - return 0; /* normal processing */ - - exec_files_info(); - return 1; -} - /* Read or write the exec file. Args are address within exec file, address within gdb address-space, @@ -890,138 +552,6 @@ Specify the filename of the executable file.", 0, 0, /* section pointers */ OPS_MAGIC, /* Always the last thing */ }; - -/* Core file stuff. */ - -/* Relocate symtabs and read in shared library info, based on symbols - from the core file. */ -void -xcoff_relocate_core () -{ -/* Offset of member MEMBER in a struct of type TYPE. */ -#ifndef offsetof -#define offsetof(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER) -#endif - -/* Size of a struct ld_info except for the variable-length filename. */ -#define LDINFO_SIZE (offsetof (struct ld_info, ldinfo_filename)) - - sec_ptr ldinfo_sec; - int offset = 0; - struct ld_info *ldip; - struct vmap *vp; - - /* Allocated size of buffer. */ - int buffer_size = LDINFO_SIZE; - 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) - { -bfd_err: - fprintf_filtered (gdb_stderr, "Couldn't get ldinfo from core file: %s\n", - bfd_errmsg (bfd_error)); - do_cleanups (old); - return; - } - do - { - int i; - int names_found = 0; - - /* Read in everything but the name. */ - if (bfd_get_section_contents (core_bfd, ldinfo_sec, buffer, - offset, LDINFO_SIZE) == 0) - goto bfd_err; - - /* Now the name. */ - i = LDINFO_SIZE; - do - { - if (i == buffer_size) - { - buffer_size *= 2; - buffer = xrealloc (buffer, buffer_size); - } - if (bfd_get_section_contents (core_bfd, ldinfo_sec, &buffer[i], - offset + i, 1) == 0) - goto bfd_err; - if (buffer[i++] == '\0') - ++names_found; - } while (names_found < 2); - - ldip = (struct ld_info *)buffer; - - /* Can't use a file descriptor from the core file; need to open it. */ - ldip->ldinfo_fd = -1; - - /* The first ldinfo is for the exec file, allocated elsewhere. */ - if (offset == 0) - vp = vmap; - else - vp = add_vmap (ldip); - - offset += ldip->ldinfo_next; - - /* We can assume pointer == CORE_ADDR, this code is native only. */ - vp->tstart = (CORE_ADDR) ldip->ldinfo_textorg; - vp->tend = vp->tstart + ldip->ldinfo_textsize; - vp->dstart = (CORE_ADDR) ldip->ldinfo_dataorg; - vp->dend = vp->dstart + ldip->ldinfo_datasize; - - if (vp->tadj != 0) { - vp->tstart += vp->tadj; - vp->tend += vp->tadj; - } - - /* Unless this is the exec file, - add our sections to the section table for the core target. */ - if (vp != vmap) - { - int count; - struct section_table *stp; - - count = core_ops.to_sections_end - core_ops.to_sections; - count += 2; - core_ops.to_sections = (struct section_table *) - xrealloc (core_ops.to_sections, - sizeof (struct section_table) * count); - core_ops.to_sections_end = core_ops.to_sections + count; - stp = core_ops.to_sections_end - 2; - - /* "Why do we add bfd_section_vma?", I hear you cry. - Well, the start of the section in the file is actually - that far into the section as the struct vmap understands it. - So for text sections, bfd_section_vma tends to be 0x200, - and if vp->tstart is 0xd0002000, then the first byte of - the text section on disk corresponds to address 0xd0002200. */ - stp->bfd = vp->bfd; - stp->sec_ptr = bfd_get_section_by_name (stp->bfd, ".text"); - stp->addr = bfd_section_vma (stp->bfd, stp->sec_ptr) + vp->tstart; - stp->endaddr = bfd_section_vma (stp->bfd, stp->sec_ptr) + vp->tend; - stp++; - - stp->bfd = vp->bfd; - stp->sec_ptr = bfd_get_section_by_name (stp->bfd, ".data"); - stp->addr = bfd_section_vma (stp->bfd, stp->sec_ptr) + vp->dstart; - stp->endaddr = bfd_section_vma (stp->bfd, stp->sec_ptr) + vp->dend; - } - - vmap_symtab (vp); - - add_text_to_loadinfo ((CORE_ADDR)ldip->ldinfo_textorg, - (CORE_ADDR)ldip->ldinfo_dataorg); - } while (ldip->ldinfo_next != 0); - vmap_exec (); - do_cleanups (old); -} void _initialize_exec()