1 /* ELF core file support for BFD.
2 Copyright 1995 Free Software Foundation, Inc.
4 This file is part of BFD, the Binary File Descriptor library.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19 /* Core file support */
21 #ifdef HAVE_SYS_PROCFS_H /* Some core file support requires host /proc files */
22 #include <sys/procfs.h>
24 #define bfd_prstatus(abfd, descdata, descsz, filepos) true
25 #define bfd_fpregset(abfd, descdata, descsz, filepos) true
26 #define bfd_prpsinfo(abfd, descdata, descsz, filepos) true
29 #ifdef HAVE_SYS_PROCFS_H
32 bfd_prstatus (abfd, descdata, descsz, filepos)
39 prstatus_t *status = (prstatus_t *) 0;
41 if (descsz == sizeof (prstatus_t))
43 newsect = bfd_make_section (abfd, ".reg");
46 newsect->_raw_size = sizeof (status->pr_reg);
47 newsect->filepos = filepos + (long) &status->pr_reg;
48 newsect->flags = SEC_HAS_CONTENTS;
49 newsect->alignment_power = 2;
50 if ((core_prstatus (abfd) = bfd_alloc (abfd, descsz)) != NULL)
52 memcpy (core_prstatus (abfd), descdata, descsz);
58 /* Stash a copy of the prpsinfo structure away for future use. */
61 bfd_prpsinfo (abfd, descdata, descsz, filepos)
67 if (descsz == sizeof (prpsinfo_t))
69 if ((core_prpsinfo (abfd) = bfd_alloc (abfd, descsz)) == NULL)
71 memcpy (core_prpsinfo (abfd), descdata, descsz);
77 bfd_fpregset (abfd, descdata, descsz, filepos)
85 newsect = bfd_make_section (abfd, ".reg2");
88 newsect->_raw_size = descsz;
89 newsect->filepos = filepos;
90 newsect->flags = SEC_HAS_CONTENTS;
91 newsect->alignment_power = 2;
95 #endif /* HAVE_SYS_PROCFS_H */
97 /* Return a pointer to the args (including the command name) that were
98 seen by the program that generated the core dump. Note that for
99 some reason, a spurious space is tacked onto the end of the args
100 in some (at least one anyway) implementations, so strip it off if
104 elf_core_file_failing_command (abfd)
107 #ifdef HAVE_SYS_PROCFS_H
108 if (core_prpsinfo (abfd))
110 prpsinfo_t *p = core_prpsinfo (abfd);
111 char *scan = p->pr_psargs;
116 if ((scan > p->pr_psargs) && (*scan == ' '))
126 /* Return the number of the signal that caused the core dump. Presumably,
127 since we have a core file, we got a signal of some kind, so don't bother
128 checking the other process status fields, just return the signal number.
132 elf_core_file_failing_signal (abfd)
135 #ifdef HAVE_SYS_PROCFS_H
136 if (core_prstatus (abfd))
138 return ((prstatus_t *) (core_prstatus (abfd)))->pr_cursig;
144 /* Check to see if the core file could reasonably be expected to have
145 come for the current executable file. Note that by default we return
146 true unless we find something that indicates that there might be a
151 elf_core_file_matches_executable_p (core_bfd, exec_bfd)
155 #ifdef HAVE_SYS_PROCFS_H
160 /* First, xvecs must match since both are ELF files for the same target. */
162 if (core_bfd->xvec != exec_bfd->xvec)
164 bfd_set_error (bfd_error_system_call);
168 #ifdef HAVE_SYS_PROCFS_H
170 /* If no prpsinfo, just return true. Otherwise, grab the last component
171 of the exec'd pathname from the prpsinfo. */
173 if (core_prpsinfo (core_bfd))
175 corename = (((prpsinfo_t *) core_prpsinfo (core_bfd))->pr_fname);
182 /* Find the last component of the executable pathname. */
184 if ((execname = strrchr (exec_bfd->filename, '/')) != NULL)
190 execname = (char *) exec_bfd->filename;
193 /* See if they match */
195 return strcmp (execname, corename) ? false : true;
201 #endif /* HAVE_SYS_PROCFS_H */
204 /* ELF core files contain a segment of type PT_NOTE, that holds much of
205 the information that would normally be available from the /proc interface
206 for the process, at the time the process dumped core. Currently this
207 includes copies of the prstatus, prpsinfo, and fpregset structures.
209 Since these structures are potentially machine dependent in size and
210 ordering, bfd provides two levels of support for them. The first level,
211 available on all machines since it does not require that the host
212 have /proc support or the relevant include files, is to create a bfd
213 section for each of the prstatus, prpsinfo, and fpregset structures,
214 without any interpretation of their contents. With just this support,
215 the bfd client will have to interpret the structures itself. Even with
216 /proc support, it might want these full structures for it's own reasons.
218 In the second level of support, where HAVE_SYS_PROCFS_H is defined,
219 bfd will pick apart the structures to gather some additional
220 information that clients may want, such as the general register
221 set, the name of the exec'ed file and its arguments, the signal (if
222 any) that caused the core dump, etc.
227 elf_corefile_note (abfd, hdr)
229 Elf_Internal_Phdr *hdr;
231 Elf_External_Note *x_note_p; /* Elf note, external form */
232 Elf_Internal_Note i_note; /* Elf note, internal form */
233 char *buf = NULL; /* Entire note segment contents */
234 char *namedata; /* Name portion of the note */
235 char *descdata; /* Descriptor portion of the note */
236 char *sectname; /* Name to use for new section */
237 long filepos; /* File offset to descriptor data */
240 if (hdr->p_filesz > 0
241 && (buf = (char *) bfd_malloc ((size_t) hdr->p_filesz)) != NULL
242 && bfd_seek (abfd, hdr->p_offset, SEEK_SET) != -1
243 && bfd_read ((PTR) buf, hdr->p_filesz, 1, abfd) == hdr->p_filesz)
245 x_note_p = (Elf_External_Note *) buf;
246 while ((char *) x_note_p < (buf + hdr->p_filesz))
248 i_note.namesz = bfd_h_get_32 (abfd, (bfd_byte *) x_note_p->namesz);
249 i_note.descsz = bfd_h_get_32 (abfd, (bfd_byte *) x_note_p->descsz);
250 i_note.type = bfd_h_get_32 (abfd, (bfd_byte *) x_note_p->type);
251 namedata = x_note_p->name;
252 descdata = namedata + BFD_ALIGN (i_note.namesz, 4);
253 filepos = hdr->p_offset + (descdata - buf);
257 /* process descdata as prstatus info */
258 if (! bfd_prstatus (abfd, descdata, i_note.descsz, filepos))
260 sectname = ".prstatus";
263 /* process descdata as fpregset info */
264 if (! bfd_fpregset (abfd, descdata, i_note.descsz, filepos))
266 sectname = ".fpregset";
269 /* process descdata as prpsinfo */
270 if (! bfd_prpsinfo (abfd, descdata, i_note.descsz, filepos))
272 sectname = ".prpsinfo";
275 /* Unknown descriptor, just ignore it. */
279 if (sectname != NULL)
281 newsect = bfd_make_section (abfd, sectname);
284 newsect->_raw_size = i_note.descsz;
285 newsect->filepos = filepos;
286 newsect->flags = SEC_ALLOC | SEC_HAS_CONTENTS;
287 newsect->alignment_power = 2;
289 x_note_p = (Elf_External_Note *)
290 (descdata + BFD_ALIGN (i_note.descsz, 4));
297 else if (hdr->p_filesz > 0)
305 /* Core files are simply standard ELF formatted files that partition
306 the file using the execution view of the file (program header table)
307 rather than the linking view. In fact, there is no section header
308 table in a core file.
310 The process status information (including the contents of the general
311 register set) and the floating point register set are stored in a
312 segment of type PT_NOTE. We handcraft a couple of extra bfd sections
313 that allow standard bfd access to the general registers (.reg) and the
314 floating point registers (.reg2).
319 elf_core_file_p (abfd)
322 Elf_External_Ehdr x_ehdr; /* Elf file header, external form */
323 Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */
324 Elf_External_Phdr x_phdr; /* Program header table entry, external form */
325 Elf_Internal_Phdr *i_phdrp; /* Program header table, internal form */
326 unsigned int phindex;
327 struct elf_backend_data *ebd;
329 /* Read in the ELF header in external format. */
331 if (bfd_read ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr))
333 if (bfd_get_error () != bfd_error_system_call)
334 bfd_set_error (bfd_error_wrong_format);
338 /* Now check to see if we have a valid ELF file, and one that BFD can
339 make use of. The magic number must match, the address size ('class')
340 and byte-swapping must match our XVEC entry, and it must have a
341 program header table (FIXME: See comments re segments at top of this
344 if (elf_file_p (&x_ehdr) == false)
347 bfd_set_error (bfd_error_wrong_format);
351 /* FIXME, Check EI_VERSION here ! */
355 int desired_address_size = ELFCLASS32;
358 int desired_address_size = ELFCLASS64;
361 if (x_ehdr.e_ident[EI_CLASS] != desired_address_size)
365 /* Switch xvec to match the specified byte order. */
366 switch (x_ehdr.e_ident[EI_DATA])
368 case ELFDATA2MSB: /* Big-endian */
369 if (abfd->xvec->byteorder_big_p == false)
372 case ELFDATA2LSB: /* Little-endian */
373 if (abfd->xvec->byteorder_big_p == true)
376 case ELFDATANONE: /* No data encoding specified */
377 default: /* Unknown data encoding specified */
381 /* Allocate an instance of the elf_obj_tdata structure and hook it up to
382 the tdata pointer in the bfd. */
385 (struct elf_obj_tdata *) bfd_zalloc (abfd, sizeof (struct elf_obj_tdata));
386 if (elf_tdata (abfd) == NULL)
389 /* FIXME, `wrong' returns from this point onward, leak memory. */
391 /* Now that we know the byte order, swap in the rest of the header */
392 i_ehdrp = elf_elfheader (abfd);
393 elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp);
395 elf_debug_file (i_ehdrp);
398 ebd = get_elf_backend_data (abfd);
400 /* Check that the ELF e_machine field matches what this particular
401 BFD format expects. */
402 if (ebd->elf_machine_code != i_ehdrp->e_machine
403 && (ebd->elf_machine_alt1 == 0 || i_ehdrp->e_machine != ebd->elf_machine_alt1)
404 && (ebd->elf_machine_alt2 == 0 || i_ehdrp->e_machine != ebd->elf_machine_alt2))
406 const bfd_target * const *target_ptr;
408 if (ebd->elf_machine_code != EM_NONE)
411 /* This is the generic ELF target. Let it match any ELF target
412 for which we do not have a specific backend. */
413 for (target_ptr = bfd_target_vector; *target_ptr != NULL; target_ptr++)
415 struct elf_backend_data *back;
417 if ((*target_ptr)->flavour != bfd_target_elf_flavour)
419 back = (struct elf_backend_data *) (*target_ptr)->backend_data;
420 if (back->elf_machine_code == i_ehdrp->e_machine)
422 /* target_ptr is an ELF backend which matches this
423 object file, so reject the generic ELF target. */
429 /* If there is no program header, or the type is not a core file, then
431 if (i_ehdrp->e_phoff == 0 || i_ehdrp->e_type != ET_CORE)
434 /* Allocate space for a copy of the program header table in
435 internal form, seek to the program header table in the file,
436 read it in, and convert it to internal form. As a simple sanity
437 check, verify that the what BFD thinks is the size of each program
438 header table entry actually matches the size recorded in the file. */
440 if (i_ehdrp->e_phentsize != sizeof (x_phdr))
442 i_phdrp = (Elf_Internal_Phdr *)
443 bfd_alloc (abfd, sizeof (*i_phdrp) * i_ehdrp->e_phnum);
446 if (bfd_seek (abfd, i_ehdrp->e_phoff, SEEK_SET) == -1)
448 for (phindex = 0; phindex < i_ehdrp->e_phnum; phindex++)
450 if (bfd_read ((PTR) & x_phdr, sizeof (x_phdr), 1, abfd)
453 elf_swap_phdr_in (abfd, &x_phdr, i_phdrp + phindex);
456 /* Once all of the program headers have been read and converted, we
457 can start processing them. */
459 for (phindex = 0; phindex < i_ehdrp->e_phnum; phindex++)
461 bfd_section_from_phdr (abfd, i_phdrp + phindex, phindex);
462 if ((i_phdrp + phindex)->p_type == PT_NOTE)
464 if (! elf_corefile_note (abfd, i_phdrp + phindex))
469 /* Remember the entry point specified in the ELF file header. */
471 bfd_get_start_address (abfd) = i_ehdrp->e_entry;