]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - bfd/elfcore.h
* elfcore.h: Add support for core files with multiple threads.
[thirdparty/binutils-gdb.git] / bfd / elfcore.h
1 /* ELF core file support for BFD.
2 Copyright (C) 1995, 1996 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 <signal.h>
23 #include <sys/procfs.h>
24
25 /* Solaris includes the field pr_who that indicates the thread number within
26 the process. */
27
28 #ifdef PIOCOPENLWP
29 #define get_thread(STATUS) ((((prstatus_t *)(STATUS))->pr_who << 16) \
30 | ((prstatus_t *)(STATUS))->pr_pid)
31 #else
32 #define get_thread(STATUS) (((prstatus_t *)(STATUS))->pr_pid)
33 #endif
34 #else
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)
39 #endif
40
41 #ifdef HAVE_SYS_PROCFS_H
42
43 static int did_reg;
44 static int did_reg2;
45
46 static boolean
47 bfd_prstatus (abfd, descdata, descsz, filepos, thread)
48 bfd *abfd;
49 char *descdata;
50 int descsz;
51 long filepos;
52 int thread;
53 {
54 asection *newsect;
55 prstatus_t *status = (prstatus_t *) 0;
56
57 if (descsz == sizeof (prstatus_t))
58 {
59 char secname[100];
60 char *p;
61
62 sprintf (secname, ".reg/%d", thread);
63 p = bfd_alloc (abfd, strlen (secname) + 1);
64 if (!p)
65 return false;
66 strcpy (p, secname);
67
68 newsect = bfd_make_section (abfd, p);
69 if (newsect == NULL)
70 return false;
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)
76 {
77 memcpy (core_prstatus (abfd), descdata, descsz);
78 }
79
80 if (!did_reg++)
81 {
82 asection *regsect;
83
84 regsect = bfd_make_section (abfd, ".reg");
85 if (regsect == NULL)
86 return false;
87 regsect->_raw_size = newsect->_raw_size;
88 regsect->filepos = newsect->filepos;
89 regsect->flags = newsect->flags;
90 regsect->alignment_power = newsect->alignment_power;
91 }
92 }
93 return true;
94 }
95
96 /* Stash a copy of the prpsinfo structure away for future use. */
97
98 static boolean
99 bfd_prpsinfo (abfd, descdata, descsz, filepos)
100 bfd *abfd;
101 char *descdata;
102 int descsz;
103 long filepos;
104 {
105 if (descsz == sizeof (prpsinfo_t))
106 {
107 if ((core_prpsinfo (abfd) = bfd_alloc (abfd, descsz)) == NULL)
108 return false;
109 memcpy (core_prpsinfo (abfd), descdata, descsz);
110 }
111 return true;
112 }
113
114 static boolean
115 bfd_fpregset (abfd, descdata, descsz, filepos, thread)
116 bfd *abfd;
117 char *descdata;
118 int descsz;
119 long filepos;
120 int thread;
121 {
122 asection *newsect;
123 char secname[100];
124 char *p;
125
126 sprintf (secname, ".reg2/%d", thread);
127 p = bfd_alloc (abfd, strlen (secname) + 1);
128 if (!p)
129 return false;
130 strcpy (p, secname);
131
132 newsect = bfd_make_section (abfd, p);
133 if (newsect == NULL)
134 return false;
135 newsect->_raw_size = descsz;
136 newsect->filepos = filepos;
137 newsect->flags = SEC_HAS_CONTENTS;
138 newsect->alignment_power = 2;
139
140 if (!did_reg2++)
141 {
142 asection *regsect;
143
144 regsect = bfd_make_section (abfd, ".reg2");
145 if (regsect == NULL)
146 return false;
147 regsect->_raw_size = newsect->_raw_size;
148 regsect->filepos = newsect->filepos;
149 regsect->flags = newsect->flags;
150 regsect->alignment_power = newsect->alignment_power;
151 }
152
153 return true;
154 }
155
156 #endif /* HAVE_SYS_PROCFS_H */
157
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
162 it exists. */
163
164 char *
165 elf_core_file_failing_command (abfd)
166 bfd *abfd;
167 {
168 #ifdef HAVE_SYS_PROCFS_H
169 if (core_prpsinfo (abfd))
170 {
171 prpsinfo_t *p = core_prpsinfo (abfd);
172 char *scan = p->pr_psargs;
173 while (*scan++)
174 {;
175 }
176 scan -= 2;
177 if ((scan > p->pr_psargs) && (*scan == ' '))
178 {
179 *scan = '\000';
180 }
181 return p->pr_psargs;
182 }
183 #endif
184 return NULL;
185 }
186
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.
190 */
191
192 int
193 elf_core_file_failing_signal (abfd)
194 bfd *abfd;
195 {
196 #ifdef HAVE_SYS_PROCFS_H
197 if (core_prstatus (abfd))
198 {
199 return ((prstatus_t *) (core_prstatus (abfd)))->pr_cursig;
200 }
201 #endif
202 return -1;
203 }
204
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
208 problem.
209 */
210
211 boolean
212 elf_core_file_matches_executable_p (core_bfd, exec_bfd)
213 bfd *core_bfd;
214 bfd *exec_bfd;
215 {
216 #ifdef HAVE_SYS_PROCFS_H
217 char *corename;
218 char *execname;
219 #endif
220
221 /* First, xvecs must match since both are ELF files for the same target. */
222
223 if (core_bfd->xvec != exec_bfd->xvec)
224 {
225 bfd_set_error (bfd_error_system_call);
226 return false;
227 }
228
229 #ifdef HAVE_SYS_PROCFS_H
230
231 /* If no prpsinfo, just return true. Otherwise, grab the last component
232 of the exec'd pathname from the prpsinfo. */
233
234 if (core_prpsinfo (core_bfd))
235 {
236 corename = (((prpsinfo_t *) core_prpsinfo (core_bfd))->pr_fname);
237 }
238 else
239 {
240 return true;
241 }
242
243 /* Find the last component of the executable pathname. */
244
245 if ((execname = strrchr (exec_bfd->filename, '/')) != NULL)
246 {
247 execname++;
248 }
249 else
250 {
251 execname = (char *) exec_bfd->filename;
252 }
253
254 /* See if they match */
255
256 return strcmp (execname, corename) ? false : true;
257
258 #else
259
260 return true;
261
262 #endif /* HAVE_SYS_PROCFS_H */
263 }
264
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.
269
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.
278
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.
284
285 */
286
287 static boolean
288 elf_corefile_note (abfd, hdr)
289 bfd *abfd;
290 Elf_Internal_Phdr *hdr;
291 {
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 */
299 asection *newsect;
300 int thread = 1; /* Current thread number */
301
302 did_reg = 0; /* Non-zero if we made .reg section */
303 did_reg2 = 0; /* Ditto for .reg2 */
304
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)
309 {
310 x_note_p = (Elf_External_Note *) buf;
311 while ((char *) x_note_p < (buf + hdr->p_filesz))
312 {
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);
319 switch (i_note.type)
320 {
321 case NT_PRSTATUS:
322 /* process descdata as prstatus info */
323 thread = get_thread (descdata);
324 if (! bfd_prstatus (abfd, descdata, i_note.descsz, filepos,
325 thread))
326 return false;
327 sectname = NULL;
328 break;
329 case NT_FPREGSET:
330 /* process descdata as fpregset info */
331 if (! bfd_fpregset (abfd, descdata, i_note.descsz, filepos,
332 thread))
333 return false;
334 sectname = NULL;
335 break;
336 case NT_PRPSINFO:
337 /* process descdata as prpsinfo */
338 if (! bfd_prpsinfo (abfd, descdata, i_note.descsz, filepos))
339 return false;
340 sectname = ".prpsinfo";
341 break;
342 default:
343 /* Unknown descriptor, just ignore it. */
344 sectname = NULL;
345 break;
346 }
347 if (sectname != NULL)
348 {
349 newsect = bfd_make_section (abfd, sectname);
350 if (newsect == NULL)
351 return false;
352 newsect->_raw_size = i_note.descsz;
353 newsect->filepos = filepos;
354 newsect->flags = SEC_ALLOC | SEC_HAS_CONTENTS;
355 newsect->alignment_power = 2;
356 }
357 x_note_p = (Elf_External_Note *)
358 (descdata + BFD_ALIGN (i_note.descsz, 4));
359 }
360 }
361 if (buf != NULL)
362 {
363 free (buf);
364 }
365 else if (hdr->p_filesz > 0)
366 {
367 return false;
368 }
369 return true;
370
371 }
372
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.
377
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).
383
384 */
385
386 const bfd_target *
387 elf_core_file_p (abfd)
388 bfd *abfd;
389 {
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;
396
397 /* Read in the ELF header in external format. */
398
399 if (bfd_read ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr))
400 {
401 if (bfd_get_error () != bfd_error_system_call)
402 bfd_set_error (bfd_error_wrong_format);
403 return NULL;
404 }
405
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
410 file). */
411
412 if (elf_file_p (&x_ehdr) == false)
413 {
414 wrong:
415 bfd_set_error (bfd_error_wrong_format);
416 return NULL;
417 }
418
419 /* FIXME, Check EI_VERSION here ! */
420
421 {
422 #if ARCH_SIZE == 32
423 int desired_address_size = ELFCLASS32;
424 #endif
425 #if ARCH_SIZE == 64
426 int desired_address_size = ELFCLASS64;
427 #endif
428
429 if (x_ehdr.e_ident[EI_CLASS] != desired_address_size)
430 goto wrong;
431 }
432
433 /* Switch xvec to match the specified byte order. */
434 switch (x_ehdr.e_ident[EI_DATA])
435 {
436 case ELFDATA2MSB: /* Big-endian */
437 if (! bfd_big_endian (abfd))
438 goto wrong;
439 break;
440 case ELFDATA2LSB: /* Little-endian */
441 if (! bfd_little_endian (abfd))
442 goto wrong;
443 break;
444 case ELFDATANONE: /* No data encoding specified */
445 default: /* Unknown data encoding specified */
446 goto wrong;
447 }
448
449 /* Allocate an instance of the elf_obj_tdata structure and hook it up to
450 the tdata pointer in the bfd. */
451
452 elf_tdata (abfd) =
453 (struct elf_obj_tdata *) bfd_zalloc (abfd, sizeof (struct elf_obj_tdata));
454 if (elf_tdata (abfd) == NULL)
455 return NULL;
456
457 /* FIXME, `wrong' returns from this point onward, leak memory. */
458
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);
462 #if DEBUG & 1
463 elf_debug_file (i_ehdrp);
464 #endif
465
466 ebd = get_elf_backend_data (abfd);
467
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))
473 {
474 const bfd_target * const *target_ptr;
475
476 if (ebd->elf_machine_code != EM_NONE)
477 goto wrong;
478
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++)
482 {
483 struct elf_backend_data *back;
484
485 if ((*target_ptr)->flavour != bfd_target_elf_flavour)
486 continue;
487 back = (struct elf_backend_data *) (*target_ptr)->backend_data;
488 if (back->elf_machine_code == i_ehdrp->e_machine)
489 {
490 /* target_ptr is an ELF backend which matches this
491 object file, so reject the generic ELF target. */
492 goto wrong;
493 }
494 }
495 }
496
497 /* If there is no program header, or the type is not a core file, then
498 we are hosed. */
499 if (i_ehdrp->e_phoff == 0 || i_ehdrp->e_type != ET_CORE)
500 goto wrong;
501
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. */
507
508 if (i_ehdrp->e_phentsize != sizeof (x_phdr))
509 goto wrong;
510 i_phdrp = (Elf_Internal_Phdr *)
511 bfd_alloc (abfd, sizeof (*i_phdrp) * i_ehdrp->e_phnum);
512 if (!i_phdrp)
513 return NULL;
514 if (bfd_seek (abfd, i_ehdrp->e_phoff, SEEK_SET) == -1)
515 return NULL;
516 for (phindex = 0; phindex < i_ehdrp->e_phnum; phindex++)
517 {
518 if (bfd_read ((PTR) & x_phdr, sizeof (x_phdr), 1, abfd)
519 != sizeof (x_phdr))
520 return NULL;
521 elf_swap_phdr_in (abfd, &x_phdr, i_phdrp + phindex);
522 }
523
524 /* Once all of the program headers have been read and converted, we
525 can start processing them. */
526
527 for (phindex = 0; phindex < i_ehdrp->e_phnum; phindex++)
528 {
529 bfd_section_from_phdr (abfd, i_phdrp + phindex, phindex);
530 if ((i_phdrp + phindex)->p_type == PT_NOTE)
531 {
532 if (! elf_corefile_note (abfd, i_phdrp + phindex))
533 return NULL;
534 }
535 }
536
537 /* Remember the entry point specified in the ELF file header. */
538
539 bfd_get_start_address (abfd) = i_ehdrp->e_entry;
540
541 return abfd->xvec;
542 }