1 /* ELF core file support for BFD.
2 Copyright (C) 1995, 1996 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 */
23 #include <sys/procfs.h>
25 /* Solaris includes the field pr_who that indicates the thread number within
29 #define get_thread(STATUS) ((((prstatus_t *)(STATUS))->pr_who << 16) \
30 | ((prstatus_t *)(STATUS))->pr_pid)
32 #define get_thread(STATUS) (((prstatus_t *)(STATUS))->pr_pid)
35 #define bfd_prstatus(abfd, descdata, descsz, filepos) true
36 #define bfd_fpregset(abfd, descdata, descsz, filepos) true
37 #define bfd_prpsinfo(abfd, descdata, descsz, filepos) true
38 #define get_thread(STATUS) (1)
41 #ifdef HAVE_SYS_PROCFS_H
47 bfd_prstatus (abfd, descdata, descsz, filepos, thread)
55 prstatus_t *status = (prstatus_t *) 0;
57 if (descsz == sizeof (prstatus_t))
62 sprintf (secname, ".reg/%d", thread);
63 p = bfd_alloc (abfd, strlen (secname) + 1);
68 newsect = bfd_make_section (abfd, p);
71 newsect->_raw_size = sizeof (status->pr_reg);
72 newsect->filepos = filepos + (long) &status->pr_reg;
73 newsect->flags = SEC_HAS_CONTENTS;
74 newsect->alignment_power = 2;
75 if ((core_prstatus (abfd) = bfd_alloc (abfd, descsz)) != NULL)
77 memcpy (core_prstatus (abfd), descdata, descsz);
84 regsect = bfd_make_section (abfd, ".reg");
87 regsect->_raw_size = newsect->_raw_size;
88 regsect->filepos = newsect->filepos;
89 regsect->flags = newsect->flags;
90 regsect->alignment_power = newsect->alignment_power;
96 /* Stash a copy of the prpsinfo structure away for future use. */
99 bfd_prpsinfo (abfd, descdata, descsz, filepos)
105 if (descsz == sizeof (prpsinfo_t))
107 if ((core_prpsinfo (abfd) = bfd_alloc (abfd, descsz)) == NULL)
109 memcpy (core_prpsinfo (abfd), descdata, descsz);
115 bfd_fpregset (abfd, descdata, descsz, filepos, thread)
126 sprintf (secname, ".reg2/%d", thread);
127 p = bfd_alloc (abfd, strlen (secname) + 1);
132 newsect = bfd_make_section (abfd, p);
135 newsect->_raw_size = descsz;
136 newsect->filepos = filepos;
137 newsect->flags = SEC_HAS_CONTENTS;
138 newsect->alignment_power = 2;
144 regsect = bfd_make_section (abfd, ".reg2");
147 regsect->_raw_size = newsect->_raw_size;
148 regsect->filepos = newsect->filepos;
149 regsect->flags = newsect->flags;
150 regsect->alignment_power = newsect->alignment_power;
156 #endif /* HAVE_SYS_PROCFS_H */
158 /* Return a pointer to the args (including the command name) that were
159 seen by the program that generated the core dump. Note that for
160 some reason, a spurious space is tacked onto the end of the args
161 in some (at least one anyway) implementations, so strip it off if
165 elf_core_file_failing_command (abfd)
168 #ifdef HAVE_SYS_PROCFS_H
169 if (core_prpsinfo (abfd))
171 prpsinfo_t *p = core_prpsinfo (abfd);
172 char *scan = p->pr_psargs;
177 if ((scan > p->pr_psargs) && (*scan == ' '))
187 /* Return the number of the signal that caused the core dump. Presumably,
188 since we have a core file, we got a signal of some kind, so don't bother
189 checking the other process status fields, just return the signal number.
193 elf_core_file_failing_signal (abfd)
196 #ifdef HAVE_SYS_PROCFS_H
197 if (core_prstatus (abfd))
199 return ((prstatus_t *) (core_prstatus (abfd)))->pr_cursig;
205 /* Check to see if the core file could reasonably be expected to have
206 come for the current executable file. Note that by default we return
207 true unless we find something that indicates that there might be a
212 elf_core_file_matches_executable_p (core_bfd, exec_bfd)
216 #ifdef HAVE_SYS_PROCFS_H
221 /* First, xvecs must match since both are ELF files for the same target. */
223 if (core_bfd->xvec != exec_bfd->xvec)
225 bfd_set_error (bfd_error_system_call);
229 #ifdef HAVE_SYS_PROCFS_H
231 /* If no prpsinfo, just return true. Otherwise, grab the last component
232 of the exec'd pathname from the prpsinfo. */
234 if (core_prpsinfo (core_bfd))
236 corename = (((prpsinfo_t *) core_prpsinfo (core_bfd))->pr_fname);
243 /* Find the last component of the executable pathname. */
245 if ((execname = strrchr (exec_bfd->filename, '/')) != NULL)
251 execname = (char *) exec_bfd->filename;
254 /* See if they match */
256 return strcmp (execname, corename) ? false : true;
262 #endif /* HAVE_SYS_PROCFS_H */
265 /* ELF core files contain a segment of type PT_NOTE, that holds much of
266 the information that would normally be available from the /proc interface
267 for the process, at the time the process dumped core. Currently this
268 includes copies of the prstatus, prpsinfo, and fpregset structures.
270 Since these structures are potentially machine dependent in size and
271 ordering, bfd provides two levels of support for them. The first level,
272 available on all machines since it does not require that the host
273 have /proc support or the relevant include files, is to create a bfd
274 section for each of the prstatus, prpsinfo, and fpregset structures,
275 without any interpretation of their contents. With just this support,
276 the bfd client will have to interpret the structures itself. Even with
277 /proc support, it might want these full structures for it's own reasons.
279 In the second level of support, where HAVE_SYS_PROCFS_H is defined,
280 bfd will pick apart the structures to gather some additional
281 information that clients may want, such as the general register
282 set, the name of the exec'ed file and its arguments, the signal (if
283 any) that caused the core dump, etc.
288 elf_corefile_note (abfd, hdr)
290 Elf_Internal_Phdr *hdr;
292 Elf_External_Note *x_note_p; /* Elf note, external form */
293 Elf_Internal_Note i_note; /* Elf note, internal form */
294 char *buf = NULL; /* Entire note segment contents */
295 char *namedata; /* Name portion of the note */
296 char *descdata; /* Descriptor portion of the note */
297 char *sectname; /* Name to use for new section */
298 long filepos; /* File offset to descriptor data */
300 int thread = 1; /* Current thread number */
302 did_reg = 0; /* Non-zero if we made .reg section */
303 did_reg2 = 0; /* Ditto for .reg2 */
305 if (hdr->p_filesz > 0
306 && (buf = (char *) bfd_malloc ((size_t) hdr->p_filesz)) != NULL
307 && bfd_seek (abfd, hdr->p_offset, SEEK_SET) != -1
308 && bfd_read ((PTR) buf, hdr->p_filesz, 1, abfd) == hdr->p_filesz)
310 x_note_p = (Elf_External_Note *) buf;
311 while ((char *) x_note_p < (buf + hdr->p_filesz))
313 i_note.namesz = bfd_h_get_32 (abfd, (bfd_byte *) x_note_p->namesz);
314 i_note.descsz = bfd_h_get_32 (abfd, (bfd_byte *) x_note_p->descsz);
315 i_note.type = bfd_h_get_32 (abfd, (bfd_byte *) x_note_p->type);
316 namedata = x_note_p->name;
317 descdata = namedata + BFD_ALIGN (i_note.namesz, 4);
318 filepos = hdr->p_offset + (descdata - buf);
322 /* process descdata as prstatus info */
323 thread = get_thread (descdata);
324 if (! bfd_prstatus (abfd, descdata, i_note.descsz, filepos,
330 /* process descdata as fpregset info */
331 if (! bfd_fpregset (abfd, descdata, i_note.descsz, filepos,
337 /* process descdata as prpsinfo */
338 if (! bfd_prpsinfo (abfd, descdata, i_note.descsz, filepos))
340 sectname = ".prpsinfo";
343 /* Unknown descriptor, just ignore it. */
347 if (sectname != NULL)
349 newsect = bfd_make_section (abfd, sectname);
352 newsect->_raw_size = i_note.descsz;
353 newsect->filepos = filepos;
354 newsect->flags = SEC_ALLOC | SEC_HAS_CONTENTS;
355 newsect->alignment_power = 2;
357 x_note_p = (Elf_External_Note *)
358 (descdata + BFD_ALIGN (i_note.descsz, 4));
365 else if (hdr->p_filesz > 0)
373 /* Core files are simply standard ELF formatted files that partition
374 the file using the execution view of the file (program header table)
375 rather than the linking view. In fact, there is no section header
376 table in a core file.
378 The process status information (including the contents of the general
379 register set) and the floating point register set are stored in a
380 segment of type PT_NOTE. We handcraft a couple of extra bfd sections
381 that allow standard bfd access to the general registers (.reg) and the
382 floating point registers (.reg2).
387 elf_core_file_p (abfd)
390 Elf_External_Ehdr x_ehdr; /* Elf file header, external form */
391 Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form */
392 Elf_External_Phdr x_phdr; /* Program header table entry, external form */
393 Elf_Internal_Phdr *i_phdrp; /* Program header table, internal form */
394 unsigned int phindex;
395 struct elf_backend_data *ebd;
397 /* Read in the ELF header in external format. */
399 if (bfd_read ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr))
401 if (bfd_get_error () != bfd_error_system_call)
402 bfd_set_error (bfd_error_wrong_format);
406 /* Now check to see if we have a valid ELF file, and one that BFD can
407 make use of. The magic number must match, the address size ('class')
408 and byte-swapping must match our XVEC entry, and it must have a
409 program header table (FIXME: See comments re segments at top of this
412 if (elf_file_p (&x_ehdr) == false)
415 bfd_set_error (bfd_error_wrong_format);
419 /* FIXME, Check EI_VERSION here ! */
423 int desired_address_size = ELFCLASS32;
426 int desired_address_size = ELFCLASS64;
429 if (x_ehdr.e_ident[EI_CLASS] != desired_address_size)
433 /* Switch xvec to match the specified byte order. */
434 switch (x_ehdr.e_ident[EI_DATA])
436 case ELFDATA2MSB: /* Big-endian */
437 if (! bfd_big_endian (abfd))
440 case ELFDATA2LSB: /* Little-endian */
441 if (! bfd_little_endian (abfd))
444 case ELFDATANONE: /* No data encoding specified */
445 default: /* Unknown data encoding specified */
449 /* Allocate an instance of the elf_obj_tdata structure and hook it up to
450 the tdata pointer in the bfd. */
453 (struct elf_obj_tdata *) bfd_zalloc (abfd, sizeof (struct elf_obj_tdata));
454 if (elf_tdata (abfd) == NULL)
457 /* FIXME, `wrong' returns from this point onward, leak memory. */
459 /* Now that we know the byte order, swap in the rest of the header */
460 i_ehdrp = elf_elfheader (abfd);
461 elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp);
463 elf_debug_file (i_ehdrp);
466 ebd = get_elf_backend_data (abfd);
468 /* Check that the ELF e_machine field matches what this particular
469 BFD format expects. */
470 if (ebd->elf_machine_code != i_ehdrp->e_machine
471 && (ebd->elf_machine_alt1 == 0 || i_ehdrp->e_machine != ebd->elf_machine_alt1)
472 && (ebd->elf_machine_alt2 == 0 || i_ehdrp->e_machine != ebd->elf_machine_alt2))
474 const bfd_target * const *target_ptr;
476 if (ebd->elf_machine_code != EM_NONE)
479 /* This is the generic ELF target. Let it match any ELF target
480 for which we do not have a specific backend. */
481 for (target_ptr = bfd_target_vector; *target_ptr != NULL; target_ptr++)
483 struct elf_backend_data *back;
485 if ((*target_ptr)->flavour != bfd_target_elf_flavour)
487 back = (struct elf_backend_data *) (*target_ptr)->backend_data;
488 if (back->elf_machine_code == i_ehdrp->e_machine)
490 /* target_ptr is an ELF backend which matches this
491 object file, so reject the generic ELF target. */
497 /* If there is no program header, or the type is not a core file, then
499 if (i_ehdrp->e_phoff == 0 || i_ehdrp->e_type != ET_CORE)
502 /* Allocate space for a copy of the program header table in
503 internal form, seek to the program header table in the file,
504 read it in, and convert it to internal form. As a simple sanity
505 check, verify that the what BFD thinks is the size of each program
506 header table entry actually matches the size recorded in the file. */
508 if (i_ehdrp->e_phentsize != sizeof (x_phdr))
510 i_phdrp = (Elf_Internal_Phdr *)
511 bfd_alloc (abfd, sizeof (*i_phdrp) * i_ehdrp->e_phnum);
514 if (bfd_seek (abfd, i_ehdrp->e_phoff, SEEK_SET) == -1)
516 for (phindex = 0; phindex < i_ehdrp->e_phnum; phindex++)
518 if (bfd_read ((PTR) & x_phdr, sizeof (x_phdr), 1, abfd)
521 elf_swap_phdr_in (abfd, &x_phdr, i_phdrp + phindex);
524 /* Once all of the program headers have been read and converted, we
525 can start processing them. */
527 for (phindex = 0; phindex < i_ehdrp->e_phnum; phindex++)
529 bfd_section_from_phdr (abfd, i_phdrp + phindex, phindex);
530 if ((i_phdrp + phindex)->p_type == PT_NOTE)
532 if (! elf_corefile_note (abfd, i_phdrp + phindex))
537 /* Remember the entry point specified in the ELF file header. */
539 bfd_get_start_address (abfd) = i_ehdrp->e_entry;