OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [elfcore.h] - Blame information for rev 58

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 khays
/* 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
  struct bfd_preserve preserve;
88
  bfd_size_type amt;
89
 
90
  preserve.marker = NULL;
91
 
92
  /* Read in the ELF header in external format.  */
93
  if (bfd_bread (&x_ehdr, sizeof (x_ehdr), abfd) != sizeof (x_ehdr))
94
    {
95
      if (bfd_get_error () != bfd_error_system_call)
96
        goto wrong;
97
      else
98
        goto fail;
99
    }
100
 
101
  /* Check the magic number.  */
102
  if (! elf_file_p (&x_ehdr))
103
    goto wrong;
104
 
105
  /* FIXME: Check EI_VERSION here !  */
106
 
107
  /* Check the address size ("class").  */
108
  if (x_ehdr.e_ident[EI_CLASS] != ELFCLASS)
109
    goto wrong;
110
 
111
  /* Check the byteorder.  */
112
  switch (x_ehdr.e_ident[EI_DATA])
113
    {
114
    case ELFDATA2MSB:           /* Big-endian.  */
115
      if (! bfd_big_endian (abfd))
116
        goto wrong;
117
      break;
118
    case ELFDATA2LSB:           /* Little-endian.  */
119
      if (! bfd_little_endian (abfd))
120
        goto wrong;
121
      break;
122
    default:
123
      goto wrong;
124
    }
125
 
126
  if (!bfd_preserve_save (abfd, &preserve))
127
    goto fail;
128
 
129
  /* Give abfd an elf_obj_tdata.  */
130
  if (! (*abfd->xvec->_bfd_set_format[bfd_core]) (abfd))
131
    goto fail;
132
  preserve.marker = elf_tdata (abfd);
133
 
134
  /* Swap in the rest of the header, now that we have the byte order.  */
135
  i_ehdrp = elf_elfheader (abfd);
136
  elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp);
137
 
138
#if DEBUG & 1
139
  elf_debug_file (i_ehdrp);
140
#endif
141
 
142
  ebd = get_elf_backend_data (abfd);
143
 
144
  /* Check that the ELF e_machine field matches what this particular
145
     BFD format expects.  */
146
 
147
  if (ebd->elf_machine_code != i_ehdrp->e_machine
148
      && (ebd->elf_machine_alt1 == 0
149
          || i_ehdrp->e_machine != ebd->elf_machine_alt1)
150
      && (ebd->elf_machine_alt2 == 0
151
          || i_ehdrp->e_machine != ebd->elf_machine_alt2))
152
    {
153
      const bfd_target * const *target_ptr;
154
 
155
      if (ebd->elf_machine_code != EM_NONE)
156
        goto wrong;
157
 
158
      /* This is the generic ELF target.  Let it match any ELF target
159
         for which we do not have a specific backend.  */
160
 
161
      for (target_ptr = bfd_target_vector; *target_ptr != NULL; target_ptr++)
162
        {
163
          const struct elf_backend_data *back;
164
 
165
          if ((*target_ptr)->flavour != bfd_target_elf_flavour)
166
            continue;
167
          back = xvec_get_elf_backend_data (*target_ptr);
168
          if (back->s->arch_size != ARCH_SIZE)
169
            continue;
170
          if (back->elf_machine_code == i_ehdrp->e_machine
171
              || (back->elf_machine_alt1 != 0
172
                  && i_ehdrp->e_machine == back->elf_machine_alt1)
173
              || (back->elf_machine_alt2 != 0
174
                  && i_ehdrp->e_machine == back->elf_machine_alt2))
175
            {
176
              /* target_ptr is an ELF backend which matches this
177
                 object file, so reject the generic ELF target.  */
178
              goto wrong;
179
            }
180
        }
181
    }
182
 
183
  /* If there is no program header, or the type is not a core file, then
184
     we are hosed.  */
185
  if (i_ehdrp->e_phoff == 0 || i_ehdrp->e_type != ET_CORE)
186
    goto wrong;
187
 
188
  /* Does BFD's idea of the phdr size match the size
189
     recorded in the file? */
190
  if (i_ehdrp->e_phentsize != sizeof (Elf_External_Phdr))
191
    goto wrong;
192
 
193
  /* If the program header count is PN_XNUM(0xffff), the actual
194
     count is in the first section header.  */
195
  if (i_ehdrp->e_shoff != 0 && i_ehdrp->e_phnum == PN_XNUM)
196
    {
197
      Elf_External_Shdr x_shdr;
198
      Elf_Internal_Shdr i_shdr;
199
      bfd_signed_vma where = i_ehdrp->e_shoff;
200
 
201
      if (where != (file_ptr) where)
202
        goto wrong;
203
 
204
      /* Seek to the section header table in the file.  */
205
      if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0)
206
        goto fail;
207
 
208
      /* Read the first section header at index 0, and convert to internal
209
         form.  */
210
      if (bfd_bread (&x_shdr, sizeof (x_shdr), abfd) != sizeof (x_shdr))
211
        goto fail;
212
      elf_swap_shdr_in (abfd, &x_shdr, &i_shdr);
213
 
214
      if (i_shdr.sh_info != 0)
