(_bfd_dwarf2_find_nearest_line): If address length is zero, set it to 8 for
[deliverable/binutils-gdb.git] / bfd / elfcore.h
index df3af0ce8da452d851dbeef3dadf51eb813c83bf..7db5f72e3338d68a483e434541bbc127592b084f 100644 (file)
@@ -1,5 +1,5 @@
 /* ELF core file support for BFD.
 /* ELF core file support for BFD.
-   Copyright 1995, 1996, 1997, 1998, 2000, 2001
+   Copyright 1995, 1996, 1997, 1998, 2000, 2001, 2002
    Free Software Foundation, Inc.
 
 This file is part of BFD, the Binary File Descriptor library.
    Free Software Foundation, Inc.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -81,14 +81,18 @@ elf_core_file_p (abfd)
 {
   Elf_External_Ehdr x_ehdr;    /* Elf file header, external form */
   Elf_Internal_Ehdr *i_ehdrp;  /* Elf file header, internal form */
 {
   Elf_External_Ehdr x_ehdr;    /* Elf file header, external form */
   Elf_Internal_Ehdr *i_ehdrp;  /* Elf file header, internal form */
-  Elf_Internal_Phdr *i_phdrp = NULL;   /* Elf program header, internal form */
+  Elf_Internal_Phdr *i_phdrp;  /* Elf program header, internal form */
   unsigned int phindex;
   struct elf_backend_data *ebd;
   unsigned int phindex;
   struct elf_backend_data *ebd;
-  struct elf_obj_tdata *preserved_tdata = elf_tdata (abfd);
+  struct bfd_preserve preserve;
   struct elf_obj_tdata *new_tdata = NULL;
   struct elf_obj_tdata *new_tdata = NULL;
+  bfd_size_type amt;
+
+  preserve.arch_info = abfd->arch_info;
 
   /* Read in the ELF header in external format.  */
 
   /* Read in the ELF header in external format.  */
-  if (bfd_read ((PTR) & x_ehdr, sizeof (x_ehdr), 1, abfd) != sizeof (x_ehdr))
+  if (bfd_bread ((PTR) &x_ehdr, (bfd_size_type) sizeof (x_ehdr), abfd)
+      != sizeof (x_ehdr))
     {
       if (bfd_get_error () != bfd_error_system_call)
        bfd_set_error (bfd_error_wrong_format);
     {
       if (bfd_get_error () != bfd_error_system_call)
        bfd_set_error (bfd_error_wrong_format);
@@ -96,7 +100,7 @@ elf_core_file_p (abfd)
     }
 
   /* Check the magic number.  */
     }
 
   /* Check the magic number.  */
-  if (elf_file_p (&x_ehdr) == false)
+  if (! elf_file_p (&x_ehdr))
     goto wrong;
 
   /* FIXME: Check EI_VERSION here ! */
     goto wrong;
 
   /* FIXME: Check EI_VERSION here ! */
@@ -121,12 +125,25 @@ elf_core_file_p (abfd)
     }
 
   /* Give abfd an elf_obj_tdata.  */
     }
 
   /* Give abfd an elf_obj_tdata.  */
-  new_tdata =
-    (struct elf_obj_tdata *) bfd_zalloc (abfd, sizeof (struct elf_obj_tdata));
+  amt = sizeof (struct elf_obj_tdata);
+  new_tdata = (struct elf_obj_tdata *) bfd_zalloc (abfd, amt);
   if (new_tdata == NULL)
     return NULL;
   if (new_tdata == NULL)
     return NULL;
+  preserve.tdata = elf_tdata (abfd);
   elf_tdata (abfd) = new_tdata;
 
   elf_tdata (abfd) = new_tdata;
 
+  /* Clear section information, since there might be a recognized bfd that
+     we now check if we can replace, and we don't want to append to it.  */
+  preserve.sections = abfd->sections;
+  preserve.section_tail = abfd->section_tail;
+  preserve.section_count = abfd->section_count;
+  preserve.section_htab = abfd->section_htab;
+  abfd->sections = NULL;
+  abfd->section_tail = &abfd->sections;
+  abfd->section_count = 0;
+  if (!bfd_hash_table_init (&abfd->section_htab, bfd_section_hash_newfunc))
+    goto fail;
+
   /* Swap in the rest of the header, now that we have the byte order.  */
   i_ehdrp = elf_elfheader (abfd);
   elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp);
   /* Swap in the rest of the header, now that we have the byte order.  */
   i_ehdrp = elf_elfheader (abfd);
   elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp);
@@ -181,12 +198,12 @@ elf_core_file_p (abfd)
     goto wrong;
 
   /* Move to the start of the program headers.  */
     goto wrong;
 
   /* Move to the start of the program headers.  */
