xref: /dragonfly/contrib/gdb-7/bfd/elfcore.h (revision 0720b42f)
1 /* ELF core file support for BFD.
2    Copyright 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005, 2007,
3    2008, 2010 Free Software Foundation, Inc.
4 
5    This file is part of BFD, the Binary File Descriptor library.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20    MA 02110-1301, USA.  */
21 
22 char*
23 elf_core_file_failing_command (bfd *abfd)
24 {
25   return elf_tdata (abfd)->core->command;
26 }
27 
28 int
29 elf_core_file_failing_signal (bfd *abfd)
30 {
31   return elf_tdata (abfd)->core->signal;
32 }
33 
34 int
35 elf_core_file_pid (bfd *abfd)
36 {
37   return elf_tdata (abfd)->core->pid;
38 }
39 
40 bfd_boolean
41 elf_core_file_matches_executable_p (bfd *core_bfd, bfd *exec_bfd)
42 {
43   char* corename;
44 
45   /* xvecs must match if both are ELF files for the same target.  */
46 
47   if (core_bfd->xvec != exec_bfd->xvec)
48     {
49       bfd_set_error (bfd_error_system_call);
50       return FALSE;
51     }
52 
53   /* See if the name in the corefile matches the executable name.  */
54   corename = elf_tdata (core_bfd)->core->program;
55   if (corename != NULL)
56     {
57       const char* execname = strrchr (exec_bfd->filename, '/');
58 
59       execname = execname ? execname + 1 : exec_bfd->filename;
60 
61       if (strcmp (execname, corename) != 0)
62 	return FALSE;
63     }
64 
65   return TRUE;
66 }
67 
68 /*  Core files are simply standard ELF formatted files that partition
69     the file using the execution view of the file (program header table)
70     rather than the linking view.  In fact, there is no section header
71     table in a core file.
72 
73     The process status information (including the contents of the general
74     register set) and the floating point register set are stored in a
75     segment of type PT_NOTE.  We handcraft a couple of extra bfd sections
76     that allow standard bfd access to the general registers (.reg) and the
77     floating point registers (.reg2).  */
78 
79 const bfd_target *
80 elf_core_file_p (bfd *abfd)
81 {
82   Elf_External_Ehdr x_ehdr;	/* Elf file header, external form.  */
83   Elf_Internal_Ehdr *i_ehdrp;	/* Elf file header, internal form.  */
84   Elf_Internal_Phdr *i_phdrp;	/* Elf program header, internal form.  */
85   unsigned int phindex;
86   const struct elf_backend_data *ebd;
87   bfd_size_type amt;
88 
89   /* Read in the ELF header in external format.  */
90   if (bfd_bread (&x_ehdr, sizeof (x_ehdr), abfd) != sizeof (x_ehdr))
91     {
92       if (bfd_get_error () != bfd_error_system_call)
93 	goto wrong;
94       else
95 	goto fail;
96     }
97 
98   /* Check the magic number.  */
99   if (! elf_file_p (&x_ehdr))
100     goto wrong;
101 
102   /* FIXME: Check EI_VERSION here !  */
103 
104   /* Check the address size ("class").  */
105   if (x_ehdr.e_ident[EI_CLASS] != ELFCLASS)
106     goto wrong;
107 
108   /* Check the byteorder.  */
109   switch (x_ehdr.e_ident[EI_DATA])
110     {
111     case ELFDATA2MSB:		/* Big-endian.  */
112       if (! bfd_big_endian (abfd))
113 	goto wrong;
114       break;
115     case ELFDATA2LSB:		/* Little-endian.  */
116       if (! bfd_little_endian (abfd))
117 	goto wrong;
118       break;
119     default:
120       goto wrong;
121     }
122 
123   /* Give abfd an elf_obj_tdata.  */
124   if (! (*abfd->xvec->_bfd_set_format[bfd_core]) (abfd))
125     goto fail;
126 
127   /* Swap in the rest of the header, now that we have the byte order.  */
128   i_ehdrp = elf_elfheader (abfd);
129   elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp);
130 
131 #if DEBUG & 1
132   elf_debug_file (i_ehdrp);
133 #endif
134 
135   ebd = get_elf_backend_data (abfd);
136 
137   /* Check that the ELF e_machine field matches what this particular
138      BFD format expects.  */
139 
140   if (ebd->elf_machine_code != i_ehdrp->e_machine
141       && (ebd->elf_machine_alt1 == 0
142 	  || i_ehdrp->e_machine != ebd->elf_machine_alt1)
143       && (ebd->elf_machine_alt2 == 0
144 	  || i_ehdrp->e_machine != ebd->elf_machine_alt2))
145     {
146       const bfd_target * const *target_ptr;
147 
148       if (ebd->elf_machine_code != EM_NONE)
149 	goto wrong;
150 
151       /* This is the generic ELF target.  Let it match any ELF target
152 	 for which we do not have a specific backend.  */
153 
154       for (target_ptr = bfd_target_vector; *target_ptr != NULL; target_ptr++)
155 	{
156 	  const struct elf_backend_data *back;
157 
158 	  if ((*target_ptr)->flavour != bfd_target_elf_flavour)
159 	    continue;
160 	  back = xvec_get_elf_backend_data (*target_ptr);
161 	  if (back->s->arch_size != ARCH_SIZE)
162 	    continue;
163 	  if (back->elf_machine_code == i_ehdrp->e_machine
164 	      || (back->elf_machine_alt1 != 0
165 	          && i_ehdrp->e_machine == back->elf_machine_alt1)
166 	      || (back->elf_machine_alt2 != 0
167 	          && i_ehdrp->e_machine == back->elf_machine_alt2))
168 	    {
169 	      /* target_ptr is an ELF backend which matches this
170 		 object file, so reject the generic ELF target.  */
171 	      goto wrong;
172 	    }
173 	}
174     }
175 
176   /* If there is no program header, or the type is not a core file, then
177      we are hosed.  */
178   if (i_ehdrp->e_phoff == 0 || i_ehdrp->e_type != ET_CORE)
179     goto wrong;
180 
181   /* Does BFD's idea of the phdr size match the size
182      recorded in the file? */
183   if (i_ehdrp->e_phentsize != sizeof (Elf_External_Phdr))
184     goto wrong;
185 
186   /* If the program header count is PN_XNUM(0xffff), the actual
187      count is in the first section header.  */
188   if (i_ehdrp->e_shoff != 0 && i_ehdrp->e_phnum == PN_XNUM)
189     {
190       Elf_External_Shdr x_shdr;
191       Elf_Internal_Shdr i_shdr;
192       bfd_signed_vma where = i_ehdrp->e_shoff;
193 
194       if (where != (file_ptr) where)
195 	goto wrong;
196 
197       /* Seek to the section header table in the file.  */
198       if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0)
199 	goto fail;
200 
201       /* Read the first section header at index 0, and convert to internal
202 	 form.  */
203       if (bfd_bread (&x_shdr, sizeof (x_shdr), abfd) != sizeof (x_shdr))
204 	goto fail;
205       elf_swap_shdr_in (abfd, &x_shdr, &i_shdr);
206 
207       if (i_shdr.sh_info != 0)
208 	{
209 	  i_ehdrp->e_phnum = i_shdr.sh_info;
210 	  if (i_ehdrp->e_phnum != i_shdr.sh_info)
211 	    goto wrong;
212 	}
213     }
214 
215   /* Sanity check that we can read all of the program headers.
216      It ought to be good enough to just read the last one.  */
217   if (i_ehdrp->e_phnum > 1)
218     {
219       Elf_External_Phdr x_phdr;
220       Elf_Internal_Phdr i_phdr;
221       bfd_signed_vma where;
222 
223       /* Check that we don't have a totally silly number of
224 	 program headers.  */
225       if (i_ehdrp->e_phnum > (unsigned int) -1 / sizeof (x_phdr)
226 	  || i_ehdrp->e_phnum > (unsigned int) -1 / sizeof (i_phdr))
227 	goto wrong;
228 
229       where = i_ehdrp->e_phoff + (i_ehdrp->e_phnum - 1) * sizeof (x_phdr);
230       if (where != (file_ptr) where)
231 	goto wrong;
232       if ((bfd_size_type) where <= i_ehdrp->e_phoff)
233 	goto wrong;
234 
235       if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0)
236 	goto fail;
237       if (bfd_bread (&x_phdr, sizeof (x_phdr), abfd) != sizeof (x_phdr))
238 	goto fail;
239     }
240 
241   /* Move to the start of the program headers.  */
242   if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_phoff, SEEK_SET) != 0)
243     goto wrong;
244 
245   /* Allocate space for the program headers.  */
246   amt = sizeof (*i_phdrp) * i_ehdrp->e_phnum;
247   i_phdrp = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt);
248   if (!i_phdrp)
249     goto fail;
250 
251   elf_tdata (abfd)->phdr = i_phdrp;
252 
253   /* Read and convert to internal form.  */
254   for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
255     {
256       Elf_External_Phdr x_phdr;
257 
258       if (bfd_bread (&x_phdr, sizeof (x_phdr), abfd) != sizeof (x_phdr))
259 	goto fail;
260 
261       elf_swap_phdr_in (abfd, &x_phdr, i_phdrp + phindex);
262     }
263 
264   /* Set the machine architecture.  Do this before processing the
265      program headers since we need to know the architecture type
266      when processing the notes of some systems' core files.  */
267   if (! bfd_default_set_arch_mach (abfd, ebd->arch, 0)
268       /* It's OK if this fails for the generic target.  */
269       && ebd->elf_machine_code != EM_NONE)
270     goto fail;
271 
272   /* Let the backend double check the format and override global
273      information.  We do this before processing the program headers
274      to allow the correct machine (as opposed to just the default
275      machine) to be set, making it possible for grok_prstatus and
276      grok_psinfo to rely on the mach setting.  */
277   if (ebd->elf_backend_object_p != NULL
278       && ! ebd->elf_backend_object_p (abfd))
279     goto wrong;
280 
281   /* Process each program header.  */
282   for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
283     if (! bfd_section_from_phdr (abfd, i_phdrp + phindex, (int) phindex))
284       goto fail;
285 
286   /* Check for core truncation.  */
287   {
288     bfd_size_type high = 0;
289     struct stat statbuf;
290     for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
291       {
292 	Elf_Internal_Phdr *p = i_phdrp + phindex;
293 	if (p->p_filesz)
294 	  {
295 	    bfd_size_type current = p->p_offset + p->p_filesz;
296 	    if (high < current)
297 	      high = current;
298 	  }
299       }
300     if (bfd_stat (abfd, &statbuf) == 0)
301       {
302 	if ((bfd_size_type) statbuf.st_size < high)
303 	  {
304 	    (*_bfd_error_handler)
305 	      (_("Warning: %B is truncated: expected core file "
306 		 "size >= %lu, found: %lu."),
307 	       abfd, (unsigned long) high, (unsigned long) statbuf.st_size);
308 	  }
309       }
310   }
311 
312   /* Save the entry point from the ELF header.  */
313   bfd_get_start_address (abfd) = i_ehdrp->e_entry;
314   return abfd->xvec;
315 
316 wrong:
317   bfd_set_error (bfd_error_wrong_format);
318 fail:
319   return NULL;
320 }
321