/* ELF executable support for BFD.
- Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
- Free Software Foundation, Inc.
+ Copyright 1991-2013 Free Software Foundation, Inc.
Written by Fred Fish @ Cygnus Support, from information published
in "UNIX System V Release 4, Programmers Guide: ANSI C and
#include "bfdlink.h"
#include "libbfd.h"
#include "elf-bfd.h"
+#include "libiberty.h"
/* Renaming structures, typedefs, macros and functions to be size-specific. */
#define Elf_External_Ehdr NAME(Elf,External_Ehdr)
Elf_Internal_Shdr *i_shdrp; /* Section header table, internal form */
unsigned int shindex;
const struct elf_backend_data *ebd;
- struct bfd_preserve preserve;
asection *s;
bfd_size_type amt;
const bfd_target *target;
- preserve.marker = NULL;
-
/* Read in the ELF header in external format. */
if (bfd_bread (&x_ehdr, sizeof (x_ehdr), abfd) != sizeof (x_ehdr))
goto got_wrong_format_error;
}
- if (!bfd_preserve_save (abfd, &preserve))
- goto got_no_match;
-
target = abfd->xvec;
/* Allocate an instance of the elf_obj_tdata structure and hook it up to
if (! (*target->_bfd_set_format[bfd_object]) (abfd))
goto got_no_match;
- preserve.marker = elf_tdata (abfd);
/* Now that we know the byte order, swap in the rest of the header */
i_ehdrp = elf_elfheader (abfd);
if (i_ehdrp->e_shnum == SHN_UNDEF)
{
i_ehdrp->e_shnum = i_shdr.sh_size;
- if (i_ehdrp->e_shnum != i_shdr.sh_size
- || i_ehdrp->e_shnum == 0)
+ if (i_ehdrp->e_shnum >= SHN_LORESERVE
+ || i_ehdrp->e_shnum != i_shdr.sh_size
+ || i_ehdrp->e_shnum == 0)
goto got_wrong_format_error;
}
s->flags |= SEC_DEBUGGING;
}
}
-
- bfd_preserve_finish (abfd, &preserve);
return target;
got_wrong_format_error:
- /* 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);
got_no_match:
- if (preserve.marker != NULL)
- bfd_preserve_restore (abfd, &preserve);
return NULL;
}
\f
{
Elf_Internal_Shdr i_shdr;
Elf_External_Shdr x_shdr;
+ bfd_byte *contents, *free_contents;
i_shdr = *i_shdrp[count];
i_shdr.sh_offset = 0;
elf_swap_shdr_out (abfd, &i_shdr, &x_shdr);
(*process) (&x_shdr, sizeof x_shdr, arg);
- /* PR ld/12451:
- Process the section's contents, if it has some. Read them in if necessary. */
- if (i_shdr.contents)
- (*process) (i_shdr.contents, i_shdr.sh_size, arg);
- else if (i_shdr.sh_type != SHT_NOBITS)
+ /* Process the section's contents, if it has some.
+ PR ld/12451: Read them in if necessary. */
+ if (i_shdr.sh_type == SHT_NOBITS)
+ continue;
+ free_contents = NULL;
+ contents = i_shdr.contents;
+ if (contents == NULL)
{
asection *sec;
sec = bfd_section_from_elf_index (abfd, count);
if (sec != NULL)
{
- if (sec->contents == NULL)
+ contents = sec->contents;
+ if (contents == NULL)
{
/* Force rereading from file. */
sec->flags &= ~SEC_IN_MEMORY;
- if (! bfd_malloc_and_get_section (abfd, sec, & sec->contents))
+ if (!bfd_malloc_and_get_section (abfd, sec, &free_contents))
continue;
+ contents = free_contents;
}
- if (sec->contents != NULL)
- (*process) (sec->contents, i_shdr.sh_size, arg);
}
}
+ if (contents != NULL)
+ {
+ (*process) (contents, i_shdr.sh_size, arg);
+ if (free_contents != NULL)
+ free (free_contents);
+ }
}
return TRUE;
verhdr = NULL;
else
verhdr = &elf_tdata (abfd)->dynversym_hdr;
- if ((elf_tdata (abfd)->dynverdef_section != 0
+ if ((elf_dynverdef (abfd) != 0
&& elf_tdata (abfd)->verdef == NULL)
- || (elf_tdata (abfd)->dynverref_section != 0
+ || (elf_dynverref (abfd) != 0
&& elf_tdata (abfd)->verref == NULL))
{
if (!_bfd_elf_slurp_version_tables (abfd, FALSE))
(bfd *templ,
bfd_vma ehdr_vma,
bfd_vma *loadbasep,
- int (*target_read_memory) (bfd_vma, bfd_byte *, size_t))
+ int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type))
{
Elf_External_Ehdr x_ehdr; /* Elf file header, external form */
Elf_Internal_Ehdr i_ehdr; /* Elf file header, internal form */
bfd_set_error (bfd_error_no_memory);
return NULL;
}
- nbfd->filename = "<in-memory>";
+ nbfd->filename = xstrdup ("<in-memory>");
nbfd->xvec = templ->xvec;
bim->size = contents_size;
bim->buffer = contents;