static LONGEST rs6000_xfer_shared_libraries (struct target_ops *ops, enum target_object object, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, LONGEST len) { const int arch64 = ARCH64 (); LdInfo *ldi_data; LdInfo *ldi; struct obstack obstack; const char *buf; LONGEST len_avail; if (writebuf) return -1; /* Get the ldinfo raw data: If debugging a live process, we get it using ptrace. Otherwise, the info is stored in the .ldinfo section of the core file. */ if (target_has_execution) ldi_data = rs6000_ptrace_ldinfo (inferior_ptid); else ldi_data = rs6000_core_ldinfo (core_bfd); /* Convert the raw data into an XML representation. */ obstack_init (&obstack); obstack_grow_str (&obstack, "<library-list version=\"1.0\">\n"); ldi = ldi_data; while (1) { /* Close the fd. We cannot use it, because we cannot assume that the user of this descriptor will be in the same process. */ close (LDI_FD (ldi, arch64)); rs6000_xfer_shared_library (ldi, &obstack); if (!LDI_NEXT (ldi, arch64)) break; ldi = (LdInfo *) ((char *) ldi + LDI_NEXT (ldi, arch64)); } xfree (ldi_data); obstack_grow_str0 (&obstack, "</library-list>\n"); buf = obstack_finish (&obstack); len_avail = strlen (buf); if (offset >= len_avail) len= 0; else { if (len > len_avail - offset) len = len_avail - offset; memcpy (readbuf, buf + offset, len); } obstack_free (&obstack, NULL); return len; }
static void vmap_ldinfo (LdInfo *ldi) { struct stat ii, vi; struct vmap *vp; int got_one, retried; int got_exec_file = 0; uint next; int arch64 = ARCH64 (); /* 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_FILENAME (ldi, arch64); char *memb = name + strlen (name) + 1; int fd = LDI_FD (ldi, arch64); retried = 0; if (fstat (fd, &ii) < 0) { /* The kernel sets ld_info to -1, if the process is still using the object, and the object is removed. Keep the symbol info for the removed object and issue a warning. */ warning (_("%s (fd=%d) has disappeared, keeping its symbols"), name, fd); continue; } retry: for (got_one = 0, vp = vmap; vp; vp = vp->nxt) { struct objfile *objfile; /* 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, find its `vp' and so on... */ /* The filenames are not always sufficient to match on. */ if ((name[0] == '/' && strcmp (name, vp->name) != 0) || (memb[0] && strcmp (memb, vp->member) != 0)) continue; /* See if we are referring to the same file. We have to check objfile->obfd, symfile.c:reread_symbols might have updated the obfd after a change. */ objfile = vp->objfile == NULL ? symfile_objfile : vp->objfile; if (objfile == NULL || objfile->obfd == NULL || bfd_stat (objfile->obfd, &vi) < 0) { warning (_("Unable to stat %s, keeping its symbols"), name); continue; } if (ii.st_dev != vi.st_dev || ii.st_ino != vi.st_ino) continue; if (!retried) close (fd); ++got_one; /* Found a corresponding VMAP. Remap! */ vmap_secs (vp, ldi, arch64); /* The objfile is only NULL for the exec file. */ if (vp->objfile == NULL) got_exec_file = 1; /* relocate symbol table(s). */ vmap_symtab (vp); /* Announce new object files. Doing this after symbol relocation makes aix-thread.c's job easier. */ if (vp->objfile) observer_notify_new_objfile (vp->objfile); /* 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 ((next = LDI_NEXT (ldi, arch64)) && (ldi = (void *) (next + (char *) ldi))); /* If we don't find the symfile_objfile anywhere in the ldinfo, it is unlikely that the symbol file is relocated to the proper address. And we might have attached to a process which is running a different copy of the same executable. */ if (symfile_objfile != NULL && !got_exec_file) { 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)."), symfile_objfile->name); free_objfile (symfile_objfile); gdb_assert (symfile_objfile == NULL); }
void xcoff_relocate_core (struct target_ops *target) { struct bfd_section *ldinfo_sec; int offset = 0; LdInfo *ldi; struct vmap *vp; int arch64 = ARCH64 (); /* Size of a struct ld_info except for the variable-length filename. */ int nonfilesz = (int)LDI_FILENAME ((LdInfo *)0, arch64); /* Allocated size of buffer. */ int buffer_size = nonfilesz; char *buffer = xmalloc (buffer_size); struct cleanup *old = make_cleanup (free_current_contents, &buffer); 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_get_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, nonfilesz) == 0) goto bfd_err; /* Now the name. */ i = nonfilesz; 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); ldi = (LdInfo *) buffer; /* Can't use a file descriptor from the core file; need to open it. */ if (arch64) ldi->l64.ldinfo_fd = -1; else ldi->l32.ldinfo_fd = -1; /* The first ldinfo is for the exec file, allocated elsewhere. */ 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, add our sections to the section table for the core target. */ if (vp != vmap) { struct section_table *stp; target_resize_to_sections (target, 2); stp = target->to_sections_end - 2; stp->bfd = vp->bfd; stp->the_bfd_section = bfd_get_section_by_name (stp->bfd, ".text"); stp->addr = vp->tstart; stp->endaddr = vp->tend; stp++; stp->bfd = vp->bfd; stp->the_bfd_section = bfd_get_section_by_name (stp->bfd, ".data"); stp->addr = vp->dstart; stp->endaddr = vp->dend; } vmap_symtab (vp); if (deprecated_target_new_objfile_hook && vp != vmap && vp->objfile) deprecated_target_new_objfile_hook (vp->objfile); } while (LDI_NEXT (ldi, arch64) != 0); vmap_exec (); breakpoint_re_set (); do_cleanups (old); }