/* 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.
{
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;
- struct elf_obj_tdata *preserved_tdata = elf_tdata (abfd);
- struct sec *preserved_sections = abfd->sections;
- unsigned int preserved_section_count = abfd->section_count;
- enum bfd_architecture previous_arch = bfd_get_arch (abfd);
- unsigned long previous_mach = bfd_get_mach (abfd);
- struct elf_obj_tdata *new_tdata = NULL;
+ struct bfd_preserve preserve;
bfd_size_type amt;
- /* 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. */
- abfd->sections = NULL;
- abfd->section_count = 0;
+ preserve.marker = NULL;
/* Read in the ELF header in external format. */
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);
- return NULL;
+ goto wrong;
+ else
+ goto fail;
}
/* Check the magic number. */
- if (elf_file_p (&x_ehdr) == false)
+ if (! elf_file_p (&x_ehdr))
goto wrong;
/* FIXME: Check EI_VERSION here ! */
/* Give abfd an 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;
- elf_tdata (abfd) = new_tdata;
+ preserve.marker = bfd_zalloc (abfd, amt);
+ if (preserve.marker == NULL)
+ goto fail;
+ if (!bfd_preserve_save (abfd, &preserve))
+ goto fail;
+
+ elf_tdata (abfd) = preserve.marker;
/* Swap in the rest of the header, now that we have the byte order. */
i_ehdrp = elf_elfheader (abfd);
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, (int) phindex))
+ /* It's OK if this fails for the generic target. */
+ if (ebd->elf_machine_code != EM_NONE)
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;
}
information. */
if (ebd->elf_backend_object_p)
{
- if ((*ebd->elf_backend_object_p) (abfd) == false)
+ if (! (*ebd->elf_backend_object_p) (abfd))
goto wrong;
}
+ bfd_preserve_finish (abfd, &preserve);
return abfd->xvec;
wrong:
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_default_set_arch_mach (abfd, previous_arch, previous_mach);
bfd_set_error (bfd_error_wrong_format);
+
fail:
- if (i_phdrp != NULL)
- bfd_release (abfd, i_phdrp);
- if (new_tdata != NULL)
- bfd_release (abfd, new_tdata);
- elf_tdata (abfd) = preserved_tdata;
- abfd->sections = preserved_sections;
- abfd->section_count = preserved_section_count;
+ if (preserve.marker != NULL)
+ bfd_preserve_restore (abfd, &preserve);
return NULL;
}