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