copyright notices
[external/binutils.git] / bfd / elfcore.h
1 /* ELF core file support for BFD.
2    Copyright  1995 Free Software Foundation, Inc.
3
4 This file is part of BFD, the Binary File Descriptor library.
5
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.
10
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.
15
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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
19 /* Core file support */
20
21 #ifdef HAVE_PROCFS              /* Some core file support requires host /proc files */
22 #include <sys/procfs.h>
23 #else
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
27 #endif
28
29 #ifdef HAVE_PROCFS
30
31 static boolean
32 bfd_prstatus (abfd, descdata, descsz, filepos)
33      bfd *abfd;
34      char *descdata;
35      int descsz;
36      long filepos;
37 {
38   asection *newsect;
39   prstatus_t *status = (prstatus_t *) 0;
40
41   if (descsz == sizeof (prstatus_t))
42     {
43       newsect = bfd_make_section (abfd, ".reg");
44       if (newsect == NULL)
45         return false;
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)
51         {
52           memcpy (core_prstatus (abfd), descdata, descsz);
53         }
54     }
55   return true;
56 }
57
58 /* Stash a copy of the prpsinfo structure away for future use. */
59
60 static boolean
61 bfd_prpsinfo (abfd, descdata, descsz, filepos)
62      bfd *abfd;
63      char *descdata;
64      int descsz;
65      long filepos;
66 {
67   if (descsz == sizeof (prpsinfo_t))
68     {
69       if ((core_prpsinfo (abfd) = bfd_alloc (abfd, descsz)) == NULL)
70         {
71           bfd_set_error (bfd_error_no_memory);
72           return false;
73         }
74       memcpy (core_prpsinfo (abfd), descdata, descsz);
75     }
76   return true;
77 }
78
79 static boolean
80 bfd_fpregset (abfd, descdata, descsz, filepos)
81      bfd *abfd;
82      char *descdata;
83      int descsz;
84      long filepos;
85 {
86   asection *newsect;
87
88   newsect = bfd_make_section (abfd, ".reg2");
89   if (newsect == NULL)
90     return false;
91   newsect->_raw_size = descsz;
92   newsect->filepos = filepos;
93   newsect->flags = SEC_HAS_CONTENTS;
94   newsect->alignment_power = 2;
95   return true;
96 }
97
98 #endif /* HAVE_PROCFS */
99
100 /* Return a pointer to the args (including the command name) that were
101    seen by the program that generated the core dump.  Note that for
102    some reason, a spurious space is tacked onto the end of the args
103    in some (at least one anyway) implementations, so strip it off if
104    it exists. */
105
106 char *
107 elf_core_file_failing_command (abfd)
108      bfd *abfd;
109 {
110 #ifdef HAVE_PROCFS
111   if (core_prpsinfo (abfd))
112     {
113       prpsinfo_t *p = core_prpsinfo (abfd);
114       char *scan = p->pr_psargs;
115       while (*scan++)
116         {;
117         }
118       scan -= 2;
119       if ((scan > p->pr_psargs) && (*scan == ' '))
120         {
121           *scan = '\000';
122         }
123       return p->pr_psargs;
124     }
125 #endif
126   return NULL;
127 }
128
129 /* Return the number of the signal that caused the core dump.  Presumably,
130    since we have a core file, we got a signal of some kind, so don't bother
131    checking the other process status fields, just return the signal number.
132    */
133
134 int
135 elf_core_file_failing_signal (abfd)
136      bfd *abfd;
137 {
138 #ifdef HAVE_PROCFS
139   if (core_prstatus (abfd))
140     {
141       return ((prstatus_t *) (core_prstatus (abfd)))->pr_cursig;
142     }
143 #endif
144   return -1;
145 }
146
147 /* Check to see if the core file could reasonably be expected to have
148    come for the current executable file.  Note that by default we return
149    true unless we find something that indicates that there might be a
150    problem.
151    */
152
153 boolean
154 elf_core_file_matches_executable_p (core_bfd, exec_bfd)
155      bfd *core_bfd;
156      bfd *exec_bfd;
157 {
158 #ifdef HAVE_PROCFS
159   char *corename;
160   char *execname;
161 #endif
162
163   /* First, xvecs must match since both are ELF files for the same target. */
164
165   if (core_bfd->xvec != exec_bfd->xvec)
166     {
167       bfd_set_error (bfd_error_system_call);
168       return false;
169     }
170
171 #ifdef HAVE_PROCFS
172
173   /* If no prpsinfo, just return true.  Otherwise, grab the last component
174      of the exec'd pathname from the prpsinfo. */
175
176   if (core_prpsinfo (core_bfd))
177     {
178       corename = (((prpsinfo_t *) core_prpsinfo (core_bfd))->pr_fname);
179     }
180   else
181     {
182       return true;
183     }
184
185   /* Find the last component of the executable pathname. */
186
187   if ((execname = strrchr (exec_bfd->filename, '/')) != NULL)
188     {
189       execname++;
190     }
191   else
192     {
193       execname = (char *) exec_bfd->filename;
194     }
195
196   /* See if they match */
197
198   return strcmp (execname, corename) ? false : true;
199
200 #else
201
202   return true;
203
204 #endif /* HAVE_PROCFS */
205 }
206
207 /* ELF core files contain a segment of type PT_NOTE, that holds much of
208    the information that would normally be available from the /proc interface
209    for the process, at the time the process dumped core.  Currently this
210    includes copies of the prstatus, prpsinfo, and fpregset structures.
211
212    Since these structures are potentially machine dependent in size and
213    ordering, bfd provides two levels of support for them.  The first level,
214    available on all machines since it does not require that the host
215    have /proc support or the relevant include files, is to create a bfd
216    section for each of the prstatus, prpsinfo, and fpregset structures,
217    without any interpretation of their contents.  With just this support,
218    the bfd client will have to interpret the structures itself.  Even with
219    /proc support, it might want these full structures for it's own reasons.
220
221    In the second level of support, where HAVE_PROCFS is defined, bfd will
222    pick apart the structures to gather some additional information that
223    clients may want, such as the general register set, the name of the
224    exec'ed file and its arguments, the signal (if any) that caused the
225    core dump, etc.
226
227    */
228
229 static boolean
230 elf_corefile_note (abfd, hdr)
231      bfd *abfd;
232      Elf_Internal_Phdr *hdr;
233 {
234   Elf_External_Note *x_note_p;  /* Elf note, external form */
235   Elf_Internal_Note i_note;     /* Elf note, internal form */
236   char *buf = NULL;             /* Entire note segment contents */
237   char *namedata;               /* Name portion of the note */
238   char *descdata;               /* Descriptor portion of the note */
239   char *sectname;               /* Name to use for new section */
240   long filepos;                 /* File offset to descriptor data */
241   asection *newsect;
242
243   if (hdr->p_filesz > 0
244       && (buf = (char *) malloc (hdr->p_filesz)) != NULL
245       && bfd_seek (abfd, hdr->p_offset, SEEK_SET) != -1
246       && bfd_read ((PTR) buf, hdr->p_filesz, 1, abfd) == hdr->p_filesz)
247     {
248       x_note_p = (Elf_External_Note *) buf;
249       while ((char *) x_note_p < (buf + hdr->p_filesz))
250         {
251           i_note.namesz = bfd_h_get_32 (abfd, (bfd_byte *) x_note_p->namesz);
252           i_note.descsz = bfd_h_get_32 (abfd, (bfd_byte *) x_note_p->descsz);
253           i_note.type = bfd_h_get_32 (abfd, (bfd_byte *) x_note_p->type);
254           namedata = x_note_p->name;
255           descdata = namedata + BFD_ALIGN (i_note.namesz, 4);
256           filepos = hdr->p_offset + (descdata - buf);
257           switch (i_note.type)
258             {
259             case NT_PRSTATUS:
260               /* process descdata as prstatus info */
261               if (! bfd_prstatus (abfd, descdata, i_note.descsz, filepos))
262                 return false;
263               sectname = ".prstatus";
264               break;
265             case NT_FPREGSET:
266               /* process descdata as fpregset info */
267               if (! bfd_fpregset (abfd, descdata, i_note.descsz, filepos))
268                 return false;
269               sectname = ".fpregset";
270               break;
271             case NT_PRPSINFO:
272               /* process descdata as prpsinfo */
273               if (! bfd_prpsinfo (abfd, descdata, i_note.descsz, filepos))
274                 return false;
275               sectname = ".prpsinfo";
276               break;
277             default:
278               /* Unknown descriptor, just ignore it. */
279               sectname = NULL;
280               break;
281             }
282           if (sectname != NULL)
283             {
284               newsect = bfd_make_section (abfd, sectname);
285               if (newsect == NULL)
286                 return false;
287               newsect->_raw_size = i_note.descsz;
288               newsect->filepos = filepos;
289               newsect->flags = SEC_ALLOC | SEC_HAS_CONTENTS;
290               newsect->alignment_power = 2;
291             }
292           x_note_p = (Elf_External_Note *)
293             (descdata + BFD_ALIGN (i_note.descsz, 4));
294         }
295     }
296   if (buf != NULL)
297     {
298       free (buf);
299     }
300   else if (hdr->p_filesz > 0)
301     {
302       bfd_set_error (bfd_error_no_memory);
303       return false;
304     }
305   return true;
306
307 }
308
309 /*  Core files are simply standard ELF formatted files that partition
310     the file using the execution view of the file (program header table)
311     rather than the linking view.  In fact, there is no section header
312     table in a core file.
313
314     The process status information (including the contents of the general
315     register set) and the floating point register set are stored in a
316     segment of type PT_NOTE.  We handcraft a couple of extra bfd sections
317     that allow standard bfd access to the general registers (.reg) and the
318     floating point registers (.reg2).
319
320  */
321
322 const bfd_target *
323 elf_core_file_p (abfd)
324      bfd *abfd;
325 {
326   Elf_External_Ehdr x_ehdr;     /* Elf file header, external form */
327   Elf_Internal_Ehdr *i_ehdrp;   /* Elf file header, internal form */
328   Elf_External_Phdr x_phdr;     /* Program header table entry, external form */
329   Elf_Internal_Phdr *i_phdrp;   /* Program header table, internal form */
330   unsigned int phindex;
331   struct elf_backend_data *ebd;
332
333   /* Read in the ELF header in external format.  */
334
335   if (bfd_read ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr))
336     {
337       if (bfd_get_error () != bfd_error_system_call)
338         bfd_set_error (bfd_error_wrong_format);
339       return NULL;
340     }
341
342   /* Now check to see if we have a valid ELF file, and one that BFD can
343      make use of.  The magic number must match, the address size ('class')
344      and byte-swapping must match our XVEC entry, and it must have a
345      program header table (FIXME: See comments re segments at top of this
346      file). */
347
348   if (elf_file_p (&x_ehdr) == false)
349     {
350     wrong:
351       bfd_set_error (bfd_error_wrong_format);
352       return NULL;
353     }
354
355   /* FIXME, Check EI_VERSION here !  */
356
357   {
358 #if ARCH_SIZE == 32
359     int desired_address_size = ELFCLASS32;
360 #endif
361 #if ARCH_SIZE == 64
362     int desired_address_size = ELFCLASS64;
363 #endif
364
365     if (x_ehdr.e_ident[EI_CLASS] != desired_address_size)
366       goto wrong;
367   }
368
369   /* Switch xvec to match the specified byte order.  */
370   switch (x_ehdr.e_ident[EI_DATA])
371     {
372     case ELFDATA2MSB:           /* Big-endian */
373       if (abfd->xvec->byteorder_big_p == false)
374         goto wrong;
375       break;
376     case ELFDATA2LSB:           /* Little-endian */
377       if (abfd->xvec->byteorder_big_p == true)
378         goto wrong;
379       break;
380     case ELFDATANONE:           /* No data encoding specified */
381     default:                    /* Unknown data encoding specified */
382       goto wrong;
383     }
384
385   /* Allocate an instance of the elf_obj_tdata structure and hook it up to
386      the tdata pointer in the bfd. */
387
388   elf_tdata (abfd) =
389     (struct elf_obj_tdata *) bfd_zalloc (abfd, sizeof (struct elf_obj_tdata));
390   if (elf_tdata (abfd) == NULL)
391     {
392       bfd_set_error (bfd_error_no_memory);
393       return NULL;
394     }
395
396   /* FIXME, `wrong' returns from this point onward, leak memory.  */
397
398   /* Now that we know the byte order, swap in the rest of the header */
399   i_ehdrp = elf_elfheader (abfd);
400   elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp);
401 #if DEBUG & 1
402   elf_debug_file (i_ehdrp);
403 #endif
404
405   ebd = get_elf_backend_data (abfd);
406
407   /* Check that the ELF e_machine field matches what this particular
408      BFD format expects.  */
409   if (ebd->elf_machine_code != i_ehdrp->e_machine
410       && (ebd->elf_machine_alt1 == 0 || i_ehdrp->e_machine != ebd->elf_machine_alt1)
411       && (ebd->elf_machine_alt2 == 0 || i_ehdrp->e_machine != ebd->elf_machine_alt2))
412     {
413       const bfd_target * const *target_ptr;
414
415       if (ebd->elf_machine_code != EM_NONE)
416         goto wrong;
417
418       /* This is the generic ELF target.  Let it match any ELF target
419          for which we do not have a specific backend.  */
420       for (target_ptr = bfd_target_vector; *target_ptr != NULL; target_ptr++)
421         {
422           struct elf_backend_data *back;
423
424           if ((*target_ptr)->flavour != bfd_target_elf_flavour)
425             continue;
426           back = (struct elf_backend_data *) (*target_ptr)->backend_data;
427           if (back->elf_machine_code == i_ehdrp->e_machine)
428             {
429               /* target_ptr is an ELF backend which matches this
430                  object file, so reject the generic ELF target.  */
431               goto wrong;
432             }
433         }
434     }
435
436   /* If there is no program header, or the type is not a core file, then
437      we are hosed. */
438   if (i_ehdrp->e_phoff == 0 || i_ehdrp->e_type != ET_CORE)
439     goto wrong;
440
441   /* Allocate space for a copy of the program header table in
442      internal form, seek to the program header table in the file,
443      read it in, and convert it to internal form.  As a simple sanity
444      check, verify that the what BFD thinks is the size of each program
445      header table entry actually matches the size recorded in the file. */
446
447   if (i_ehdrp->e_phentsize != sizeof (x_phdr))
448     goto wrong;
449   i_phdrp = (Elf_Internal_Phdr *)
450     bfd_alloc (abfd, sizeof (*i_phdrp) * i_ehdrp->e_phnum);
451   if (!i_phdrp)
452     {
453       bfd_set_error (bfd_error_no_memory);
454       return NULL;
455     }
456   if (bfd_seek (abfd, i_ehdrp->e_phoff, SEEK_SET) == -1)
457     return NULL;
458   for (phindex = 0; phindex < i_ehdrp->e_phnum; phindex++)
459     {
460       if (bfd_read ((PTR) & x_phdr, sizeof (x_phdr), 1, abfd)
461           != sizeof (x_phdr))
462         return NULL;
463       elf_swap_phdr_in (abfd, &x_phdr, i_phdrp + phindex);
464     }
465
466   /* Once all of the program headers have been read and converted, we
467      can start processing them. */
468
469   for (phindex = 0; phindex < i_ehdrp->e_phnum; phindex++)
470     {
471       bfd_section_from_phdr (abfd, i_phdrp + phindex, phindex);
472       if ((i_phdrp + phindex)->p_type == PT_NOTE)
473         {
474           if (! elf_corefile_note (abfd, i_phdrp + phindex))
475             return NULL;
476         }
477     }
478
479   /* Remember the entry point specified in the ELF file header. */
480
481   bfd_get_start_address (abfd) = i_ehdrp->e_entry;
482
483   return abfd->xvec;
484 }