x86: move fetch error handling into a helper function
[binutils-gdb.git] / bfd / elfcore.h
blob77c240caafae5f741fa747ec83cdf91096567b58
1 /* ELF core file support for BFD.
2 Copyright (C) 1995-2023 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 3 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., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
21 char*
22 elf_core_file_failing_command (bfd *abfd)
24 return elf_tdata (abfd)->core->command;
27 int
28 elf_core_file_failing_signal (bfd *abfd)
30 return elf_tdata (abfd)->core->signal;
33 int
34 elf_core_file_pid (bfd *abfd)
36 return elf_tdata (abfd)->core->pid;
39 bool
40 elf_core_file_matches_executable_p (bfd *core_bfd, bfd *exec_bfd)
42 char* corename;
44 /* xvecs must match if both are ELF files for the same target. */
46 if (core_bfd->xvec != exec_bfd->xvec)
48 bfd_set_error (bfd_error_system_call);
49 return false;
52 /* If both BFDs have identical build-ids, then they match. */
53 if (core_bfd->build_id != NULL
54 && exec_bfd->build_id != NULL
55 && core_bfd->build_id->size == exec_bfd->build_id->size
56 && memcmp (core_bfd->build_id->data, exec_bfd->build_id->data,
57 core_bfd->build_id->size) == 0)
58 return true;
60 /* See if the name in the corefile matches the executable name. */
61 corename = elf_tdata (core_bfd)->core->program;
62 if (corename != NULL)
64 const char* execname = strrchr (bfd_get_filename (exec_bfd), '/');
66 execname = execname ? execname + 1 : bfd_get_filename (exec_bfd);
68 if (strcmp (execname, corename) != 0)
69 return false;
72 return true;
75 /* Core files are simply standard ELF formatted files that partition
76 the file using the execution view of the file (program header table)
77 rather than the linking view. In fact, there is no section header
78 table in a core file.
80 The process status information (including the contents of the general
81 register set) and the floating point register set are stored in a
82 segment of type PT_NOTE. We handcraft a couple of extra bfd sections
83 that allow standard bfd access to the general registers (.reg) and the
84 floating point registers (.reg2). */
86 bfd_cleanup
87 elf_core_file_p (bfd *abfd)
89 Elf_External_Ehdr x_ehdr; /* Elf file header, external form. */
90 Elf_Internal_Ehdr *i_ehdrp; /* Elf file header, internal form. */
91 Elf_Internal_Phdr *i_phdrp; /* Elf program header, internal form. */
92 unsigned int phindex;
93 const struct elf_backend_data *ebd;
94 bfd_size_type amt;
95 ufile_ptr filesize;
97 /* Read in the ELF header in external format. */
98 if (bfd_bread (&x_ehdr, sizeof (x_ehdr), abfd) != sizeof (x_ehdr))
100 if (bfd_get_error () != bfd_error_system_call)
101 goto wrong;
102 else
103 goto fail;
106 /* Check the magic number. */
107 if (! elf_file_p (&x_ehdr))
108 goto wrong;
110 /* FIXME: Check EI_VERSION here ! */
112 /* Check the address size ("class"). */
113 if (x_ehdr.e_ident[EI_CLASS] != ELFCLASS)
114 goto wrong;
116 /* Check the byteorder. */
117 switch (x_ehdr.e_ident[EI_DATA])
119 case ELFDATA2MSB: /* Big-endian. */
120 if (! bfd_big_endian (abfd))
121 goto wrong;
122 break;
123 case ELFDATA2LSB: /* Little-endian. */
124 if (! bfd_little_endian (abfd))
125 goto wrong;
126 break;
127 default:
128 goto wrong;
131 /* Give abfd an elf_obj_tdata. */
132 if (! (*abfd->xvec->_bfd_set_format[bfd_core]) (abfd))
133 goto fail;
135 /* Swap in the rest of the header, now that we have the byte order. */
136 i_ehdrp = elf_elfheader (abfd);
137 elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp);
139 #if DEBUG & 1
140 elf_debug_file (i_ehdrp);
141 #endif
143 ebd = get_elf_backend_data (abfd);
145 /* Check that the ELF e_machine field matches what this particular
146 BFD format expects. */
148 if (ebd->elf_machine_code != i_ehdrp->e_machine
149 && (ebd->elf_machine_alt1 == 0
150 || i_ehdrp->e_machine != ebd->elf_machine_alt1)
151 && (ebd->elf_machine_alt2 == 0
152 || i_ehdrp->e_machine != ebd->elf_machine_alt2)
153 && ebd->elf_machine_code != EM_NONE)
154 goto wrong;
156 if (ebd->elf_machine_code != EM_NONE
157 && i_ehdrp->e_ident[EI_OSABI] != ebd->elf_osabi
158 && ebd->elf_osabi != ELFOSABI_NONE)
159 goto wrong;
161 /* If there is no program header, or the type is not a core file, then
162 we are hosed. */
163 if (i_ehdrp->e_phoff == 0 || i_ehdrp->e_type != ET_CORE)
164 goto wrong;
166 /* Does BFD's idea of the phdr size match the size
167 recorded in the file? */
168 if (i_ehdrp->e_phentsize != sizeof (Elf_External_Phdr))
169 goto wrong;
171 /* If the program header count is PN_XNUM(0xffff), the actual
172 count is in the first section header. */
173 if (i_ehdrp->e_shoff != 0 && i_ehdrp->e_phnum == PN_XNUM)
175 Elf_External_Shdr x_shdr;
176 Elf_Internal_Shdr i_shdr;
177 file_ptr where = (file_ptr) i_ehdrp->e_shoff;
179 if (i_ehdrp->e_shoff < sizeof (x_ehdr))
180 goto wrong;
182 /* Seek to the section header table in the file. */
183 if (bfd_seek (abfd, where, SEEK_SET) != 0)
184 goto fail;
186 /* Read the first section header at index 0, and convert to internal
187 form. */
188 if (bfd_bread (&x_shdr, sizeof (x_shdr), abfd) != sizeof (x_shdr))
189 goto fail;
190 elf_swap_shdr_in (abfd, &x_shdr, &i_shdr);
192 if (i_shdr.sh_info != 0)
194 i_ehdrp->e_phnum = i_shdr.sh_info;
195 if (i_ehdrp->e_phnum != i_shdr.sh_info)
196 goto wrong;
200 /* Sanity check that we can read all of the program headers.
201 It ought to be good enough to just read the last one. */
202 if (i_ehdrp->e_phnum > 1)
204 Elf_External_Phdr x_phdr;
205 Elf_Internal_Phdr i_phdr;
206 file_ptr where;
208 /* Check that we don't have a totally silly number of
209 program headers. */
210 if (i_ehdrp->e_phnum > (unsigned int) -1 / sizeof (x_phdr)
211 || i_ehdrp->e_phnum > (unsigned int) -1 / sizeof (i_phdr))
212 goto wrong;
214 where = (file_ptr)(i_ehdrp->e_phoff + (i_ehdrp->e_phnum - 1) * sizeof (x_phdr));
215 if ((bfd_size_type) where <= i_ehdrp->e_phoff)
216 goto wrong;
218 if (bfd_seek (abfd, where, SEEK_SET) != 0)
219 goto fail;
220 if (bfd_bread (&x_phdr, sizeof (x_phdr), abfd) != sizeof (x_phdr))
221 goto fail;
224 /* Move to the start of the program headers. */
225 if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_phoff, SEEK_SET) != 0)
226 goto wrong;
228 /* Allocate space for the program headers. */
229 amt = sizeof (*i_phdrp) * i_ehdrp->e_phnum;
230 i_phdrp = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt);
231 if (!i_phdrp)
232 goto fail;
234 elf_tdata (abfd)->phdr = i_phdrp;
236 /* Read and convert to internal form. */
237 for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
239 Elf_External_Phdr x_phdr;
241 if (bfd_bread (&x_phdr, sizeof (x_phdr), abfd) != sizeof (x_phdr))
242 goto fail;
244 elf_swap_phdr_in (abfd, &x_phdr, i_phdrp + phindex);
247 /* Set the machine architecture. Do this before processing the
248 program headers since we need to know the architecture type
249 when processing the notes of some systems' core files. */
250 if (! bfd_default_set_arch_mach (abfd, ebd->arch, 0)
251 /* It's OK if this fails for the generic target. */
252 && ebd->elf_machine_code != EM_NONE)
253 goto fail;
255 /* Let the backend double check the format and override global
256 information. We do this before processing the program headers
257 to allow the correct machine (as opposed to just the default
258 machine) to be set, making it possible for grok_prstatus and
259 grok_psinfo to rely on the mach setting. */
260 if (ebd->elf_backend_object_p != NULL
261 && ! ebd->elf_backend_object_p (abfd))
262 goto wrong;
264 /* Process each program header. */
265 for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
266 if (! bfd_section_from_phdr (abfd, i_phdrp + phindex, (int) phindex))
267 goto fail;
269 /* Check for core truncation. */
270 filesize = bfd_get_file_size (abfd);
271 if (filesize != 0)
273 for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
275 Elf_Internal_Phdr *p = i_phdrp + phindex;
276 if (p->p_filesz
277 && (p->p_offset >= filesize
278 || p->p_filesz > filesize - p->p_offset))
280 _bfd_error_handler (_("warning: %pB has a segment "
281 "extending past end of file"), abfd);
282 abfd->read_only = 1;
283 break;
288 /* Save the entry point from the ELF header. */
289 abfd->start_address = i_ehdrp->e_entry;
290 return _bfd_no_cleanup;
292 wrong:
293 bfd_set_error (bfd_error_wrong_format);
294 fail:
295 return NULL;
298 /* Attempt to find a build-id in a core file from the core file BFD.
299 OFFSET is the file offset to a PT_LOAD segment that may contain
300 the build-id note. Returns TRUE upon success, FALSE otherwise. */
302 bool
303 NAME(_bfd_elf, core_find_build_id)
304 (bfd *abfd,
305 bfd_vma offset)
307 Elf_External_Ehdr x_ehdr; /* Elf file header, external form. */
308 Elf_Internal_Ehdr i_ehdr; /* Elf file header, internal form. */
309 Elf_Internal_Phdr *i_phdr;
310 unsigned int i;
311 size_t amt;
313 /* Seek to the position of the segment at OFFSET. */
314 if (bfd_seek (abfd, offset, SEEK_SET) != 0)
315 goto fail;
317 /* Read in the ELF header in external format. */
318 if (bfd_bread (&x_ehdr, sizeof (x_ehdr), abfd) != sizeof (x_ehdr))
320 if (bfd_get_error () != bfd_error_system_call)
321 goto wrong;
322 else
323 goto fail;
326 /* Now check to see if we have a valid ELF file, and one that BFD can
327 make use of. The magic number must match, the address size ('class')
328 and byte-swapping must match our XVEC entry, and it must have a
329 section header table (FIXME: See comments re sections at top of this
330 file). */
331 if (! elf_file_p (&x_ehdr)
332 || x_ehdr.e_ident[EI_VERSION] != EV_CURRENT
333 || x_ehdr.e_ident[EI_CLASS] != ELFCLASS)
334 goto wrong;
336 /* Check that file's byte order matches xvec's. */
337 switch (x_ehdr.e_ident[EI_DATA])
339 case ELFDATA2MSB: /* Big-endian. */
340 if (! bfd_header_big_endian (abfd))
341 goto wrong;
342 break;
343 case ELFDATA2LSB: /* Little-endian. */
344 if (! bfd_header_little_endian (abfd))
345 goto wrong;
346 break;
347 case ELFDATANONE: /* No data encoding specified. */
348 default: /* Unknown data encoding specified . */
349 goto wrong;
352 elf_swap_ehdr_in (abfd, &x_ehdr, &i_ehdr);
353 #if DEBUG
354 elf_debug_file (&i_ehdr);
355 #endif
357 if (i_ehdr.e_phentsize != sizeof (Elf_External_Phdr) || i_ehdr.e_phnum == 0)
358 goto fail;
360 /* Read in program headers. */
361 if (_bfd_mul_overflow (i_ehdr.e_phnum, sizeof (*i_phdr), &amt))
363 bfd_set_error (bfd_error_file_too_big);
364 goto fail;
366 i_phdr = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt);
367 if (i_phdr == NULL)
368 goto fail;
370 if (bfd_seek (abfd, (file_ptr) (offset + i_ehdr.e_phoff), SEEK_SET) != 0)
371 goto fail;
373 /* Read in program headers and parse notes. */
374 for (i = 0; i < i_ehdr.e_phnum; ++i, ++i_phdr)
376 Elf_External_Phdr x_phdr;
378 if (bfd_bread (&x_phdr, sizeof (x_phdr), abfd) != sizeof (x_phdr))
379 goto fail;
380 elf_swap_phdr_in (abfd, &x_phdr, i_phdr);
382 if (i_phdr->p_type == PT_NOTE && i_phdr->p_filesz > 0)
384 elf_read_notes (abfd, offset + i_phdr->p_offset,
385 i_phdr->p_filesz, i_phdr->p_align);
387 /* Make sure ABFD returns to processing the program headers. */
388 if (bfd_seek (abfd, (file_ptr) (offset + i_ehdr.e_phoff
389 + (i + 1) * sizeof (x_phdr)),
390 SEEK_SET) != 0)
391 goto fail;
393 if (abfd->build_id != NULL)
394 return true;
398 /* Having gotten this far, we have a valid ELF section, but no
399 build-id was found. */
400 goto fail;
402 wrong:
403 bfd_set_error (bfd_error_wrong_format);
404 fail:
405 return false;