215
        {
216
          i_ehdrp->e_phnum = i_shdr.sh_info;
217
          if (i_ehdrp->e_phnum != i_shdr.sh_info)
218
            goto wrong;
219
        }
220
    }
221
 
222
  /* Sanity check that we can read all of the program headers.
223
     It ought to be good enough to just read the last one.  */
224
  if (i_ehdrp->e_phnum > 1)
225
    {
226
      Elf_External_Phdr x_phdr;
227
      Elf_Internal_Phdr i_phdr;
228
      bfd_signed_vma where;
229
 
230
      /* Check that we don't have a totally silly number of
231
         program headers.  */
232
      if (i_ehdrp->e_phnum > (unsigned int) -1 / sizeof (x_phdr)
233
          || i_ehdrp->e_phnum > (unsigned int) -1 / sizeof (i_phdr))
234
        goto wrong;
235
 
236
      where = i_ehdrp->e_phoff + (i_ehdrp->e_phnum - 1) * sizeof (x_phdr);
237
      if (where != (file_ptr) where)
238
        goto wrong;
239
      if ((bfd_size_type) where <= i_ehdrp->e_phoff)
240
        goto wrong;
241
 
242
      if (bfd_seek (abfd, (file_ptr) where, SEEK_SET) != 0)
243
        goto fail;
244
      if (bfd_bread (&x_phdr, sizeof (x_phdr), abfd) != sizeof (x_phdr))
245
        goto fail;
246
    }
247
 
248
  /* Move to the start of the program headers.  */
249
  if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_phoff, SEEK_SET) != 0)
250
    goto wrong;
251
 
252
  /* Allocate space for the program headers.  */
253
  amt = sizeof (*i_phdrp) * i_ehdrp->e_phnum;
254
  i_phdrp = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt);
255
  if (!i_phdrp)
256
    goto fail;
257
 
258
  elf_tdata (abfd)->phdr = i_phdrp;
259
 
260
  /* Read and convert to internal form.  */
261
  for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
262
    {
263
      Elf_External_Phdr x_phdr;
264
 
265
      if (bfd_bread (&x_phdr, sizeof (x_phdr), abfd) != sizeof (x_phdr))
266
        goto fail;
267
 
268
      elf_swap_phdr_in (abfd, &x_phdr, i_phdrp + phindex);
269
    }
270
 
271
  /* Set the machine architecture.  Do this before processing the
272
     program headers since we need to know the architecture type
273
     when processing the notes of some systems' core files.  */
274
  if (! bfd_default_set_arch_mach (abfd, ebd->arch, 0)
275
      /* It's OK if this fails for the generic target.  */
276
      && ebd->elf_machine_code != EM_NONE)
277
    goto fail;
278
 
279
  /* Let the backend double check the format and override global
280
     information.  We do this before processing the program headers
281
     to allow the correct machine (as opposed to just the default
282
     machine) to be set, making it possible for grok_prstatus and
283
     grok_psinfo to rely on the mach setting.  */
284
  if (ebd->elf_backend_object_p != NULL
285
      && ! ebd->elf_backend_object_p (abfd))
286
    goto wrong;
287
 
288
  /* Process each program header.  */
289
  for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
290
    if (! bfd_section_from_phdr (abfd, i_phdrp + phindex, (int) phindex))
291
      goto fail;
292
 
293
  /* Check for core truncation.  */
294
  {
295
    bfd_size_type high = 0;
296
    struct stat statbuf;
297
    for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
298
      {
299
        Elf_Internal_Phdr *p = i_phdrp + phindex;
300
        if (p->p_filesz)
301
          {
302
            bfd_size_type current = p->p_offset + p->p_filesz;
303
            if (high < current)
304
              high = current;
305
          }
306
      }
307
    if (bfd_stat (abfd, &statbuf) == 0)
308
      {
309
        if ((bfd_size_type) statbuf.st_size < high)
310
          {
311
            (*_bfd_error_handler)
312
              (_("Warning: %B is truncated: expected core file "
313
                 "size >= %lu, found: %lu."),
314
               abfd, (unsigned long) high, (unsigned long) statbuf.st_size);
315
          }
316
      }
317
  }
318
 
319
  /* Save the entry point from the ELF header.  */
320
  bfd_get_start_address (abfd) = i_ehdrp->e_entry;
321
 
322
  bfd_preserve_finish (abfd, &preserve);
323
  return abfd->xvec;
324
 
325
wrong:
326
  /* There is way too much undoing of half-known state here.  The caller,
327
     bfd_check_format_matches, really shouldn't iterate on live bfd's to
328
     check match/no-match like it does.  We have to rely on that a call to
329
     bfd_default_set_arch_mach with the previously known mach, undoes what
330
     was done by the first bfd_default_set_arch_mach (with mach 0) here.
331
     For this to work, only elf-data and the mach may be changed by the
332
     target-specific elf_backend_object_p function.  Note that saving the
333
     whole bfd here and restoring it would be even worse; the first thing
334
     you notice is that the cached bfd file position gets out of sync.  */
335
  bfd_set_error (bfd_error_wrong_format);
336
 
337
fail:
338
  if (preserve.marker != NULL)
339
    bfd_preserve_restore (abfd, &preserve);
340
  return NULL;
341
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.