* libbfd.c (bfd_malloc, bfd_realloc): New functions.
[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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19 /* Core file support */
20
21 #ifdef HAVE_SYS_PROCFS_H                /* 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_SYS_PROCFS_H
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         return false;
71       memcpy (core_prpsinfo (abfd), descdata, descsz);
72     }
73   return true;
74 }
75
76 static boolean
77 bfd_fpregset (abfd, descdata, descsz, filepos)
78      bfd *abfd;
79      char *descdata;
80      int descsz;
81      long filepos;
82 {
83   asection *newsect;
84
85   newsect = bfd_make_section (abfd, ".reg2");
86   if (newsect == NULL)
87     return false;
88   newsect->_raw_size = descsz;
89   newsect->filepos = filepos;
90   newsect->flags = SEC_HAS_CONTENTS;
91   newsect->alignment_power = 2;
92   return true;
93 }
94
95 #endif /* HAVE_SYS_PROCFS_H */
96
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
101    it exists. */
102
103 char *
104 elf_core_file_failing_command (abfd)
105      bfd *abfd;
106 {
107 #ifdef HAVE_SYS_PROCFS_H
108   if (core_prpsinfo (abfd))
109     {
110       prpsinfo_t *p = core_prpsinfo (abfd);
111       char *scan = p->pr_psargs;
112       while (*scan++)
113         {;
114         }
115       scan -= 2;
116       if ((scan > p->pr_psargs) && (*scan == ' '))
117         {
118           *scan = '\000';
119         }
120       return p->pr_psargs;
121     }
122 #endif
123   return NULL;
124 }
125
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.
129    */
130
131 int
132 elf_core_file_failing_signal (abfd)
133      bfd *abfd;
134 {
135 #ifdef HAVE_SYS_PROCFS_H
136   if (core_prstatus (abfd))
137     {
138       return ((prstatus_t *) (core_prstatus (abfd)))->pr_cursig;
139     }
140 #endif
141   return -1;
142 }
143
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
147    problem.
148    */
149
150 boolean
151 elf_core_file_matches_executable_p (core_bfd, exec_bfd)
152      bfd *core_bfd;
153      bfd *exec_bfd;
154 {
155 #ifdef HAVE_SYS_PROCFS_H
156   char *corename;
157   char *execname;
158 #endif
159
160   /* First, xvecs must match since both are ELF files for the same target. */
161
162   if (core_bfd->xvec != exec_bfd->xvec)
163     {
164       bfd_set_error (bfd_error_system_call);
165       return false;
166     }
167
168 #ifdef HAVE_SYS_PROCFS_H
169
170   /* If no prpsinfo, just return true.  Otherwise, grab the last component
171      of the exec'd pathname from the prpsinfo. */
172
173   if (core_prpsinfo (core_bfd))
174     {
175       corename = (((prpsinfo_t *) core_prpsinfo (core_bfd))->pr_fname);
176     }
177   else
178     {
179       return true;
180     }
181
182   /* Find the last component of the executable pathname. */
183
184   if ((execname = strrchr (exec_bfd->filename, '/')) != NULL)
185     {
186       execname++;
187     }
188   else
189     {
190       execname = (char *) exec_bfd->filename;
191     }
192
193   /* See if they match */
194
195   return strcmp (execname, corename) ? false : true;
196
197 #else
198
199   return true;
200
201 #endif /* HAVE_SYS_PROCFS_H */
202 }
203
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.
208
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.
217
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.
223
224    */
225
226 static boolean
227 elf_corefile_note (abfd, hdr)
228      bfd *abfd;
229      Elf_Internal_Phdr *hdr;
230 {
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 */
238   asection *newsect;
239
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)
244     {
245       x_note_p = (Elf_External_Note *) buf;
246       while ((char *) x_note_p < (buf + hdr->p_filesz))
247         {
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);
254           switch (i_note.type)
255             {
256             case NT_PRSTATUS:
257               /* process descdata as prstatus info */
258               if (! bfd_prstatus (abfd, descdata, i_note.descsz, filepos))
259                 return false;
260               sectname = ".prstatus";
261               break;
262             case NT_FPREGSET:
263               /* process descdata as fpregset info */
264               if (! bfd_fpregset (abfd, descdata, i_note.descsz, filepos))
265                 return false;
266               sectname = ".fpregset";
267               break;
268             case NT_PRPSINFO:
269               /* process descdata as prpsinfo */
270               if (! bfd_prpsinfo (abfd, descdata, i_note.descsz, filepos))
271                 return false;
272               sectname = ".prpsinfo";
273               break;
274             default:
275               /* Unknown descriptor, just ignore it. */
276               sectname = NULL;
277               break;
278             }
279           if (sectname != NULL)
280             {
281               newsect = bfd_make_section (abfd, sectname);
282               if (newsect == NULL)
283                 return false;
284               newsect->_raw_size = i_note.descsz;
285               newsect->filepos = filepos;
286               newsect->flags = SEC_ALLOC | SEC_HAS_CONTENTS;
287               newsect->alignment_power = 2;
288             }
289           x_note_p = (Elf_External_Note *)
290             (descdata + BFD_ALIGN (i_note.descsz, 4));
291         }
292     }
293   if (buf != NULL)
294     {
295       free (buf);
296     }
297   else if (hdr->p_filesz > 0)
298     {
299       return false;
300     }
301   return true;
302
303 }
304
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.
309
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).
315
316  */
317
318 const bfd_target *
319 elf_core_file_p (abfd)
320      bfd *abfd;
321 {
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;
328
329   /* Read in the ELF header in external format.  */
330
331   if (bfd_read ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr))
332     {
333       if (bfd_get_error () != bfd_error_system_call)
334         bfd_set_error (bfd_error_wrong_format);
335       return NULL;
336     }
337
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
342      file). */
343
344   if (elf_file_p (&x_ehdr) == false)
345     {
346     wrong:
347       bfd_set_error (bfd_error_wrong_format);
348       return NULL;
349     }
350
351   /* FIXME, Check EI_VERSION here !  */
352
353   {
354 #if ARCH_SIZE == 32
355     int desired_address_size = ELFCLASS32;
356 #endif
357 #if ARCH_SIZE == 64
358     int desired_address_size = ELFCLASS64;
359 #endif
360
361     if (x_ehdr.e_ident[EI_CLASS] != desired_address_size)
362       goto wrong;
363   }
364
365   /* Switch xvec to match the specified byte order.  */
366   switch (x_ehdr.e_ident[EI_DATA])
367     {
368     case ELFDATA2MSB:           /* Big-endian */
369       if (abfd->xvec->byteorder_big_p == false)
370         goto wrong;
371       break;
372     case ELFDATA2LSB:           /* Little-endian */
373       if (abfd->xvec->byteorder_big_p == true)
374         goto wrong;
375       break;
376     case ELFDATANONE:           /* No data encoding specified */
377     default:                    /* Unknown data encoding specified */
378       goto wrong;
379     }
380
381   /* Allocate an instance of the elf_obj_tdata structure and hook it up to
382      the tdata pointer in the bfd. */
383
384   elf_tdata (abfd) =
385     (struct elf_obj_tdata *) bfd_zalloc (abfd, sizeof (struct elf_obj_tdata));
386   if (elf_tdata (abfd) == NULL)
387     return NULL;
388
389   /* FIXME, `wrong' returns from this point onward, leak memory.  */
390
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);
394 #if DEBUG & 1
395   elf_debug_file (i_ehdrp);
396 #endif
397
398   ebd = get_elf_backend_data (abfd);
399
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))
405     {
406       const bfd_target * const *target_ptr;
407
408       if (ebd->elf_machine_code != EM_NONE)
409         goto wrong;
410
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++)
414         {
415           struct elf_backend_data *back;
416
417           if ((*target_ptr)->flavour != bfd_target_elf_flavour)
418             continue;
419           back = (struct elf_backend_data *) (*target_ptr)->backend_data;
420           if (back->elf_machine_code == i_ehdrp->e_machine)
421             {
422               /* target_ptr is an ELF backend which matches this
423                  object file, so reject the generic ELF target.  */
424               goto wrong;
425             }
426         }
427     }
428
429   /* If there is no program header, or the type is not a core file, then
430      we are hosed. */
431   if (i_ehdrp->e_phoff == 0 || i_ehdrp->e_type != ET_CORE)
432     goto wrong;
433
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. */
439
440   if (i_ehdrp->e_phentsize != sizeof (x_phdr))
441     goto wrong;
442   i_phdrp = (Elf_Internal_Phdr *)
443     bfd_alloc (abfd, sizeof (*i_phdrp) * i_ehdrp->e_phnum);
444   if (!i_phdrp)
445     return NULL;
446   if (bfd_seek (abfd, i_ehdrp->e_phoff, SEEK_SET) == -1)
447     return NULL;
448   for (phindex = 0; phindex < i_ehdrp->e_phnum; phindex++)
449     {
450       if (bfd_read ((PTR) & x_phdr, sizeof (x_phdr), 1, abfd)
451           != sizeof (x_phdr))
452         return NULL;
453       elf_swap_phdr_in (abfd, &x_phdr, i_phdrp + phindex);
454     }
455
456   /* Once all of the program headers have been read and converted, we
457      can start processing them. */
458
459   for (phindex = 0; phindex < i_ehdrp->e_phnum; phindex++)
460     {
461       bfd_section_from_phdr (abfd, i_phdrp + phindex, phindex);
462       if ((i_phdrp + phindex)->p_type == PT_NOTE)
463         {
464           if (! elf_corefile_note (abfd, i_phdrp + phindex))
465             return NULL;
466         }
467     }
468
469   /* Remember the entry point specified in the ELF file header. */
470
471   bfd_get_start_address (abfd) = i_ehdrp->e_entry;
472
473   return abfd->xvec;
474 }