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); }
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 struct vmap * add_vmap (LdInfo *ldi) { bfd *abfd, *last; char *mem, *objname, *filename; struct objfile *obj; struct vmap *vp; int fd; ARCH64_DECL (arch64); /* 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. */ filename = LDI_FILENAME (ldi, arch64); mem = filename + strlen (filename) + 1; mem = xstrdup (mem); objname = xstrdup (filename); fd = LDI_FD (ldi, arch64); if (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, fd); if (!abfd) { 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 (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 (strcmp (mem, last->filename) == 0) break; if (!last) { warning (_("\"%s\": member \"%s\" missing."), objname, mem); bfd_close (abfd); return NULL; } if (!bfd_check_format (last, bfd_object)) { 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 { warning (_("\"%s\": not in executable format: %s."), objname, bfd_errmsg (bfd_get_error ())); bfd_close (abfd); return NULL; } obj = allocate_objfile (vp->bfd, 0); vp->objfile = obj; /* Always add symbols for the main objfile. */ if (vp == vmap || auto_solib_add) vmap_add_symbols (vp); return vp; }
static struct vmap * add_vmap (LdInfo *ldi) { bfd *abfd, *last; char *mem, *filename; struct objfile *obj; struct vmap *vp; int fd; ARCH64_DECL (arch64); /* 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. */ filename = LDI_FILENAME (ldi, arch64); mem = filename + strlen (filename) + 1; mem = xstrdup (mem); fd = LDI_FD (ldi, arch64); abfd = gdb_bfd_open (filename, gnutarget, fd < 0 ? -1 : fd); if (!abfd) { warning (_("Could not open `%s' as an executable file: %s"), filename, bfd_errmsg (bfd_get_error ())); return NULL; } /* 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 = gdb_bfd_openr_next_archived_file (abfd, NULL); while (last != NULL) { bfd *next; if (strcmp (mem, last->filename) == 0) break; next = gdb_bfd_openr_next_archived_file (abfd, last); gdb_bfd_unref (last); last = next; } if (!last) { warning (_("\"%s\": member \"%s\" missing."), filename, mem); gdb_bfd_unref (abfd); return NULL; } if (!bfd_check_format (last, bfd_object)) { warning (_("\"%s\": member \"%s\" not in executable format: %s."), filename, mem, bfd_errmsg (bfd_get_error ())); gdb_bfd_unref (last); gdb_bfd_unref (abfd); return NULL; } vp = map_vmap (last, abfd); /* map_vmap acquired a reference to LAST, so we can release ours. */ gdb_bfd_unref (last); } else { warning (_("\"%s\": not in executable format: %s."), filename, bfd_errmsg (bfd_get_error ())); gdb_bfd_unref (abfd); return NULL; } obj = allocate_objfile (vp->bfd, 0); vp->objfile = obj; /* Always add symbols for the main objfile. */ if (vp == vmap || auto_solib_add) vmap_add_symbols (vp); /* Anything needing a reference to ABFD has already acquired it, so release our local reference. */ gdb_bfd_unref (abfd); return vp; }