-  if (bfd_seek (abfd, i_ehdrp->e_phoff, SEEK_SET) != 0)
+  if (bfd_seek (abfd, (file_ptr) i_ehdrp->e_phoff, SEEK_SET) != 0)
     goto wrong;
 
   /* Allocate space for the program headers.  */
     goto wrong;
 
   /* Allocate space for the program headers.  */
-  i_phdrp = (Elf_Internal_Phdr *)
-    bfd_alloc (abfd, sizeof (*i_phdrp) * i_ehdrp->e_phnum);
+  amt = sizeof (*i_phdrp) * i_ehdrp->e_phnum;
+  i_phdrp = (Elf_Internal_Phdr *) bfd_alloc (abfd, amt);
   if (!i_phdrp)
     goto fail;
 
   if (!i_phdrp)
     goto fail;
 
@@ -196,25 +213,27 @@ elf_core_file_p (abfd)
   for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
     {
       Elf_External_Phdr x_phdr;
   for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
     {
       Elf_External_Phdr x_phdr;
-      if (bfd_read ((PTR) &x_phdr, sizeof (x_phdr), 1, abfd)
+      if (bfd_bread ((PTR) &x_phdr, (bfd_size_type) sizeof (x_phdr), abfd)
          != sizeof (x_phdr))
        goto fail;
 
       elf_swap_phdr_in (abfd, &x_phdr, i_phdrp + phindex);
     }
 
          != sizeof (x_phdr))
        goto fail;
 
       elf_swap_phdr_in (abfd, &x_phdr, i_phdrp + phindex);
     }
 
-  /* Process each program header.  */
-  for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
+  /* Set the machine architecture.  Do this before processing the
+     program headers since we need to know the architecture type
+     when processing the notes of some systems' core files.  */
+  if (! bfd_default_set_arch_mach (abfd, ebd->arch, 0))
     {
     {
-      if (! bfd_section_from_phdr (abfd, i_phdrp + phindex, phindex))
+      /* It's OK if this fails for the generic target.  */
+      if (ebd->elf_machine_code != EM_NONE)
        goto fail;
     }
 
        goto fail;
     }
 
-  /* Set the machine architecture.  */
-  if (! bfd_default_set_arch_mach (abfd, ebd->arch, 0))
+  /* Process each program header.  */
+  for (phindex = 0; phindex < i_ehdrp->e_phnum; ++phindex)
     {
     {
-      /* It's OK if this fails for the generic target.  */
-      if (ebd->elf_machine_code != EM_NONE)
+      if (! bfd_section_from_phdr (abfd, i_phdrp + phindex, (int) phindex))
        goto fail;
     }
 
        goto fail;
     }
 
@@ -225,19 +244,37 @@ elf_core_file_p (abfd)
      information.  */
   if (ebd->elf_backend_object_p)
     {
      information.  */
   if (ebd->elf_backend_object_p)
     {
-      if ((*ebd->elf_backend_object_p) (abfd) == false)
+      if (! (*ebd->elf_backend_object_p) (abfd))
        goto wrong;
     }
 
        goto wrong;
     }
 
+  bfd_hash_table_free (&preserve.section_htab);
   return abfd->xvec;
 
 wrong:
   return abfd->xvec;
 
 wrong:
+  /* There is way too much undoing of half-known state here.  The caller,
+     bfd_check_format_matches, really shouldn't iterate on live bfd's to
+     check match/no-match like it does.  We have to rely on that a call to
+     bfd_default_set_arch_mach with the previously known mach, undoes what
+     was done by the first bfd_default_set_arch_mach (with mach 0) here.
+     For this to work, only elf-data and the mach may be changed by the
+     target-specific elf_backend_object_p function.  Note that saving the
+     whole bfd here and restoring it would be even worse; the first thing
+     you notice is that the cached bfd file position gets out of sync.  */
   bfd_set_error (bfd_error_wrong_format);
   bfd_set_error (bfd_error_wrong_format);
+
 fail:
 fail:
-  if (i_phdrp != NULL)
-    bfd_release (abfd, i_phdrp);
+  abfd->arch_info = preserve.arch_info;
   if (new_tdata != NULL)
   if (new_tdata != NULL)
-    bfd_release (abfd, new_tdata);
-  elf_tdata (abfd) = preserved_tdata;
+    {
+      /* bfd_release frees all memory more recently bfd_alloc'd than
+        its arg, as well as its arg.  */
+      bfd_release (abfd, new_tdata);
+      elf_tdata (abfd) = preserve.tdata;
+      abfd->section_htab = preserve.section_htab;
+      abfd->sections = preserve.sections;
+      abfd->section_tail = preserve.section_tail;
+      abfd->section_count = preserve.section_count;
+    }
   return NULL;
 }
   return NULL;
 }
This page took 0.025472 seconds and 4 git commands to generate.