xref: /netbsd/external/gpl3/binutils/dist/bfd/elfcore.h (revision f22f0ef4)
1 /* ELF core file support for BFD.
2    Copyright (C) 1995-2022 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 3 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., 51 Franklin Street - Fifth Floor, Boston,
19    MA 02110-1301, USA.  */
20 
21 char*
elf_core_file_failing_command(bfd * abfd)22 elf_core_file_failing_command (bfd *abfd)
23 {
24   return elf_tdata (abfd)->core->command;
25 }
26 
27 int
elf_core_file_failing_signal(bfd * abfd)28 elf_core_file_failing_signal (bfd *abfd)
29 {
30   return elf_tdata (abfd)->core->signal;
31 }
32 
33 int
elf_core_file_pid(bfd * abfd)34 elf_core_file_pid (bfd *abfd)
35 {
36   return elf_tdata (abfd)->core->pid;
37 }
38 
39 bool
elf_core_file_matches_executable_p(bfd * core_bfd,bfd * exec_bfd)40 elf_core_file_matches_executable_p (bfd *core_bfd, bfd *exec_bfd)
41 {
42   char* corename;
43 
44   /* xvecs must match if both are ELF files for the same target.  */
45 
46   if (core_bfd->xvec != exec_bfd->xvec)
47     {
48       bfd_set_error (bfd_error_system_call);
49       return false;
50     }
51 
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;
59 
60   /* See if the name in the corefile matches the executable name.  */
61   corename = elf_tdata (core_bfd)->core->program;
62   if (corename != NULL)
63     {
64       const char* execname = strrchr (bfd_get_filename (exec_bfd), '/');
65 
66       execname = execname ? execname + 1 : bfd_get_filename (exec_bfd);
67 
68       if (strcmp (execname, corename) != 0)
69 	return false;
70     }
71 
72   return true;
73 }
74 
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.
79 
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).  */
85 
86 bfd_cleanup
elf_core_file_p(bfd * abfd)87 elf_core_file_p (bfd *abfd)
88 {
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;
96 
97   /* Read in the ELF header in external format.  */
98   if (bfd_bread (&x_ehdr, sizeof (x_ehdr), abfd) != sizeof (x_ehdr))
99     {
100       if (bfd_get_error () != bfd_error_system_call)
101 	goto wrong;
102       else
103 	goto fail;
104     }
105 
106   /* Check the magic number.  */
107   if (! elf_file_p (&x_ehdr))
108     goto wrong;
109 
110   /* FIXME: Check EI_VERSION here !  */
111 
112   /* Check the address size ("class").  */
113   if (x_ehdr.e_ident[EI_CLASS] != ELFCLASS)
114     goto wrong;
115 
116   /* Check the byteorder.  */
117   switch (x_ehdr.e_ident[EI_DATA])
118     {
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;
129     }
130 
131   /* Give abfd an elf_obj_tdata.  */
132   if (! (*abfd->xvec->_bfd_set_format[bfd_core]) (abfd))
133     goto fail;
134 
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);
138 
139 #if DEBUG & 1
140   elf_debug_file (i_ehdrp);
141 #endif
142 
143   ebd = get_elf_backend_data (abfd);
144 
145   /* Check that the ELF e_machine field matches what this particular
146      BFD format expects.  */
147 
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;
155 
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;
160 
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;
165 
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;
170 
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)
174     {
175       Elf_External_Shdr x_shdr;
176       Elf_Internal_Shdr i_shdr;
177       file_ptr where = (file_ptr) i_ehdrp->e_shoff;
178 
179       if (i_ehdrp->e_shoff < sizeof (x_ehdr))
180 	goto wrong;
181 
182       /* Seek to the section header table in the file.  */
183       if (bfd_seek (abfd, where, SEEK_SET) != 0)
184 	goto fail;
185 
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);
191 
192       if (i_shdr.sh_info != 0)
193 	{
194 	  i_ehdrp->e_phnum = i_shdr.sh_info;
195 	  if (i_ehdrp->e_phnum != i_shdr.sh_info)
196 	    goto wrong;
197 	}
198     }
199 
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)
203     {
204       Elf_External_Phdr x_phdr;
205       Elf_Internal_Phdr i_phdr;
206       file_ptr where;
207 
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;
213 
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;
217 
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;
222     }
223 
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;
227 
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;
233 
234   elf_tdata (abfd)->phdr = i_phdrp;
235 
236   /* Read and convert to internal form.  */
237   for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
238     {
239       Elf_External_Phdr x_phdr;
240 
241       if (bfd_bread (&x_phdr, sizeof (x_phdr), abfd) != sizeof (x_phdr))
242 	goto fail;
243 
244       elf_swap_phdr_in (abfd, &x_phdr, i_phdrp + phindex);
245     }
246 
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;
254 
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;
263 
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;
268 
269   /* Check for core truncation.  */
270   filesize = bfd_get_file_size (abfd);
271   if (filesize != 0)
272     {
273       for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
274 	{
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))
279 	    {
280 	      _bfd_error_handler (_("warning: %pB has a segment "
281 				    "extending past end of file"), abfd);
282 	      abfd->read_only = 1;
283 	      break;
284 	    }
285       }
286   }
287 
288   /* Save the entry point from the ELF header.  */
289   abfd->start_address = i_ehdrp->e_entry;
290   return _bfd_no_cleanup;
291 
292  wrong:
293   bfd_set_error (bfd_error_wrong_format);
294  fail:
295   return NULL;
296 }
297 
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.  */
301 
302 bool
NAME(_bfd_elf,core_find_build_id)303 NAME(_bfd_elf, core_find_build_id)
304   (bfd *abfd,
305    bfd_vma offset)
306 {
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;
312 
313   /* Seek to the position of the segment at OFFSET.  */
314   if (bfd_seek (abfd, offset, SEEK_SET) != 0)
315     goto fail;
316 
317   /* Read in the ELF header in external format.  */
318   if (bfd_bread (&x_ehdr, sizeof (x_ehdr), abfd) != sizeof (x_ehdr))
319     {
320       if (bfd_get_error () != bfd_error_system_call)
321 	goto wrong;
322       else
323 	goto fail;
324     }
325 
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;
335 
336   /* Check that file's byte order matches xvec's.  */
337   switch (x_ehdr.e_ident[EI_DATA])
338     {
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;
350     }
351 
352   elf_swap_ehdr_in (abfd, &x_ehdr, &i_ehdr);
353 #if DEBUG
354   elf_debug_file (&i_ehdr);
355 #endif
356 
357   if (i_ehdr.e_phentsize != sizeof (Elf_External_Phdr) || i_ehdr.e_phnum == 0)
358     goto fail;
359 
360   /* Read in program headers.  */
361   if (_bfd_mul_overflow (i_ehdr.e_phnum, sizeof (*i_phdr), &amt))
362     {
363       bfd_set_error (bfd_error_file_too_big);
364       goto fail;
365     }
366   i_phdr = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt);
367   if (i_phdr == NULL)
368     goto fail;
369 
370   if (bfd_seek (abfd, (file_ptr) (offset + i_ehdr.e_phoff), SEEK_SET) != 0)
371     goto fail;
372 
373   /* Read in program headers and parse notes.  */
374   for (i = 0; i < i_ehdr.e_phnum; ++i, ++i_phdr)
375     {
376       Elf_External_Phdr x_phdr;
377 
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);
381 
382       if (i_phdr->p_type == PT_NOTE && i_phdr->p_filesz > 0)
383 	{
384 	  elf_read_notes (abfd, offset + i_phdr->p_offset,
385 			  i_phdr->p_filesz, i_phdr->p_align);
386 
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;
392 
393 	  if (abfd->build_id != NULL)
394 	    return true;
395 	}
396     }
397 
398   /* Having gotten this far, we have a valid ELF section, but no
399      build-id was found.  */
400   goto fail;
401 
402  wrong:
403   bfd_set_error (bfd_error_wrong_format);
404  fail:
405   return false;
406 }
407