* bfd.c (struct bfd_preserve): New.

(bfd_preserve_save): New function.
	(bfd_preserve_restore): Ditto.
	(bfd_preserve_finish): Ditto.
	* bfd-in2.h: Regenerate.
	* mach-o.c: Formatting.
	(bfd_mach_o_scan_read_symtab_symbol): Make "value" unsigned.
	(bfd_mach_o_object_p): Use bfd_preserve_save/restore/finish.
	(bfd_mach_o_core_p): Ditto.
	(bfd_mach_o_scan): Pass in mdata.
	* mach-o.h (bfd_mach_o_scan): Update prototype.
	* pef.c: Formatting.
	(bfd_pef_object_p): Use bfd_preserve_save/restore/finish.
	(bfd_pef_xlib_object_p): Ditto.
	(bfd_pef_scan): Pass in mdata.  Move version check to bfd_pef_object_p.
	* pef.h (bfd_pef_scan): Update prototype.
	* xsym.c: Formatting, K&R fixes.
	(bfd_sym_object_p): Use bfd_preserve_save/restore/finish.
	(bfd_sym_scan): New function split out from bfd_sym_object_p.
	* xsym.h (bfd_sym_scan): Declare.
	* elfcode.h (elf_object_p): Use bfd_preserve_save/restore/finish.
	(elf_core_file_p): Likewise.
	* targets.c (_bfd_target_vector): Revert 2002-11-08 change.
This commit is contained in:
Alan Modra 2002-11-12 15:44:24 +00:00
parent c4c4121963
commit e84d6fca26
11 changed files with 1068 additions and 753 deletions

View file

@ -1,3 +1,30 @@
2002-11-13 Klee Dienes <kdienes@apple.com>
Alan Modra <amodra@bigpond.net.au>
* bfd.c (struct bfd_preserve): New.
(bfd_preserve_save): New function.
(bfd_preserve_restore): Ditto.
(bfd_preserve_finish): Ditto.
* bfd-in2.h: Regenerate.
* mach-o.c: Formatting.
(bfd_mach_o_scan_read_symtab_symbol): Make "value" unsigned.
(bfd_mach_o_object_p): Use bfd_preserve_save/restore/finish.
(bfd_mach_o_core_p): Ditto.
(bfd_mach_o_scan): Pass in mdata.
* mach-o.h (bfd_mach_o_scan): Update prototype.
* pef.c: Formatting.
(bfd_pef_object_p): Use bfd_preserve_save/restore/finish.
(bfd_pef_xlib_object_p): Ditto.
(bfd_pef_scan): Pass in mdata. Move version check to bfd_pef_object_p.
* pef.h (bfd_pef_scan): Update prototype.
* xsym.c: Formatting, K&R fixes.
(bfd_sym_object_p): Use bfd_preserve_save/restore/finish.
(bfd_sym_scan): New function split out from bfd_sym_object_p.
* xsym.h (bfd_sym_scan): Declare.
* elfcode.h (elf_object_p): Use bfd_preserve_save/restore/finish.
(elf_core_file_p): Likewise.
* targets.c (_bfd_target_vector): Revert 2002-11-08 change.
2002-11-12 Nick Clifton <nickc@redhat.com> 2002-11-12 Nick Clifton <nickc@redhat.com>
* po/da.po: Updated Danish translation. * po/da.po: Updated Danish translation.

View file

@ -3739,6 +3739,27 @@ extern bfd_byte *bfd_get_relocated_section_contents
boolean boolean
bfd_alt_mach_code PARAMS ((bfd *abfd, int alternative)); bfd_alt_mach_code PARAMS ((bfd *abfd, int alternative));
struct bfd_preserve
{
PTR marker;
PTR tdata;
flagword flags;
const struct bfd_arch_info *arch_info;
struct sec *sections;
struct sec **section_tail;
unsigned int section_count;
struct bfd_hash_table section_htab;
};
boolean
bfd_preserve_save PARAMS ((bfd *, struct bfd_preserve *));
void
bfd_preserve_restore PARAMS ((bfd *, struct bfd_preserve *));
void
bfd_preserve_finish PARAMS ((bfd *, struct bfd_preserve *));
/* Extracted from archive.c. */ /* Extracted from archive.c. */
symindex symindex
bfd_get_next_mapent PARAMS ((bfd *abfd, symindex previous, carsym **sym)); bfd_get_next_mapent PARAMS ((bfd *abfd, symindex previous, carsym **sym));

130
bfd/bfd.c
View file

@ -1392,3 +1392,133 @@ bfd_alt_mach_code (abfd, alternative)
return false; return false;
} }
/*
CODE_FRAGMENT
.struct bfd_preserve
.{
. PTR marker;
. PTR tdata;
. flagword flags;
. const struct bfd_arch_info *arch_info;
. struct sec *sections;
. struct sec **section_tail;
. unsigned int section_count;
. struct bfd_hash_table section_htab;
.};
.
*/
/*
FUNCTION
bfd_preserve_save
SYNOPSIS
boolean bfd_preserve_save (bfd *, struct bfd_preserve *);
DESCRIPTION
When testing an object for compatibility with a particular
target back-end, the back-end object_p function needs to set
up certain fields in the bfd on successfully recognizing the
object. This typically happens in a piecemeal fashion, with
failures possible at many points. On failure, the bfd is
supposed to be restored to its initial state, which is
virtually impossible. However, restoring a subset of the bfd
state works in practice. This function stores the subset and
reinitializes the bfd.
*/
boolean
bfd_preserve_save (abfd, preserve)
bfd *abfd;
struct bfd_preserve *preserve;
{
preserve->tdata = abfd->tdata.any;
preserve->arch_info = abfd->arch_info;
preserve->flags = abfd->flags;
preserve->sections = abfd->sections;
preserve->section_tail = abfd->section_tail;
preserve->section_count = abfd->section_count;
preserve->section_htab = abfd->section_htab;
if (! bfd_hash_table_init (&abfd->section_htab, bfd_section_hash_newfunc))
return false;
abfd->tdata.any = NULL;
abfd->arch_info = &bfd_default_arch_struct;
abfd->flags = 0;
abfd->sections = NULL;
abfd->section_tail = &abfd->sections;
abfd->section_count = 0;
return true;
}
/*
FUNCTION
bfd_preserve_restore
SYNOPSIS
void bfd_preserve_restore (bfd *, struct bfd_preserve *);
DESCRIPTION
This function restores bfd state saved by bfd_preserve_save.
If MARKER is non-NULL in struct bfd_preserve then that block
and all subsequently bfd_alloc'd memory is freed.
*/
void
bfd_preserve_restore (abfd, preserve)
bfd *abfd;
struct bfd_preserve *preserve;
{
bfd_hash_table_free (&abfd->section_htab);
abfd->tdata.any = preserve->tdata;
abfd->arch_info = preserve->arch_info;
abfd->flags = preserve->flags;
abfd->section_htab = preserve->section_htab;
abfd->sections = preserve->sections;
abfd->section_tail = preserve->section_tail;
abfd->section_count = preserve->section_count;
/* bfd_release frees all memory more recently bfd_alloc'd than
its arg, as well as its arg. */
if (preserve->marker != NULL)
{
bfd_release (abfd, preserve->marker);
preserve->marker = NULL;
}
}
/*
FUNCTION
bfd_preserve_finish
SYNOPSIS
void bfd_preserve_finish (bfd *, struct bfd_preserve *);
DESCRIPTION
This function should be called when the bfd state saved by
bfd_preserve_save is no longer needed. ie. when the back-end
object_p function returns with success.
*/
void
bfd_preserve_finish (abfd, preserve)
bfd *abfd ATTRIBUTE_UNUSED;
struct bfd_preserve *preserve;
{
/* It would be nice to be able to free more memory here, eg. old
tdata, but that's not possible since these blocks are sitting
inside bfd_alloc'd memory. The section hash is on a separate
objalloc. */
bfd_hash_table_free (&preserve->section_htab);
}

View file

@ -505,16 +505,6 @@ elf_file_p (x_ehdrp)
&& (x_ehdrp->e_ident[EI_MAG3] == ELFMAG3)); && (x_ehdrp->e_ident[EI_MAG3] == ELFMAG3));
} }
struct bfd_preserve
{
const struct bfd_arch_info *arch_info;
struct elf_obj_tdata *tdata;
struct bfd_hash_table section_htab;
struct sec *sections;
struct sec **section_tail;
unsigned int section_count;
};
/* Check to see if the file associated with ABFD matches the target vector /* Check to see if the file associated with ABFD matches the target vector
that ABFD points to. that ABFD points to.
@ -536,11 +526,10 @@ elf_object_p (abfd)
char *shstrtab; /* Internal copy of section header stringtab */ char *shstrtab; /* Internal copy of section header stringtab */
struct elf_backend_data *ebd; struct elf_backend_data *ebd;
struct bfd_preserve preserve; struct bfd_preserve preserve;
struct elf_obj_tdata *new_tdata = NULL;
asection *s; asection *s;
bfd_size_type amt; bfd_size_type amt;
preserve.arch_info = abfd->arch_info; preserve.marker = NULL;
/* Read in the ELF header in external format. */ /* Read in the ELF header in external format. */
@ -584,23 +573,13 @@ elf_object_p (abfd)
the tdata pointer in the bfd. */ the tdata pointer in the bfd. */
amt = sizeof (struct elf_obj_tdata); amt = sizeof (struct elf_obj_tdata);
new_tdata = (struct elf_obj_tdata *) bfd_zalloc (abfd, amt); preserve.marker = bfd_zalloc (abfd, amt);
if (new_tdata == NULL) if (preserve.marker == NULL)
goto got_no_match;
if (!bfd_preserve_save (abfd, &preserve))
goto got_no_match; goto got_no_match;
preserve.tdata = elf_tdata (abfd);
elf_tdata (abfd) = new_tdata;
/* Clear section information, since there might be a recognized bfd that elf_tdata (abfd) = preserve.marker;
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 got_no_match;
/* Now that we know the byte order, swap in the rest of the header */ /* Now that we know the byte order, swap in the rest of the header */
i_ehdrp = elf_elfheader (abfd); i_ehdrp = elf_elfheader (abfd);
@ -633,8 +612,10 @@ elf_object_p (abfd)
/* Check that the ELF e_machine field matches what this particular /* Check that the ELF e_machine field matches what this particular
BFD format expects. */ BFD format expects. */
if (ebd->elf_machine_code != i_ehdrp->e_machine if (ebd->elf_machine_code != i_ehdrp->e_machine
&& (ebd->elf_machine_alt1 == 0 || i_ehdrp->e_machine != ebd->elf_machine_alt1) && (ebd->elf_machine_alt1 == 0
&& (ebd->elf_machine_alt2 == 0 || i_ehdrp->e_machine != ebd->elf_machine_alt2)) || i_ehdrp->e_machine != ebd->elf_machine_alt1)
&& (ebd->elf_machine_alt2 == 0
|| i_ehdrp->e_machine != ebd->elf_machine_alt2))
{ {
const bfd_target * const *target_ptr; const bfd_target * const *target_ptr;
@ -844,11 +825,8 @@ elf_object_p (abfd)
} }
} }
/* It would be nice to be able to free more memory here, eg. old bfd_preserve_finish (abfd, &preserve);
elf_elfsections, old tdata, but that's not possible since these return abfd->xvec;
blocks are sitting inside obj_alloc'd memory. */
bfd_hash_table_free (&preserve.section_htab);
return (abfd->xvec);
got_wrong_format_error: got_wrong_format_error:
/* There is way too much undoing of half-known state here. The caller, /* There is way too much undoing of half-known state here. The caller,
@ -864,17 +842,8 @@ elf_object_p (abfd)
got_no_match: got_no_match:
abfd->arch_info = preserve.arch_info; abfd->arch_info = preserve.arch_info;
if (new_tdata != NULL) if (preserve.marker != NULL)
{ bfd_preserve_restore (abfd, &preserve);
/* 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;
} }

View file

@ -691,7 +691,7 @@ bfd_mach_o_scan_read_symtab_symbol (abfd, sym, s, i)
unsigned char type = -1; unsigned char type = -1;
unsigned char section = -1; unsigned char section = -1;
short desc = -1; short desc = -1;
long value = -1; unsigned long value = -1;
unsigned long stroff = -1; unsigned long stroff = -1;
unsigned int symtype = -1; unsigned int symtype = -1;
@ -1374,7 +1374,8 @@ bfd_mach_o_scan_read_segment (abfd, command)
{ {
bfd_vma segoff = command->offset + 48 + 8 + (i * 68); bfd_vma segoff = command->offset + 48 + 8 + (i * 68);
if (bfd_mach_o_scan_read_section (abfd, &seg->sections[i], segoff) != 0) if (bfd_mach_o_scan_read_section (abfd, &seg->sections[i],
segoff) != 0)
return -1; return -1;
} }
} }
@ -1455,7 +1456,8 @@ bfd_mach_o_scan_read_command (abfd, command)
return -1; return -1;
command->type = (bfd_h_get_32 (abfd, buf) & ~BFD_MACH_O_LC_REQ_DYLD); command->type = (bfd_h_get_32 (abfd, buf) & ~BFD_MACH_O_LC_REQ_DYLD);
command->type_required = (bfd_h_get_32 (abfd, buf) & BFD_MACH_O_LC_REQ_DYLD) ? 1 : 0; command->type_required = (bfd_h_get_32 (abfd, buf) & BFD_MACH_O_LC_REQ_DYLD
? 1 : 0);
command->len = bfd_h_get_32 (abfd, buf + 4); command->len = bfd_h_get_32 (abfd, buf + 4);
switch (command->type) switch (command->type)
@ -1531,20 +1533,24 @@ bfd_mach_o_flatten_sections (abfd)
{ {
if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT) if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT)
{ {
bfd_mach_o_segment_command *seg = &mdata->commands[i].command.segment; bfd_mach_o_segment_command *seg;
seg = &mdata->commands[i].command.segment;
mdata->nsects += seg->nsects; mdata->nsects += seg->nsects;
} }
} }
mdata->sections = bfd_alloc (abfd, mdata->nsects * sizeof (bfd_mach_o_section *)); mdata->sections = bfd_alloc (abfd,
mdata->nsects * sizeof (bfd_mach_o_section *));
csect = 0; csect = 0;
for (i = 0; i < mdata->header.ncmds; i++) for (i = 0; i < mdata->header.ncmds; i++)
{ {
if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT) if (mdata->commands[i].type == BFD_MACH_O_LC_SEGMENT)
{ {
bfd_mach_o_segment_command *seg = &mdata->commands[i].command.segment; bfd_mach_o_segment_command *seg;
seg = &mdata->commands[i].command.segment;
BFD_ASSERT (csect + seg->nsects <= mdata->nsects); BFD_ASSERT (csect + seg->nsects <= mdata->nsects);
for (j = 0; j < seg->nsects; j++) for (j = 0; j < seg->nsects; j++)
@ -1579,7 +1585,8 @@ bfd_mach_o_scan_start_address (abfd)
for (i = 0; i < cmd->nflavours; i++) for (i = 0; i < cmd->nflavours; i++)
{ {
if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386) if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
&& (cmd->flavours[i].flavour == (unsigned long) BFD_MACH_O_i386_THREAD_STATE)) && (cmd->flavours[i].flavour
== (unsigned long) BFD_MACH_O_i386_THREAD_STATE))
{ {
unsigned char buf[4]; unsigned char buf[4];
@ -1608,27 +1615,24 @@ bfd_mach_o_scan_start_address (abfd)
} }
int int
bfd_mach_o_scan (abfd, header) bfd_mach_o_scan (abfd, header, mdata)
bfd *abfd; bfd *abfd;
bfd_mach_o_header *header; bfd_mach_o_header *header;
bfd_mach_o_data_struct *mdata;
{ {
unsigned int i; unsigned int i;
bfd_mach_o_data_struct *mdata = NULL;
enum bfd_architecture cputype; enum bfd_architecture cputype;
unsigned long cpusubtype; unsigned long cpusubtype;
mdata = ((bfd_mach_o_data_struct *)
bfd_alloc (abfd, sizeof (bfd_mach_o_data_struct)));
if (mdata == NULL)
return -1;
mdata->header = *header; mdata->header = *header;
mdata->symbols = NULL; mdata->symbols = NULL;
abfd->flags = abfd->xvec->object_flags | (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS)); abfd->flags = (abfd->xvec->object_flags
| (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS)));
abfd->tdata.mach_o_data = mdata; abfd->tdata.mach_o_data = mdata;
bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype, &cputype, &cpusubtype); bfd_mach_o_convert_architecture (header->cputype, header->cpusubtype,
&cputype, &cpusubtype);
if (cputype == bfd_arch_unknown) if (cputype == bfd_arch_unknown)
{ {
fprintf (stderr, "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx\n", fprintf (stderr, "bfd_mach_o_scan: unknown architecture 0x%lx/0x%lx\n",
@ -1712,84 +1716,99 @@ const bfd_target *
bfd_mach_o_object_p (abfd) bfd_mach_o_object_p (abfd)
bfd *abfd; bfd *abfd;
{ {
struct bfd_preserve preserve;
bfd_mach_o_header header; bfd_mach_o_header header;
preserve.marker = NULL;
if (bfd_mach_o_read_header (abfd, &header) != 0) if (bfd_mach_o_read_header (abfd, &header) != 0)
goto wrong;
if (! (header.byteorder == BFD_ENDIAN_BIG
|| header.byteorder == BFD_ENDIAN_LITTLE))
{ {
bfd_set_error (bfd_error_wrong_format); fprintf (stderr, "unknown header byte-order value 0x%lx\n",
return NULL; (long) header.byteorder);
goto wrong;
} }
if (! ((header.byteorder == BFD_ENDIAN_BIG) if (! ((header.byteorder == BFD_ENDIAN_BIG
|| (header.byteorder == BFD_ENDIAN_LITTLE))) && abfd->xvec->byteorder == BFD_ENDIAN_BIG
{ && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
fprintf (stderr, "unknown header byte-order value 0x%lx\n", (long) header.byteorder); || (header.byteorder == BFD_ENDIAN_LITTLE
bfd_set_error (bfd_error_wrong_format); && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
return NULL; && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
} goto wrong;
if (! (((header.byteorder == BFD_ENDIAN_BIG) preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
&& (abfd->xvec->byteorder == BFD_ENDIAN_BIG) if (preserve.marker == NULL
&& (abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)) || !bfd_preserve_save (abfd, &preserve))
|| goto fail;
((header.byteorder == BFD_ENDIAN_LITTLE)
&& (abfd->xvec->byteorder == BFD_ENDIAN_LITTLE)
&& (abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE))))
{
bfd_set_error (bfd_error_wrong_format);
return NULL;
}
abfd->tdata.mach_o_data = NULL; if (bfd_mach_o_scan (abfd, &header,
(bfd_mach_o_data_struct *) preserve.marker) != 0)
if (bfd_mach_o_scan (abfd, &header) != 0) goto wrong;
{
abfd->tdata.mach_o_data = NULL;
bfd_set_error (bfd_error_wrong_format);
return NULL;
}
bfd_preserve_finish (abfd, &preserve);
return abfd->xvec; return abfd->xvec;
wrong:
bfd_set_error (bfd_error_wrong_format);
fail:
if (preserve.marker != NULL)
bfd_preserve_restore (abfd, &preserve);
return NULL;
} }
const bfd_target * const bfd_target *
bfd_mach_o_core_p (abfd) bfd_mach_o_core_p (abfd)
bfd *abfd; bfd *abfd;
{ {
struct bfd_preserve preserve;
bfd_mach_o_header header; bfd_mach_o_header header;
bfd_set_error (bfd_error_wrong_format); preserve.marker = NULL;
if (bfd_mach_o_read_header (abfd, &header) != 0) if (bfd_mach_o_read_header (abfd, &header) != 0)
return NULL; goto wrong;
if (! ((header.byteorder == BFD_ENDIAN_BIG) if (! (header.byteorder == BFD_ENDIAN_BIG
|| (header.byteorder == BFD_ENDIAN_LITTLE))) || header.byteorder == BFD_ENDIAN_LITTLE))
{ {
fprintf (stderr, "unknown header byte-order value 0x%lx\n", (long) header.byteorder); fprintf (stderr, "unknown header byte-order value 0x%lx\n",
(long) header.byteorder);
abort (); abort ();
} }
if (! (((header.byteorder == BFD_ENDIAN_BIG) if (! ((header.byteorder == BFD_ENDIAN_BIG
&& (abfd->xvec->byteorder == BFD_ENDIAN_BIG) && abfd->xvec->byteorder == BFD_ENDIAN_BIG
&& (abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)) && abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
|| || (header.byteorder == BFD_ENDIAN_LITTLE
((header.byteorder == BFD_ENDIAN_LITTLE) && abfd->xvec->byteorder == BFD_ENDIAN_LITTLE
&& (abfd->xvec->byteorder == BFD_ENDIAN_LITTLE) && abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))
&& (abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)))) goto wrong;
return NULL;
if (header.filetype != BFD_MACH_O_MH_CORE) if (header.filetype != BFD_MACH_O_MH_CORE)
return NULL; goto wrong;
abfd->tdata.mach_o_data = NULL; preserve.marker = bfd_zalloc (abfd, sizeof (bfd_mach_o_data_struct));
if (bfd_mach_o_scan (abfd, &header) != 0) if (preserve.marker == NULL
{ || !bfd_preserve_save (abfd, &preserve))
abfd->tdata.mach_o_data = NULL; goto fail;
return NULL;
}
if (bfd_mach_o_scan (abfd, &header,
(bfd_mach_o_data_struct *) preserve.marker) != 0)
goto wrong;
bfd_preserve_finish (abfd, &preserve);
return abfd->xvec; return abfd->xvec;
wrong:
bfd_set_error (bfd_error_wrong_format);
fail:
if (preserve.marker != NULL)
bfd_preserve_restore (abfd, &preserve);
return NULL;
} }
typedef struct mach_o_fat_archentry typedef struct mach_o_fat_archentry
@ -1813,35 +1832,35 @@ const bfd_target *
bfd_mach_o_archive_p (abfd) bfd_mach_o_archive_p (abfd)
bfd *abfd; bfd *abfd;
{ {
mach_o_fat_data_struct *adata; mach_o_fat_data_struct *adata = NULL;
unsigned char buf[20]; unsigned char buf[20];
unsigned long i; unsigned long i;
bfd_seek (abfd, 0, SEEK_SET); bfd_seek (abfd, 0, SEEK_SET);
if (bfd_bread ((PTR) buf, 8, abfd) != 8) if (bfd_bread ((PTR) buf, 8, abfd) != 8)
return NULL; goto error;
adata = (mach_o_fat_data_struct *) adata = (mach_o_fat_data_struct *)
bfd_alloc (abfd, sizeof (mach_o_fat_data_struct)); bfd_alloc (abfd, sizeof (mach_o_fat_data_struct));
if (adata == NULL) if (adata == NULL)
return NULL; goto error;
adata->magic = bfd_getb32 (buf); adata->magic = bfd_getb32 (buf);
adata->nfat_arch = bfd_getb32 (buf + 4); adata->nfat_arch = bfd_getb32 (buf + 4);
if (adata->magic != 0xcafebabe) if (adata->magic != 0xcafebabe)
return NULL; goto error;
adata->archentries = (mach_o_fat_archentry *) adata->archentries = (mach_o_fat_archentry *)
bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry)); bfd_alloc (abfd, adata->nfat_arch * sizeof (mach_o_fat_archentry));
if (adata->archentries == NULL) if (adata->archentries == NULL)
return NULL; goto error;
for (i = 0; i < adata->nfat_arch; i++) for (i = 0; i < adata->nfat_arch; i++)
{ {
bfd_seek (abfd, 8 + 20 * i, SEEK_SET); bfd_seek (abfd, 8 + 20 * i, SEEK_SET);
if (bfd_bread ((PTR) buf, 20, abfd) != 20) if (bfd_bread ((PTR) buf, 20, abfd) != 20)
return NULL; goto error;
adata->archentries[i].cputype = bfd_getb32 (buf); adata->archentries[i].cputype = bfd_getb32 (buf);
adata->archentries[i].cpusubtype = bfd_getb32 (buf + 4); adata->archentries[i].cpusubtype = bfd_getb32 (buf + 4);
adata->archentries[i].offset = bfd_getb32 (buf + 8); adata->archentries[i].offset = bfd_getb32 (buf + 8);
@ -1852,6 +1871,12 @@ bfd_mach_o_archive_p (abfd)
abfd->tdata.mach_o_fat_data = adata; abfd->tdata.mach_o_fat_data = adata;
return abfd->xvec; return abfd->xvec;
error:
if (adata != NULL)
bfd_release (abfd, adata);
bfd_set_error (bfd_error_wrong_format);
return NULL;
} }
bfd * bfd *
@ -1859,10 +1884,11 @@ bfd_mach_o_openr_next_archived_file (archive, prev)
bfd *archive; bfd *archive;
bfd *prev; bfd *prev;
{ {
mach_o_fat_data_struct *adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data; mach_o_fat_data_struct *adata;
mach_o_fat_archentry *entry = NULL; mach_o_fat_archentry *entry = NULL;
unsigned long i; unsigned long i;
adata = (mach_o_fat_data_struct *) archive->tdata.mach_o_fat_data;
BFD_ASSERT (adata != NULL); BFD_ASSERT (adata != NULL);
/* Find index of previous entry. */ /* Find index of previous entry. */
@ -1913,9 +1939,12 @@ bfd_mach_o_openr_next_archived_file (archive, prev)
return entry->abfd; return entry->abfd;
} }
int bfd_mach_o_lookup_section int
(bfd *abfd, asection *section, bfd_mach_o_lookup_section (abfd, section, mcommand, msection)
bfd_mach_o_load_command **mcommand, bfd_mach_o_section **msection) bfd *abfd;
asection *section;
bfd_mach_o_load_command **mcommand;
bfd_mach_o_section **msection;
{ {
struct mach_o_data_struct *md = abfd->tdata.mach_o_data; struct mach_o_data_struct *md = abfd->tdata.mach_o_data;
unsigned int i, j, num; unsigned int i, j, num;
@ -1962,9 +1991,10 @@ int bfd_mach_o_lookup_section
} }
int int
bfd_mach_o_lookup_command bfd_mach_o_lookup_command (abfd, type, mcommand)
(bfd *abfd, bfd_mach_o_load_command_type type, bfd *abfd;
bfd_mach_o_load_command **mcommand) bfd_mach_o_load_command_type type;
bfd_mach_o_load_command **mcommand;
{ {
struct mach_o_data_struct *md = NULL; struct mach_o_data_struct *md = NULL;
bfd_mach_o_load_command *ncmd = NULL; bfd_mach_o_load_command *ncmd = NULL;
@ -2011,7 +2041,7 @@ bfd_mach_o_stack_addr (type)
case BFD_MACH_O_CPU_TYPE_I860: case BFD_MACH_O_CPU_TYPE_I860:
return 0; return 0;
case BFD_MACH_O_CPU_TYPE_HPPA: case BFD_MACH_O_CPU_TYPE_HPPA:
return (0xc0000000-0x04000000); return 0xc0000000 - 0x04000000;
default: default:
return 0; return 0;
} }
@ -2063,8 +2093,9 @@ bfd_mach_o_core_fetch_environment (abfd, rbuf, rlen)
for (offset = 4; offset <= size; offset += 4) for (offset = 4; offset <= size; offset += 4)
{ {
unsigned long val = *((unsigned long *) (buf + size - offset)); unsigned long val;
val = *((unsigned long *) (buf + size - offset));
if (! found_nonnull) if (! found_nonnull)
{ {
if (val != 0) if (val != 0)
@ -2072,9 +2103,11 @@ bfd_mach_o_core_fetch_environment (abfd, rbuf, rlen)
} }
else if (val == 0x0) else if (val == 0x0)
{ {
unsigned long bottom = seg->fileoff + seg->filesize - offset; unsigned long bottom;
unsigned long top = seg->fileoff + seg->filesize - 4; unsigned long top;
bottom = seg->fileoff + seg->filesize - offset;
top = seg->fileoff + seg->filesize - 4;
*rbuf = bfd_malloc (top - bottom); *rbuf = bfd_malloc (top - bottom);
*rlen = top - bottom; *rlen = top - bottom;
@ -2159,4 +2192,3 @@ bfd_mach_o_core_file_matches_executable_p (core_bfd, exec_bfd)
#undef TARGET_STRING #undef TARGET_STRING
#undef TARGET_BIG_ENDIAN #undef TARGET_BIG_ENDIAN
#undef TARGET_ARCHIVE #undef TARGET_ARCHIVE

View file

@ -469,7 +469,7 @@ int bfd_mach_o_scan_read_symtab_strtab PARAMS ((bfd *, bfd_mach
int bfd_mach_o_scan_read_symtab_symbols PARAMS ((bfd *, bfd_mach_o_symtab_command *)); int bfd_mach_o_scan_read_symtab_symbols PARAMS ((bfd *, bfd_mach_o_symtab_command *));
int bfd_mach_o_scan_read_dysymtab_symbol PARAMS ((bfd *, bfd_mach_o_dysymtab_command *, bfd_mach_o_symtab_command *, asymbol *, unsigned long)); int bfd_mach_o_scan_read_dysymtab_symbol PARAMS ((bfd *, bfd_mach_o_dysymtab_command *, bfd_mach_o_symtab_command *, asymbol *, unsigned long));
int bfd_mach_o_scan_start_address PARAMS ((bfd *)); int bfd_mach_o_scan_start_address PARAMS ((bfd *));
int bfd_mach_o_scan PARAMS ((bfd *, bfd_mach_o_header *)); int bfd_mach_o_scan PARAMS ((bfd *, bfd_mach_o_header *, bfd_mach_o_data_struct *));
boolean bfd_mach_o_mkobject PARAMS ((bfd *)); boolean bfd_mach_o_mkobject PARAMS ((bfd *));
const bfd_target * bfd_mach_o_object_p PARAMS ((bfd *)); const bfd_target * bfd_mach_o_object_p PARAMS ((bfd *));
const bfd_target * bfd_mach_o_core_p PARAMS ((bfd *)); const bfd_target * bfd_mach_o_core_p PARAMS ((bfd *));

495
bfd/pef.c
View file

@ -78,7 +78,8 @@ PARAMS ((bfd *abfd, asection *section, unsigned char *buf,
size_t len, size_t pos, asymbol *sym, FILE *file)); size_t len, size_t pos, asymbol *sym, FILE *file));
static const char *bfd_pef_section_name PARAMS ((bfd_pef_section *section)); static const char *bfd_pef_section_name PARAMS ((bfd_pef_section *section));
static unsigned long bfd_pef_section_flags PARAMS ((bfd_pef_section *section)); static unsigned long bfd_pef_section_flags PARAMS ((bfd_pef_section *section));
static asection *bfd_pef_make_bfd_section PARAMS ((bfd *abfd, bfd_pef_section *section)); static asection *bfd_pef_make_bfd_section
PARAMS ((bfd *abfd, bfd_pef_section *section));
static int bfd_pef_read_header PARAMS ((bfd *abfd, bfd_pef_header *header)); static int bfd_pef_read_header PARAMS ((bfd *abfd, bfd_pef_header *header));
static const bfd_target *bfd_pef_object_p PARAMS ((bfd *)); static const bfd_target *bfd_pef_object_p PARAMS ((bfd *));
static int bfd_pef_parse_traceback_tables static int bfd_pef_parse_traceback_tables
@ -88,7 +89,8 @@ static int bfd_pef_parse_function_stub
PARAMS ((bfd *abfd, unsigned char *buf, size_t len, unsigned long *offset)); PARAMS ((bfd *abfd, unsigned char *buf, size_t len, unsigned long *offset));
static int bfd_pef_parse_function_stubs static int bfd_pef_parse_function_stubs
PARAMS ((bfd *abfd, asection *codesec, unsigned char *codebuf, size_t codelen, PARAMS ((bfd *abfd, asection *codesec, unsigned char *codebuf, size_t codelen,
unsigned char *loaderbuf, size_t loaderlen, unsigned long *nsym, asymbol **csym)); unsigned char *loaderbuf, size_t loaderlen, unsigned long *nsym,
asymbol **csym));
static long bfd_pef_parse_symbols PARAMS ((bfd *abfd, asymbol **csym)); static long bfd_pef_parse_symbols PARAMS ((bfd *abfd, asymbol **csym));
static long bfd_pef_count_symbols PARAMS ((bfd *abfd)); static long bfd_pef_count_symbols PARAMS ((bfd *abfd));
static long bfd_pef_get_symtab_upper_bound PARAMS ((bfd *)); static long bfd_pef_get_symtab_upper_bound PARAMS ((bfd *));
@ -97,7 +99,8 @@ static asymbol *bfd_pef_make_empty_symbol PARAMS ((bfd *));
static void bfd_pef_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *)); static void bfd_pef_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *));
static int bfd_pef_sizeof_headers PARAMS ((bfd *, boolean)); static int bfd_pef_sizeof_headers PARAMS ((bfd *, boolean));
static int bfd_pef_xlib_read_header PARAMS ((bfd *abfd, bfd_pef_xlib_header *header)); static int bfd_pef_xlib_read_header
PARAMS ((bfd *abfd, bfd_pef_xlib_header *header));
static int bfd_pef_xlib_scan PARAMS ((bfd *abfd, bfd_pef_xlib_header *header)); static int bfd_pef_xlib_scan PARAMS ((bfd *abfd, bfd_pef_xlib_header *header));
static const bfd_target *bfd_pef_xlib_object_p PARAMS ((bfd *abfd)); static const bfd_target *bfd_pef_xlib_object_p PARAMS ((bfd *abfd));
@ -109,29 +112,32 @@ bfd_pef_print_symbol (abfd, afile, symbol, how)
bfd_print_symbol_type how; bfd_print_symbol_type how;
{ {
FILE *file = (FILE *) afile; FILE *file = (FILE *) afile;
switch (how) { switch (how)
{
case bfd_print_symbol_name: case bfd_print_symbol_name:
fprintf (file, "%s", symbol->name); fprintf (file, "%s", symbol->name);
break; break;
default: default:
bfd_print_symbol_vandf (abfd, (PTR) file, symbol); bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
fprintf (file, " %-5s %s", symbol->section->name, symbol->name); fprintf (file, " %-5s %s", symbol->section->name, symbol->name);
if (strncmp (symbol->name, "__traceback_", strlen ("__traceback_")) == 0) { if (strncmp (symbol->name, "__traceback_", strlen ("__traceback_")) == 0)
{
char *buf = alloca (symbol->udata.i); char *buf = alloca (symbol->udata.i);
size_t offset = symbol->value + 4; size_t offset = symbol->value + 4;
size_t len = symbol->udata.i; size_t len = symbol->udata.i;
int ret; int ret;
bfd_get_section_contents (abfd, symbol->section, buf, offset, len); bfd_get_section_contents (abfd, symbol->section, buf, offset, len);
ret = bfd_pef_parse_traceback_table (abfd, symbol->section, buf, len, 0, NULL, file); ret = bfd_pef_parse_traceback_table (abfd, symbol->section, buf,
if (ret < 0) { len, 0, NULL, file);
if (ret < 0)
fprintf (file, " [ERROR]"); fprintf (file, " [ERROR]");
} }
} }
}
} }
static void bfd_pef_convert_architecture (architecture, type, subtype) static void
bfd_pef_convert_architecture (architecture, type, subtype)
unsigned long architecture; unsigned long architecture;
enum bfd_architecture *type; enum bfd_architecture *type;
unsigned long *subtype; unsigned long *subtype;
@ -170,7 +176,8 @@ bfd_pef_parse_traceback_table (abfd, section, buf, len, pos, sym, file)
const char *s; const char *s;
asymbol tmpsymbol; asymbol tmpsymbol;
if (sym == NULL) { sym = &tmpsymbol; } if (sym == NULL)
sym = &tmpsymbol;
sym->name = NULL; sym->name = NULL;
sym->value = 0; sym->value = 0;
@ -181,120 +188,119 @@ bfd_pef_parse_traceback_table (abfd, section, buf, len, pos, sym, file)
/* memcpy is fine since all fields are unsigned char */ /* memcpy is fine since all fields are unsigned char */
if ((pos + 8) > len) { return -1; } if ((pos + 8) > len)
return -1;
memcpy (&table, buf + pos, 8); memcpy (&table, buf + pos, 8);
/* calling code relies on returned symbols having a name and correct offset */ /* calling code relies on returned symbols having a name and
correct offset */
if ((table.lang != TB_C) && (table.lang != TB_CPLUSPLUS)) { if ((table.lang != TB_C) && (table.lang != TB_CPLUSPLUS))
return -1; return -1;
}
if (! (table.flags2 & TB_NAME_PRESENT)) { if (! (table.flags2 & TB_NAME_PRESENT))
return -1; return -1;
}
if (! table.flags1 & TB_HAS_TBOFF) { if (! table.flags1 & TB_HAS_TBOFF)
return -1; return -1;
}
offset = 8; offset = 8;
if ((table.flags5 & TB_FLOATPARAMS) || (table.fixedparams)) { if ((table.flags5 & TB_FLOATPARAMS) || (table.fixedparams))
offset += 4; offset += 4;
}
if (table.flags1 & TB_HAS_TBOFF) {
if (table.flags1 & TB_HAS_TBOFF)
{
struct traceback_table_tboff off; struct traceback_table_tboff off;
if ((pos + offset + 4) > len) { return -1; } if ((pos + offset + 4) > len)
return -1;
off.tb_offset = bfd_getb32 (buf + pos + offset); off.tb_offset = bfd_getb32 (buf + pos + offset);
offset += 4; offset += 4;
/* need to subtract 4 because the offset includes the 0x0L /* need to subtract 4 because the offset includes the 0x0L
preceding the table */ preceding the table */
if (file != NULL) { if (file != NULL)
fprintf (file, " [offset = 0x%lx]", off.tb_offset); fprintf (file, " [offset = 0x%lx]", off.tb_offset);
}
if ((file == NULL) && ((off.tb_offset + 4) > (pos + offset))) { if ((file == NULL) && ((off.tb_offset + 4) > (pos + offset)))
return -1; return -1;
}
sym->value = pos - off.tb_offset - 4; sym->value = pos - off.tb_offset - 4;
} }
if (table.flags2 & TB_INT_HNDL) { if (table.flags2 & TB_INT_HNDL)
offset += 4; offset += 4;
}
if (table.flags1 & TB_HAS_CTL) {
if (table.flags1 & TB_HAS_CTL)
{
struct traceback_table_anchors anchors; struct traceback_table_anchors anchors;
if ((pos + offset + 4) > len) { return -1; } if ((pos + offset + 4) > len)
return -1;
anchors.ctl_info = bfd_getb32 (buf + pos + offset); anchors.ctl_info = bfd_getb32 (buf + pos + offset);
offset += 4; offset += 4;
if (anchors.ctl_info > 1024) { if (anchors.ctl_info > 1024)
return -1; return -1;
}
offset += anchors.ctl_info * 4; offset += anchors.ctl_info * 4;
} }
if (table.flags2 & TB_NAME_PRESENT) { if (table.flags2 & TB_NAME_PRESENT)
{
struct traceback_table_routine name; struct traceback_table_routine name;
char *namebuf; char *namebuf;
if ((pos + offset + 2) > len) { return -1; } if ((pos + offset + 2) > len)
return -1;
name.name_len = bfd_getb16 (buf + pos + offset); name.name_len = bfd_getb16 (buf + pos + offset);
offset += 2; offset += 2;
if (name.name_len > 4096) { return -1; } if (name.name_len > 4096)
return -1;
if ((pos + offset + name.name_len) > len) { return -1; } if ((pos + offset + name.name_len) > len)
return -1;
namebuf = (char *) bfd_alloc (abfd, name.name_len + 1); namebuf = (char *) bfd_alloc (abfd, name.name_len + 1);
if (namebuf == NULL) { return -1; } if (namebuf == NULL)
return -1;
memcpy (namebuf, buf + pos + offset, name.name_len); memcpy (namebuf, buf + pos + offset, name.name_len);
namebuf[name.name_len] = '\0'; namebuf[name.name_len] = '\0';
/* strip leading period inserted by compiler */ /* strip leading period inserted by compiler */
if (namebuf[0] == '.') { if (namebuf[0] == '.')
memmove (namebuf, namebuf + 1, name.name_len + 1); memmove (namebuf, namebuf + 1, name.name_len + 1);
}
sym->name = namebuf; sym->name = namebuf;
for (s = sym->name; (*s != '\0'); s++) { for (s = sym->name; (*s != '\0'); s++)
if (! isprint (*s)) { if (! isprint (*s))
return -1; return -1;
}
}
offset += name.name_len; offset += name.name_len;
} }
if (table.flags2 & TB_USES_ALLOCA) { if (table.flags2 & TB_USES_ALLOCA)
offset += 4; offset += 4;
}
if (table.flags4 & TB_HAS_VEC_INFO) { if (table.flags4 & TB_HAS_VEC_INFO)
offset += 4; offset += 4;
}
if (file != NULL) { if (file != NULL)
fprintf (file, " [length = 0x%lx]", (long) offset); fprintf (file, " [length = 0x%lx]", (long) offset);
}
return offset; return offset;
} }
static const char *bfd_pef_section_name (section) static const char *bfd_pef_section_name (section)
bfd_pef_section *section; bfd_pef_section *section;
{ {
switch (section->section_kind) { switch (section->section_kind)
{
case BFD_PEF_SECTION_CODE: return "code"; case BFD_PEF_SECTION_CODE: return "code";
case BFD_PEF_SECTION_UNPACKED_DATA: return "unpacked-data"; case BFD_PEF_SECTION_UNPACKED_DATA: return "unpacked-data";
case BFD_PEF_SECTION_PACKED_DATA: return "packed-data"; case BFD_PEF_SECTION_PACKED_DATA: return "packed-data";
@ -311,7 +317,8 @@ static const char *bfd_pef_section_name (section)
static unsigned long bfd_pef_section_flags (section) static unsigned long bfd_pef_section_flags (section)
bfd_pef_section *section; bfd_pef_section *section;
{ {
switch (section->section_kind) { switch (section->section_kind)
{
case BFD_PEF_SECTION_CODE: case BFD_PEF_SECTION_CODE:
return SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE; return SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
case BFD_PEF_SECTION_UNPACKED_DATA: case BFD_PEF_SECTION_UNPACKED_DATA:
@ -336,7 +343,8 @@ bfd_pef_make_bfd_section (abfd, section)
const char *name = bfd_pef_section_name (section); const char *name = bfd_pef_section_name (section);
bfdsec = bfd_make_section_anyway (abfd, name); bfdsec = bfd_make_section_anyway (abfd, name);
if (bfdsec == NULL) { return NULL; } if (bfdsec == NULL)
return NULL;
bfdsec->vma = section->default_address + section->container_offset; bfdsec->vma = section->default_address + section->container_offset;
bfdsec->lma = section->default_address + section->container_offset; bfdsec->lma = section->default_address + section->container_offset;
@ -419,7 +427,8 @@ int bfd_pef_scan_section (abfd, section)
unsigned char buf[28]; unsigned char buf[28];
bfd_seek (abfd, section->header_offset, SEEK_SET); bfd_seek (abfd, section->header_offset, SEEK_SET);
if (bfd_bread ((PTR) buf, 28, abfd) != 28) { return -1; } if (bfd_bread ((PTR) buf, 28, abfd) != 28)
return -1;
section->name_offset = bfd_h_get_32 (abfd, buf); section->name_offset = bfd_h_get_32 (abfd, buf);
section->default_address = bfd_h_get_32 (abfd, buf + 4); section->default_address = bfd_h_get_32 (abfd, buf + 4);
@ -433,7 +442,8 @@ int bfd_pef_scan_section (abfd, section)
section->reserved = buf[27]; section->reserved = buf[27];
section->bfd_section = bfd_pef_make_bfd_section (abfd, section); section->bfd_section = bfd_pef_make_bfd_section (abfd, section);
if (section->bfd_section == NULL) { return -1; } if (section->bfd_section == NULL)
return -1;
return 0; return 0;
} }
@ -450,14 +460,19 @@ bfd_pef_print_loader_header (abfd, header, file)
fprintf (file, "init_offset: %lu\n", header->init_offset); fprintf (file, "init_offset: %lu\n", header->init_offset);
fprintf (file, "term_section: %ld\n", header->term_section); fprintf (file, "term_section: %ld\n", header->term_section);
fprintf (file, "term_offset: %lu\n", header->term_offset); fprintf (file, "term_offset: %lu\n", header->term_offset);
fprintf (file, "imported_library_count: %lu\n", header->imported_library_count); fprintf (file, "imported_library_count: %lu\n",
fprintf (file, "total_imported_symbol_count: %lu\n", header->total_imported_symbol_count); header->imported_library_count);
fprintf (file, "total_imported_symbol_count: %lu\n",
header->total_imported_symbol_count);
fprintf (file, "reloc_section_count: %lu\n", header->reloc_section_count); fprintf (file, "reloc_section_count: %lu\n", header->reloc_section_count);
fprintf (file, "reloc_instr_offset: %lu\n", header->reloc_instr_offset); fprintf (file, "reloc_instr_offset: %lu\n", header->reloc_instr_offset);
fprintf (file, "loader_strings_offset: %lu\n", header->loader_strings_offset); fprintf (file, "loader_strings_offset: %lu\n",
header->loader_strings_offset);
fprintf (file, "export_hash_offset: %lu\n", header->export_hash_offset); fprintf (file, "export_hash_offset: %lu\n", header->export_hash_offset);
fprintf (file, "export_hash_table_power: %lu\n", header->export_hash_table_power); fprintf (file, "export_hash_table_power: %lu\n",
fprintf (file, "exported_symbol_count: %lu\n", header->exported_symbol_count); header->export_hash_table_power);
fprintf (file, "exported_symbol_count: %lu\n",
header->exported_symbol_count);
} }
int int
@ -472,18 +487,33 @@ bfd_pef_print_loader_section (abfd, file)
int ret; int ret;
loadersec = bfd_get_section_by_name (abfd, "loader"); loadersec = bfd_get_section_by_name (abfd, "loader");
if (loadersec == NULL) { return -1; } if (loadersec == NULL)
return -1;
loaderlen = bfd_section_size (abfd, loadersec); loaderlen = bfd_section_size (abfd, loadersec);
loaderbuf = (unsigned char *) bfd_malloc (loaderlen); loaderbuf = (unsigned char *) bfd_malloc (loaderlen);
if (bfd_seek (abfd, loadersec->filepos, SEEK_SET) < 0) if (bfd_seek (abfd, loadersec->filepos, SEEK_SET) < 0)
{ free (loaderbuf); return -1; } {
free (loaderbuf);
return -1;
}
if (bfd_bread ((PTR) loaderbuf, loaderlen, abfd) != loaderlen) if (bfd_bread ((PTR) loaderbuf, loaderlen, abfd) != loaderlen)
{ free (loaderbuf); return -1; } {
free (loaderbuf);
return -1;
}
if (loaderlen < 56) { free (loaderbuf); return -1; } if (loaderlen < 56)
{
free (loaderbuf);
return -1;
}
ret = bfd_pef_parse_loader_header (abfd, loaderbuf, 56, &header); ret = bfd_pef_parse_loader_header (abfd, loaderbuf, 56, &header);
if (ret < 0) { free (loaderbuf); return -1; } if (ret < 0)
{
free (loaderbuf);
return -1;
}
bfd_pef_print_loader_header (abfd, &header, file); bfd_pef_print_loader_header (abfd, &header, file);
return 0; return 0;
@ -502,86 +532,94 @@ bfd_pef_scan_start_address (abfd)
int ret; int ret;
loadersec = bfd_get_section_by_name (abfd, "loader"); loadersec = bfd_get_section_by_name (abfd, "loader");
if (loadersec == NULL) { goto end; } if (loadersec == NULL)
goto end;
loaderlen = bfd_section_size (abfd, loadersec); loaderlen = bfd_section_size (abfd, loadersec);
loaderbuf = (unsigned char *) bfd_malloc (loaderlen); loaderbuf = (unsigned char *) bfd_malloc (loaderlen);
if (bfd_seek (abfd, loadersec->filepos, SEEK_SET) < 0) { goto error; } if (bfd_seek (abfd, loadersec->filepos, SEEK_SET) < 0)
if (bfd_bread ((PTR) loaderbuf, loaderlen, abfd) != loaderlen) { goto error; } goto error;
if (bfd_bread ((PTR) loaderbuf, loaderlen, abfd) != loaderlen)
goto error;
if (loaderlen < 56) { goto error; } if (loaderlen < 56)
goto error;
ret = bfd_pef_parse_loader_header (abfd, loaderbuf, 56, &header); ret = bfd_pef_parse_loader_header (abfd, loaderbuf, 56, &header);
if (ret < 0) { goto error; } if (ret < 0)
goto error;
if (header.main_section < 0) { goto end; } if (header.main_section < 0)
goto end;
for (section = abfd->sections; section != NULL; section = section->next) { for (section = abfd->sections; section != NULL; section = section->next)
if ((section->index + 1) == header.main_section) { break; } if ((section->index + 1) == header.main_section)
} break;
if (section == NULL) { goto error; } if (section == NULL)
goto error;
abfd->start_address = section->vma + header.main_offset; abfd->start_address = section->vma + header.main_offset;
end: end:
if (loaderbuf != NULL) { free (loaderbuf); } if (loaderbuf != NULL)
free (loaderbuf);
return 0; return 0;
error: error:
if (loaderbuf != NULL) { free (loaderbuf); } if (loaderbuf != NULL)
free (loaderbuf);
return -1; return -1;
} }
int int
bfd_pef_scan (abfd, header) bfd_pef_scan (abfd, header, mdata)
bfd *abfd; bfd *abfd;
bfd_pef_header *header; bfd_pef_header *header;
bfd_pef_data_struct *mdata;
{ {
unsigned int i; unsigned int i;
bfd_pef_data_struct *mdata = NULL;
enum bfd_architecture cputype; enum bfd_architecture cputype;
unsigned long cpusubtype; unsigned long cpusubtype;
if ((header->tag1 != BFD_PEF_TAG1) || (header->tag2 != BFD_PEF_TAG2)) { mdata->header = *header;
return -1;
}
mdata = ((bfd_pef_data_struct *)
bfd_alloc (abfd, sizeof (bfd_pef_data_struct)));
if (mdata == NULL) { return -1; }
bfd_pef_convert_architecture (header->architecture, &cputype, &cpusubtype); bfd_pef_convert_architecture (header->architecture, &cputype, &cpusubtype);
if (cputype == bfd_arch_unknown) { if (cputype == bfd_arch_unknown)
fprintf (stderr, "bfd_pef_scan: unknown architecture 0x%lx\n", header->architecture); {
fprintf (stderr, "bfd_pef_scan: unknown architecture 0x%lx\n",
header->architecture);
return -1; return -1;
} }
bfd_set_arch_mach (abfd, cputype, cpusubtype); bfd_set_arch_mach (abfd, cputype, cpusubtype);
mdata->header = *header; mdata->header = *header;
abfd->flags = abfd->xvec->object_flags | (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS)); abfd->flags = (abfd->xvec->object_flags
| (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS)));
if (header->section_count != 0) {
if (header->section_count != 0)
{
mdata->sections = mdata->sections =
((bfd_pef_section *) ((bfd_pef_section *)
bfd_alloc (abfd, header->section_count * sizeof (bfd_pef_section))); bfd_alloc (abfd, header->section_count * sizeof (bfd_pef_section)));
if (mdata->sections == NULL) { return -1; }
for (i = 0; i < header->section_count; i++) { if (mdata->sections == NULL)
return -1;
for (i = 0; i < header->section_count; i++)
{
bfd_pef_section *cur = &mdata->sections[i]; bfd_pef_section *cur = &mdata->sections[i];
cur->header_offset = 40 + (i * 28); cur->header_offset = 40 + (i * 28);
if (bfd_pef_scan_section (abfd, cur) < 0) { if (bfd_pef_scan_section (abfd, cur) < 0)
return -1; return -1;
} }
} }
}
if (bfd_pef_scan_start_address (abfd) < 0) { if (bfd_pef_scan_start_address (abfd) < 0)
{
#if 0 #if 0
fprintf (stderr, "bfd_pef_scan: unable to scan start address: %s\n", fprintf (stderr, "bfd_pef_scan: unable to scan start address: %s\n",
bfd_errmsg (bfd_get_error ())); bfd_errmsg (bfd_get_error ()));
abfd->tdata.pef_data = NULL;
return -1; return -1;
#endif #endif
} }
@ -600,7 +638,8 @@ bfd_pef_read_header (abfd, header)
bfd_seek (abfd, 0, SEEK_SET); bfd_seek (abfd, 0, SEEK_SET);
if (bfd_bread ((PTR) buf, 40, abfd) != 40) { return -1; } if (bfd_bread ((PTR) buf, 40, abfd) != 40)
return -1;
header->tag1 = bfd_getb32 (buf); header->tag1 = bfd_getb32 (buf);
header->tag2 = bfd_getb32 (buf + 4); header->tag2 = bfd_getb32 (buf + 4);
@ -621,23 +660,35 @@ static const bfd_target *
bfd_pef_object_p (abfd) bfd_pef_object_p (abfd)
bfd *abfd; bfd *abfd;
{ {
struct bfd_preserve preserve;
bfd_pef_header header; bfd_pef_header header;
abfd->tdata.pef_data = NULL; preserve.marker = NULL;
if (bfd_pef_read_header (abfd, &header) != 0)
goto wrong;
if (bfd_pef_read_header (abfd, &header) != 0) { if (header.tag1 != BFD_PEF_TAG1 || header.tag2 != BFD_PEF_TAG2)
abfd->tdata.pef_data = NULL; goto wrong;
bfd_set_error (bfd_error_wrong_format);
return NULL;
}
if (bfd_pef_scan (abfd, &header) != 0) { preserve.marker = bfd_zalloc (abfd, sizeof (bfd_pef_data_struct));
abfd->tdata.pef_data = NULL; if (preserve.marker == NULL
bfd_set_error (bfd_error_wrong_format); || !bfd_preserve_save (abfd, &preserve))
return NULL; goto fail;
}
if (bfd_pef_scan (abfd, &header,
(bfd_pef_data_struct *) preserve.marker) != 0)
goto wrong;
bfd_preserve_finish (abfd, &preserve);
return abfd->xvec; return abfd->xvec;
wrong:
bfd_set_error (bfd_error_wrong_format);
fail:
if (preserve.marker != NULL)
bfd_preserve_restore (abfd, &preserve);
return NULL;
} }
static int bfd_pef_parse_traceback_tables (abfd, sec, buf, len, nsym, csym) static int bfd_pef_parse_traceback_tables (abfd, sec, buf, len, nsym, csym)
@ -660,30 +711,30 @@ static int bfd_pef_parse_traceback_tables (abfd, sec, buf, len, nsym, csym)
unsigned long count = 0; unsigned long count = 0;
int ret; int ret;
for (;;) { for (;;)
{
/* we're reading symbols two at a time */ /* we're reading symbols two at a time */
if (csym && ((csym[count] == NULL) || (csym[count + 1] == NULL))) { if (csym && ((csym[count] == NULL) || (csym[count + 1] == NULL)))
break; break;
}
pos += 3; pos += 3;
pos -= (pos % 4); pos -= (pos % 4);
while ((pos + 4) <= len) { while ((pos + 4) <= len)
if (bfd_getb32 (buf + pos) == 0) { {
if (bfd_getb32 (buf + pos) == 0)
break; break;
}
pos += 4; pos += 4;
} }
if ((pos + 4) > len) { if ((pos + 4) > len)
break; break;
}
ret = bfd_pef_parse_traceback_table (abfd, sec, buf, len, pos + 4, &function, 0); ret = bfd_pef_parse_traceback_table (abfd, sec, buf, len, pos + 4,
if (ret < 0) { &function, 0);
if (ret < 0)
{
/* skip over 0x0L to advance to next possible traceback table */ /* skip over 0x0L to advance to next possible traceback table */
pos += 4; pos += 4;
continue; continue;
@ -698,7 +749,8 @@ static int bfd_pef_parse_traceback_tables (abfd, sec, buf, len, nsym, csym)
{ {
tbnamelen = strlen (tbprefix) + strlen (function.name); tbnamelen = strlen (tbprefix) + strlen (function.name);
name = bfd_alloc (abfd, tbnamelen + 1); name = bfd_alloc (abfd, tbnamelen + 1);
if (name == NULL) { if (name == NULL)
{
bfd_release (abfd, (PTR) function.name); bfd_release (abfd, (PTR) function.name);
function.name = NULL; function.name = NULL;
break; break;
@ -731,21 +783,27 @@ static int bfd_pef_parse_function_stub (abfd, buf, len, offset)
{ {
BFD_ASSERT (len == 24); BFD_ASSERT (len == 24);
if ((bfd_getb32 (buf) & 0xffff0000) != 0x81820000) { return -1; } if ((bfd_getb32 (buf) & 0xffff0000) != 0x81820000)
if (bfd_getb32 (buf + 4) != 0x90410014) { return -1; } return -1;
if (bfd_getb32 (buf + 8) != 0x800c0000) { return -1; } if (bfd_getb32 (buf + 4) != 0x90410014)
if (bfd_getb32 (buf + 12) != 0x804c0004) { return -1; } return -1;
if (bfd_getb32 (buf + 16) != 0x7c0903a6) { return -1; } if (bfd_getb32 (buf + 8) != 0x800c0000)
if (bfd_getb32 (buf + 20) != 0x4e800420) { return -1; } return -1;
if (bfd_getb32 (buf + 12) != 0x804c0004)
return -1;
if (bfd_getb32 (buf + 16) != 0x7c0903a6)
return -1;
if (bfd_getb32 (buf + 20) != 0x4e800420)
return -1;
if (offset != NULL) { if (offset != NULL)
*offset = (bfd_getb32 (buf) & 0x0000ffff) / 4; *offset = (bfd_getb32 (buf) & 0x0000ffff) / 4;
}
return 0; return 0;
} }
static int bfd_pef_parse_function_stubs (abfd, codesec, codebuf, codelen, loaderbuf, loaderlen, nsym, csym) static int bfd_pef_parse_function_stubs (abfd, codesec, codebuf, codelen,
loaderbuf, loaderlen, nsym, csym)
bfd *abfd; bfd *abfd;
asection *codesec; asection *codesec;
unsigned char *codebuf; unsigned char *codebuf;
@ -767,82 +825,107 @@ static int bfd_pef_parse_function_stubs (abfd, codesec, codebuf, codelen, loader
unsigned long i; unsigned long i;
int ret; int ret;
if (loaderlen < 56) { goto error; } if (loaderlen < 56)
goto error;
ret = bfd_pef_parse_loader_header (abfd, loaderbuf, 56, &header); ret = bfd_pef_parse_loader_header (abfd, loaderbuf, 56, &header);
if (ret < 0) { goto error; } if (ret < 0)
goto error;
libraries = (bfd_pef_imported_library *) bfd_malloc libraries = (bfd_pef_imported_library *) bfd_malloc
(header.imported_library_count * sizeof (bfd_pef_imported_library)); (header.imported_library_count * sizeof (bfd_pef_imported_library));
imports = (bfd_pef_imported_symbol *) bfd_malloc imports = (bfd_pef_imported_symbol *) bfd_malloc
(header.total_imported_symbol_count * sizeof (bfd_pef_imported_symbol)); (header.total_imported_symbol_count * sizeof (bfd_pef_imported_symbol));
if (loaderlen < (56 + (header.imported_library_count * 24))) { goto error; } if (loaderlen < (56 + (header.imported_library_count * 24)))
for (i = 0; i < header.imported_library_count; i++) { goto error;
for (i = 0; i < header.imported_library_count; i++)
{
ret = bfd_pef_parse_imported_library ret = bfd_pef_parse_imported_library
(abfd, loaderbuf + 56 + (i * 24), 24, &libraries[i]); (abfd, loaderbuf + 56 + (i * 24), 24, &libraries[i]);
if (ret < 0) { goto error; } if (ret < 0)
goto error;
} }
if (loaderlen < (56 + (header.imported_library_count * 24) + (header.total_imported_symbol_count * 4))) if (loaderlen < (56 + (header.imported_library_count * 24)
{ goto error; } + (header.total_imported_symbol_count * 4)))
for (i = 0; i < header.total_imported_symbol_count; i++) { goto error;
ret = bfd_pef_parse_imported_symbol for (i = 0; i < header.total_imported_symbol_count; i++)
(abfd, loaderbuf + 56 + (header.imported_library_count * 24) + (i * 4), 4, &imports[i]); {
if (ret < 0) { goto error; } ret = (bfd_pef_parse_imported_symbol
(abfd,
loaderbuf + 56 + (header.imported_library_count * 24) + (i * 4),
4, &imports[i]));
if (ret < 0)
goto error;
} }
codepos = 0; codepos = 0;
for (;;) { for (;;)
{
asymbol sym; asymbol sym;
const char *symname; const char *symname;
char *name; char *name;
unsigned long index; unsigned long index;
int ret; int ret;
if (csym && (csym[count] == NULL)) { break; } if (csym && (csym[count] == NULL))
break;
codepos += 3; codepos += 3;
codepos -= (codepos % 4); codepos -= (codepos % 4);
while ((codepos + 4) <= codelen) { while ((codepos + 4) <= codelen)
if ((bfd_getb32 (codebuf + codepos) & 0xffff0000) == 0x81820000) { {
if ((bfd_getb32 (codebuf + codepos) & 0xffff0000) == 0x81820000)
break; break;
}
codepos += 4; codepos += 4;
} }
if ((codepos + 4) > codelen) { if ((codepos + 4) > codelen)
break; break;
}
ret = bfd_pef_parse_function_stub (abfd, codebuf + codepos, 24, &index); ret = bfd_pef_parse_function_stub (abfd, codebuf + codepos, 24, &index);
if (ret < 0) { codepos += 24; continue; } if (ret < 0)
{
codepos += 24;
continue;
}
if (index >= header.total_imported_symbol_count) { codepos += 24; continue; } if (index >= header.total_imported_symbol_count)
{
codepos += 24;
continue;
}
{ {
size_t max, namelen; size_t max, namelen;
const char *s; const char *s;
if (loaderlen < (header.loader_strings_offset + imports[index].name)) { goto error; } if (loaderlen < (header.loader_strings_offset + imports[index].name))
goto error;
max = loaderlen - (header.loader_strings_offset + imports[index].name); max = loaderlen - (header.loader_strings_offset + imports[index].name);
symname = loaderbuf + header.loader_strings_offset + imports[index].name; symname = loaderbuf + header.loader_strings_offset + imports[index].name;
namelen = 0; namelen = 0;
for (s = symname; s < (symname + max); s++) { for (s = symname; s < (symname + max); s++)
if (*s == '\0') { break; } {
if (! isprint (*s)) { goto error; } if (*s == '\0')
break;
if (! isprint (*s))
goto error;
namelen++; namelen++;
} }
if (*s != '\0') { goto error; } if (*s != '\0')
goto error;
name = bfd_alloc (abfd, strlen (sprefix) + namelen + 1); name = bfd_alloc (abfd, strlen (sprefix) + namelen + 1);
if (name == NULL) { break; } if (name == NULL)
break;
snprintf (name, strlen (sprefix) + namelen + 1, "%s%s", sprefix, symname); snprintf (name, strlen (sprefix) + namelen + 1, "%s%s",
sprefix, symname);
sym.name = name; sym.name = name;
} }
@ -854,23 +937,27 @@ static int bfd_pef_parse_function_stubs (abfd, codesec, codebuf, codelen, loader
codepos += 24; codepos += 24;
if (csym != NULL) { if (csym != NULL)
*(csym[count]) = sym; *(csym[count]) = sym;
}
count++; count++;
} }
goto end; goto end;
end: end:
if (libraries != NULL) { free (libraries); } if (libraries != NULL)
if (imports != NULL) { free (imports); } free (libraries);
if (imports != NULL)
free (imports);
*nsym = count; *nsym = count;
return 0; return 0;
error: error:
if (libraries != NULL) { free (libraries); } if (libraries != NULL)
if (imports != NULL) { free (imports); } free (libraries);
if (imports != NULL)
free (imports);
*nsym = count; *nsym = count;
return -1; return -1;
} }
@ -894,8 +981,10 @@ static long bfd_pef_parse_symbols (abfd, csym)
{ {
codelen = bfd_section_size (abfd, codesec); codelen = bfd_section_size (abfd, codesec);
codebuf = (unsigned char *) bfd_malloc (codelen); codebuf = (unsigned char *) bfd_malloc (codelen);
if (bfd_seek (abfd, codesec->filepos, SEEK_SET) < 0) { goto end; } if (bfd_seek (abfd, codesec->filepos, SEEK_SET) < 0)
if (bfd_bread ((PTR) codebuf, codelen, abfd) != codelen) { goto end; } goto end;
if (bfd_bread ((PTR) codebuf, codelen, abfd) != codelen)
goto end;
} }
loadersec = bfd_get_section_by_name (abfd, "loader"); loadersec = bfd_get_section_by_name (abfd, "loader");
@ -903,15 +992,18 @@ static long bfd_pef_parse_symbols (abfd, csym)
{ {
loaderlen = bfd_section_size (abfd, loadersec); loaderlen = bfd_section_size (abfd, loadersec);
loaderbuf = (unsigned char *) bfd_malloc (loaderlen); loaderbuf = (unsigned char *) bfd_malloc (loaderlen);
if (bfd_seek (abfd, loadersec->filepos, SEEK_SET) < 0) { goto end; } if (bfd_seek (abfd, loadersec->filepos, SEEK_SET) < 0)
if (bfd_bread ((PTR) loaderbuf, loaderlen, abfd) != loaderlen) { goto end; } goto end;
if (bfd_bread ((PTR) loaderbuf, loaderlen, abfd) != loaderlen)
goto end;
} }
count = 0; count = 0;
if (codesec != NULL) if (codesec != NULL)
{ {
unsigned long ncount = 0; unsigned long ncount = 0;
bfd_pef_parse_traceback_tables (abfd, codesec, codebuf, codelen, &ncount, csym); bfd_pef_parse_traceback_tables (abfd, codesec, codebuf, codelen,
&ncount, csym);
count += ncount; count += ncount;
} }
@ -924,9 +1016,8 @@ static long bfd_pef_parse_symbols (abfd, csym)
count += ncount; count += ncount;
} }
if (csym != NULL) { if (csym != NULL)
csym[count] = NULL; csym[count] = NULL;
}
end: end:
if (codebuf != NULL) if (codebuf != NULL)
@ -950,7 +1041,8 @@ bfd_pef_get_symtab_upper_bound (abfd)
bfd *abfd; bfd *abfd;
{ {
long nsyms = bfd_pef_count_symbols (abfd); long nsyms = bfd_pef_count_symbols (abfd);
if (nsyms < 0) { return nsyms; } if (nsyms < 0)
return nsyms;
return ((nsyms + 1) * sizeof (asymbol *)); return ((nsyms + 1) * sizeof (asymbol *));
} }
@ -964,20 +1056,21 @@ bfd_pef_get_symtab (abfd, alocation)
long ret; long ret;
long nsyms = bfd_pef_count_symbols (abfd); long nsyms = bfd_pef_count_symbols (abfd);
if (nsyms < 0) { return nsyms; } if (nsyms < 0)
return nsyms;
syms = bfd_alloc (abfd, nsyms * sizeof (asymbol)); syms = bfd_alloc (abfd, nsyms * sizeof (asymbol));
if (syms == NULL) { return -1; } if (syms == NULL)
return -1;
for (i = 0; i < nsyms; i++) { for (i = 0; i < nsyms; i++)
alocation[i] = &syms[i]; alocation[i] = &syms[i];
}
alocation[nsyms] = NULL; alocation[nsyms] = NULL;
ret = bfd_pef_parse_symbols (abfd, alocation); ret = bfd_pef_parse_symbols (abfd, alocation);
if (ret != nsyms) { if (ret != nsyms)
return 0; return 0;
}
return ret; return ret;
} }
@ -1077,7 +1170,8 @@ bfd_pef_xlib_read_header (abfd, header)
bfd_seek (abfd, 0, SEEK_SET); bfd_seek (abfd, 0, SEEK_SET);
if (bfd_bread ((PTR) buf, 76, abfd) != 76) { return -1; } if (bfd_bread ((PTR) buf, 76, abfd) != 76)
return -1;
header->tag1 = bfd_getb32 (buf); header->tag1 = bfd_getb32 (buf);
header->tag2 = bfd_getb32 (buf + 4); header->tag2 = bfd_getb32 (buf + 4);
@ -1110,18 +1204,15 @@ bfd_pef_xlib_scan (abfd, header)
{ {
bfd_pef_xlib_data_struct *mdata = NULL; bfd_pef_xlib_data_struct *mdata = NULL;
if ((header->tag1 != BFD_PEF_XLIB_TAG1)
|| ((header->tag2 != BFD_PEF_VLIB_TAG2) && (header->tag2 != BFD_PEF_BLIB_TAG2))) {
return -1;
}
mdata = ((bfd_pef_xlib_data_struct *) mdata = ((bfd_pef_xlib_data_struct *)
bfd_alloc (abfd, sizeof (bfd_pef_xlib_data_struct))); bfd_alloc (abfd, sizeof (bfd_pef_xlib_data_struct)));
if (mdata == NULL) { return -1; } if (mdata == NULL)
return -1;
mdata->header = *header; mdata->header = *header;
abfd->flags = abfd->xvec->object_flags | (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS)); abfd->flags = (abfd->xvec->object_flags
| (abfd->flags & (BFD_IN_MEMORY | BFD_IO_FUNCS)));
abfd->tdata.pef_xlib_data = mdata; abfd->tdata.pef_xlib_data = mdata;
@ -1132,22 +1223,37 @@ static const bfd_target *
bfd_pef_xlib_object_p (abfd) bfd_pef_xlib_object_p (abfd)
bfd *abfd; bfd *abfd;
{ {
struct bfd_preserve preserve;
bfd_pef_xlib_header header; bfd_pef_xlib_header header;
abfd->tdata.pef_xlib_data = NULL; if (bfd_pef_xlib_read_header (abfd, &header) != 0)
{
if (bfd_pef_xlib_read_header (abfd, &header) != 0) {
abfd->tdata.pef_xlib_data = NULL;
bfd_set_error (bfd_error_wrong_format); bfd_set_error (bfd_error_wrong_format);
return NULL; return NULL;
} }
if (bfd_pef_xlib_scan (abfd, &header) != 0) { if ((header.tag1 != BFD_PEF_XLIB_TAG1)
abfd->tdata.pef_xlib_data = NULL; || ((header.tag2 != BFD_PEF_VLIB_TAG2)
&& (header.tag2 != BFD_PEF_BLIB_TAG2)))
{
bfd_set_error (bfd_error_wrong_format); bfd_set_error (bfd_error_wrong_format);
return NULL; return NULL;
} }
if (! bfd_preserve_save (abfd, &preserve))
{
bfd_set_error (bfd_error_wrong_format);
return NULL;
}
if (bfd_pef_xlib_scan (abfd, &header) != 0)
{
bfd_preserve_restore (abfd, &preserve);
bfd_set_error (bfd_error_wrong_format);
return NULL;
}
bfd_preserve_finish (abfd, &preserve);
return abfd->xvec; return abfd->xvec;
} }
@ -1204,4 +1310,3 @@ const bfd_target pef_xlib_vec =
NULL NULL
}; };

View file

@ -183,4 +183,4 @@ int bfd_pef_parse_imported_library PARAMS ((bfd *, unsigned char *, size_t, bfd
int bfd_pef_parse_imported_symbol PARAMS ((bfd *, unsigned char *, size_t, bfd_pef_imported_symbol *)); int bfd_pef_parse_imported_symbol PARAMS ((bfd *, unsigned char *, size_t, bfd_pef_imported_symbol *));
int bfd_pef_scan_section PARAMS ((bfd *, bfd_pef_section *)); int bfd_pef_scan_section PARAMS ((bfd *, bfd_pef_section *));
int bfd_pef_scan_start_address PARAMS ((bfd *)); int bfd_pef_scan_start_address PARAMS ((bfd *));
int bfd_pef_scan PARAMS ((bfd *, bfd_pef_header *)); int bfd_pef_scan PARAMS ((bfd *, bfd_pef_header *, bfd_pef_data_struct *));

View file

@ -997,11 +997,8 @@ static const bfd_target * const _bfd_target_vector[] = {
&pc532machaout_vec, &pc532machaout_vec,
&pc532netbsd_vec, &pc532netbsd_vec,
&pdp11_aout_vec, &pdp11_aout_vec,
#if 0
/* bfd_pef_object_p and bfd_pef_xlib_object_p are broken. */
&pef_vec, &pef_vec,
&pef_xlib_vec, &pef_xlib_vec,
#endif
#if 0 #if 0
/* This has the same magic number as RS/6000. */ /* This has the same magic number as RS/6000. */
&pmac_xcoff_vec, &pmac_xcoff_vec,
@ -1031,10 +1028,7 @@ static const bfd_target * const _bfd_target_vector[] = {
&sparclynx_coff_vec, &sparclynx_coff_vec,
&sparcnetbsd_vec, &sparcnetbsd_vec,
&sunos_big_vec, &sunos_big_vec,
#if 0
/* bfd_sym_object_p is broken. */
&sym_vec, &sym_vec,
#endif
&tic30_aout_vec, &tic30_aout_vec,
&tic30_coff_vec, &tic30_coff_vec,
&tic54x_coff0_beh_vec, &tic54x_coff0_beh_vec,

View file

@ -116,7 +116,7 @@ bfd_sym_valid (abfd)
if (abfd == NULL || abfd->xvec == NULL) if (abfd == NULL || abfd->xvec == NULL)
return 0; return 0;
return (abfd->xvec == &sym_vec); return abfd->xvec == &sym_vec;
} }
unsigned char * unsigned char *
@ -135,7 +135,7 @@ bfd_sym_read_name_table (abfd, dshb)
bfd_seek (abfd, table_offset, SEEK_SET); bfd_seek (abfd, table_offset, SEEK_SET);
ret = bfd_bread (rstr, table_size, abfd); ret = bfd_bread (rstr, table_size, abfd);
if ((ret < 0) || ((unsigned long) ret != table_size)) if (ret < 0 || (unsigned long) ret != table_size)
{ {
bfd_release (abfd, rstr); bfd_release (abfd, rstr);
return NULL; return NULL;
@ -554,12 +554,14 @@ bfd_sym_fetch_resources_table_entry (abfd, entry, index)
bfd_sym_resources_table_entry *entry; bfd_sym_resources_table_entry *entry;
unsigned long index; unsigned long index;
{ {
void (*parser) (unsigned char *, size_t, bfd_sym_resources_table_entry *) = NULL; void (*parser) PARAMS ((unsigned char *, size_t,
bfd_sym_resources_table_entry *));
unsigned long offset; unsigned long offset;
unsigned long entry_size; unsigned long entry_size;
unsigned char buf[18]; unsigned char buf[18];
bfd_sym_data_struct *sdata = NULL; bfd_sym_data_struct *sdata = NULL;
parser = NULL;
BFD_ASSERT (bfd_sym_valid (abfd)); BFD_ASSERT (bfd_sym_valid (abfd));
sdata = abfd->tdata.sym_data; sdata = abfd->tdata.sym_data;
@ -605,12 +607,14 @@ bfd_sym_fetch_modules_table_entry (abfd, entry, index)
bfd_sym_modules_table_entry *entry; bfd_sym_modules_table_entry *entry;
unsigned long index; unsigned long index;
{ {
void (*parser) (unsigned char *, size_t, bfd_sym_modules_table_entry *) = NULL; void (*parser) PARAMS ((unsigned char *, size_t,
bfd_sym_modules_table_entry *));
unsigned long offset; unsigned long offset;
unsigned long entry_size; unsigned long entry_size;
unsigned char buf[46]; unsigned char buf[46];
bfd_sym_data_struct *sdata = NULL; bfd_sym_data_struct *sdata = NULL;
parser = NULL;
BFD_ASSERT (bfd_sym_valid (abfd)); BFD_ASSERT (bfd_sym_valid (abfd));
sdata = abfd->tdata.sym_data; sdata = abfd->tdata.sym_data;
@ -656,12 +660,14 @@ bfd_sym_fetch_file_references_table_entry (abfd, entry, index)
bfd_sym_file_references_table_entry *entry; bfd_sym_file_references_table_entry *entry;
unsigned long index; unsigned long index;
{ {
void (*parser) (unsigned char *, size_t, bfd_sym_file_references_table_entry *) = NULL; void (*parser) PARAMS ((unsigned char *, size_t,
bfd_sym_file_references_table_entry *));
unsigned long offset; unsigned long offset;
unsigned long entry_size = 0; unsigned long entry_size = 0;
unsigned char buf[8]; unsigned char buf[8];
bfd_sym_data_struct *sdata = NULL; bfd_sym_data_struct *sdata = NULL;
parser = NULL;
BFD_ASSERT (bfd_sym_valid (abfd)); BFD_ASSERT (bfd_sym_valid (abfd));
sdata = abfd->tdata.sym_data; sdata = abfd->tdata.sym_data;
@ -706,12 +712,14 @@ bfd_sym_fetch_contained_modules_table_entry (abfd, entry, index)
bfd_sym_contained_modules_table_entry *entry; bfd_sym_contained_modules_table_entry *entry;
unsigned long index; unsigned long index;
{ {
void (*parser) (unsigned char *, size_t, bfd_sym_contained_modules_table_entry *) = NULL; void (*parser) PARAMS ((unsigned char *, size_t,
bfd_sym_contained_modules_table_entry *));
unsigned long offset; unsigned long offset;
unsigned long entry_size = 0; unsigned long entry_size = 0;
unsigned char buf[6]; unsigned char buf[6];
bfd_sym_data_struct *sdata = NULL; bfd_sym_data_struct *sdata = NULL;
parser = NULL;
BFD_ASSERT (bfd_sym_valid (abfd)); BFD_ASSERT (bfd_sym_valid (abfd));
sdata = abfd->tdata.sym_data; sdata = abfd->tdata.sym_data;
@ -756,12 +764,14 @@ bfd_sym_fetch_contained_variables_table_entry (abfd, entry, index)
bfd_sym_contained_variables_table_entry *entry; bfd_sym_contained_variables_table_entry *entry;
unsigned long index; unsigned long index;
{ {
void (*parser) (unsigned char *, size_t, bfd_sym_contained_variables_table_entry *) = NULL; void (*parser) PARAMS ((unsigned char *, size_t,
bfd_sym_contained_variables_table_entry *));
unsigned long offset; unsigned long offset;
unsigned long entry_size = 0; unsigned long entry_size = 0;
unsigned char buf[26]; unsigned char buf[26];
bfd_sym_data_struct *sdata = NULL; bfd_sym_data_struct *sdata = NULL;
parser = NULL;
BFD_ASSERT (bfd_sym_valid (abfd)); BFD_ASSERT (bfd_sym_valid (abfd));
sdata = abfd->tdata.sym_data; sdata = abfd->tdata.sym_data;
@ -806,12 +816,14 @@ bfd_sym_fetch_contained_statements_table_entry (abfd, entry, index)
bfd_sym_contained_statements_table_entry *entry; bfd_sym_contained_statements_table_entry *entry;
unsigned long index; unsigned long index;
{ {
void (*parser) (unsigned char *, size_t, bfd_sym_contained_statements_table_entry *) = NULL; void (*parser) PARAMS ((unsigned char *, size_t,
bfd_sym_contained_statements_table_entry *));
unsigned long offset; unsigned long offset;
unsigned long entry_size = 0; unsigned long entry_size = 0;
unsigned char buf[8]; unsigned char buf[8];
bfd_sym_data_struct *sdata = NULL; bfd_sym_data_struct *sdata = NULL;
parser = NULL;
BFD_ASSERT (bfd_sym_valid (abfd)); BFD_ASSERT (bfd_sym_valid (abfd));
sdata = abfd->tdata.sym_data; sdata = abfd->tdata.sym_data;
@ -856,12 +868,14 @@ bfd_sym_fetch_contained_labels_table_entry (abfd, entry, index)
bfd_sym_contained_labels_table_entry *entry; bfd_sym_contained_labels_table_entry *entry;
unsigned long index; unsigned long index;
{ {
void (*parser) (unsigned char *, size_t, bfd_sym_contained_labels_table_entry *) = NULL; void (*parser) PARAMS ((unsigned char *, size_t,
bfd_sym_contained_labels_table_entry *));
unsigned long offset; unsigned long offset;
unsigned long entry_size = 0; unsigned long entry_size = 0;
unsigned char buf[12]; unsigned char buf[12];
bfd_sym_data_struct *sdata = NULL; bfd_sym_data_struct *sdata = NULL;
parser = NULL;
BFD_ASSERT (bfd_sym_valid (abfd)); BFD_ASSERT (bfd_sym_valid (abfd));
sdata = abfd->tdata.sym_data; sdata = abfd->tdata.sym_data;
@ -906,12 +920,14 @@ bfd_sym_fetch_contained_types_table_entry (abfd, entry, index)
bfd_sym_contained_types_table_entry *entry; bfd_sym_contained_types_table_entry *entry;
unsigned long index; unsigned long index;
{ {
void (*parser) (unsigned char *, size_t, bfd_sym_contained_types_table_entry *) = NULL; void (*parser) PARAMS ((unsigned char *, size_t,
bfd_sym_contained_types_table_entry *));
unsigned long offset; unsigned long offset;
unsigned long entry_size = 0; unsigned long entry_size = 0;
unsigned char buf[0]; unsigned char buf[0];
bfd_sym_data_struct *sdata = NULL; bfd_sym_data_struct *sdata = NULL;
parser = NULL;
BFD_ASSERT (bfd_sym_valid (abfd)); BFD_ASSERT (bfd_sym_valid (abfd));
sdata = abfd->tdata.sym_data; sdata = abfd->tdata.sym_data;
@ -956,12 +972,14 @@ bfd_sym_fetch_file_references_index_table_entry (abfd, entry, index)
bfd_sym_file_references_index_table_entry *entry; bfd_sym_file_references_index_table_entry *entry;
unsigned long index; unsigned long index;
{ {
void (*parser) (unsigned char *, size_t, bfd_sym_file_references_index_table_entry *) = NULL; void (*parser) PARAMS ((unsigned char *, size_t,
bfd_sym_file_references_index_table_entry *));
unsigned long offset; unsigned long offset;
unsigned long entry_size = 0; unsigned long entry_size = 0;
unsigned char buf[0]; unsigned char buf[0];
bfd_sym_data_struct *sdata = NULL; bfd_sym_data_struct *sdata = NULL;
parser = NULL;
BFD_ASSERT (bfd_sym_valid (abfd)); BFD_ASSERT (bfd_sym_valid (abfd));
sdata = abfd->tdata.sym_data; sdata = abfd->tdata.sym_data;
@ -1006,12 +1024,14 @@ bfd_sym_fetch_constant_pool_entry (abfd, entry, index)
bfd_sym_constant_pool_entry *entry; bfd_sym_constant_pool_entry *entry;
unsigned long index; unsigned long index;
{ {
void (*parser) (unsigned char *, size_t, bfd_sym_constant_pool_entry *) = NULL; void (*parser) PARAMS ((unsigned char *, size_t,
bfd_sym_constant_pool_entry *));
unsigned long offset; unsigned long offset;
unsigned long entry_size = 0; unsigned long entry_size = 0;
unsigned char buf[0]; unsigned char buf[0];
bfd_sym_data_struct *sdata = NULL; bfd_sym_data_struct *sdata = NULL;
parser = NULL;
BFD_ASSERT (bfd_sym_valid (abfd)); BFD_ASSERT (bfd_sym_valid (abfd));
sdata = abfd->tdata.sym_data; sdata = abfd->tdata.sym_data;
@ -1056,12 +1076,14 @@ bfd_sym_fetch_type_table_entry (abfd, entry, index)
bfd_sym_type_table_entry *entry; bfd_sym_type_table_entry *entry;
unsigned long index; unsigned long index;
{ {
void (*parser) (unsigned char *, size_t, bfd_sym_type_table_entry *) = NULL; void (*parser) PARAMS ((unsigned char *, size_t,
bfd_sym_type_table_entry *));
unsigned long offset; unsigned long offset;
unsigned long entry_size = 0; unsigned long entry_size = 0;
unsigned char buf[4]; unsigned char buf[4];
bfd_sym_data_struct *sdata = NULL; bfd_sym_data_struct *sdata = NULL;
parser = NULL;
BFD_ASSERT (bfd_sym_valid (abfd)); BFD_ASSERT (bfd_sym_valid (abfd));
sdata = abfd->tdata.sym_data; sdata = abfd->tdata.sym_data;
@ -1182,10 +1204,11 @@ bfd_sym_symbol_name (abfd, index)
return ""; return "";
index *= 2; index *= 2;
if ((index / sdata->header.dshb_page_size) > sdata->header.dshb_nte.dti_page_count) if ((index / sdata->header.dshb_page_size)
> sdata->header.dshb_nte.dti_page_count)
return "\009[INVALID]"; return "\009[INVALID]";
return ((const unsigned char *) sdata->name_table + index); return (const unsigned char *) sdata->name_table + index;
} }
const unsigned char * const unsigned char *
@ -1272,7 +1295,8 @@ bfd_sym_print_file_reference (abfd, f, entry)
bfd_sym_file_references_table_entry frtentry; bfd_sym_file_references_table_entry frtentry;
int ret; int ret;
ret = bfd_sym_fetch_file_references_table_entry (abfd, &frtentry, entry->fref_frte_index); ret = bfd_sym_fetch_file_references_table_entry (abfd, &frtentry,
entry->fref_frte_index);
fprintf (f, "FILE "); fprintf (f, "FILE ");
if ((ret < 0) || (frtentry.generic.type != BFD_SYM_FILE_NAME_INDEX)) if ((ret < 0) || (frtentry.generic.type != BFD_SYM_FILE_NAME_INDEX))
@ -1312,7 +1336,8 @@ bfd_sym_print_modules_table_entry (abfd, f, entry)
fprintf (f, "\n "); fprintf (f, "\n ");
bfd_sym_print_file_reference (abfd, f, &entry->mte_imp_fref); bfd_sym_print_file_reference (abfd, f, &entry->mte_imp_fref);
fprintf (f, " range %lu -- %lu", entry->mte_imp_fref.fref_offset, entry->mte_imp_end); fprintf (f, " range %lu -- %lu",
entry->mte_imp_fref.fref_offset, entry->mte_imp_end);
fprintf (f, "\n "); fprintf (f, "\n ");
@ -1924,7 +1949,7 @@ bfd_sym_display_name_table_entry (abfd, f, entry)
sdata = abfd->tdata.sym_data; sdata = abfd->tdata.sym_data;
index = (entry - sdata->name_table) / 2; index = (entry - sdata->name_table) / 2;
if ((sdata->version >= BFD_SYM_VERSION_3_4) && (entry[0] == 255) && (entry[1] == 0)) if (sdata->version >= BFD_SYM_VERSION_3_4 && entry[0] == 255 && entry[1] == 0)
{ {
unsigned short length = bfd_getb16 (entry + 2); unsigned short length = bfd_getb16 (entry + 2);
fprintf (f, "[%8lu] \"%.*s\"\n", index, length, entry + 4); fprintf (f, "[%8lu] \"%.*s\"\n", index, length, entry + 4);
@ -1932,7 +1957,7 @@ bfd_sym_display_name_table_entry (abfd, f, entry)
} }
else else
{ {
if (! ((entry[0] == 0) || ((entry[0] == 1) && (entry[1] == '\0')))) if (! (entry[0] == 0 || (entry[0] == 1 && entry[1] == '\0')))
fprintf (f, "[%8lu] \"%.*s\"\n", index, entry[0], entry + 1); fprintf (f, "[%8lu] \"%.*s\"\n", index, entry[0], entry + 1);
if (sdata->version >= BFD_SYM_VERSION_3_4) if (sdata->version >= BFD_SYM_VERSION_3_4)
@ -2293,55 +2318,30 @@ bfd_sym_display_type_information_table (abfd, f)
} }
} }
const bfd_target * int
bfd_sym_object_p (abfd) bfd_sym_scan (abfd, version, mdata)
bfd *abfd; bfd *abfd;
bfd_sym_version version;
bfd_sym_data_struct *mdata;
{ {
bfd_sym_data_struct *mdata = NULL;
asection *bfdsec; asection *bfdsec;
const char *name = "symbols"; const char *name = "symbols";
mdata = ((bfd_sym_data_struct *)
bfd_alloc (abfd, sizeof (bfd_sym_data_struct)));
if (mdata == NULL)
return NULL;
abfd->tdata.sym_data = mdata;
mdata->name_table = 0; mdata->name_table = 0;
mdata->sbfd = abfd; mdata->sbfd = abfd;
mdata->version = version;
bfd_seek (abfd, 0, SEEK_SET);
if (bfd_sym_read_version (abfd, &mdata->version) != 0)
{
abfd->tdata.sym_data = NULL;
bfd_set_error (bfd_error_wrong_format);
return NULL;
}
bfd_seek (abfd, 0, SEEK_SET); bfd_seek (abfd, 0, SEEK_SET);
if (bfd_sym_read_header (abfd, &mdata->header, mdata->version) != 0) if (bfd_sym_read_header (abfd, &mdata->header, mdata->version) != 0)
{ return -1;
abfd->tdata.sym_data = NULL;
bfd_set_error (bfd_error_wrong_format);
return NULL;
}
mdata->name_table = bfd_sym_read_name_table (abfd, &mdata->header); mdata->name_table = bfd_sym_read_name_table (abfd, &mdata->header);
if (mdata->name_table == NULL) if (mdata->name_table == NULL)
{ return -1;
abfd->tdata.sym_data = NULL;
bfd_set_error (bfd_error_wrong_format);
return NULL;
}
bfdsec = bfd_make_section_anyway (abfd, name); bfdsec = bfd_make_section_anyway (abfd, name);
if (bfdsec == NULL) if (bfdsec == NULL)
{ return -1;
abfd->tdata.sym_data = NULL;
bfd_set_error (bfd_error_wrong_format);
return NULL;
}
bfdsec->vma = 0; bfdsec->vma = 0;
bfdsec->lma = 0; bfdsec->lma = 0;
@ -2351,7 +2351,42 @@ bfd_sym_object_p (abfd)
bfdsec->flags = SEC_HAS_CONTENTS; bfdsec->flags = SEC_HAS_CONTENTS;
abfd->tdata.sym_data = mdata;
return 0;
}
const bfd_target *
bfd_sym_object_p (abfd)
bfd *abfd;
{
struct bfd_preserve preserve;
bfd_sym_version version = -1;
preserve.marker = NULL;
bfd_seek (abfd, 0, SEEK_SET);
if (bfd_sym_read_version (abfd, &version) != 0)
goto wrong;
preserve.marker = bfd_alloc (abfd, sizeof (bfd_sym_data_struct));
if (preserve.marker == NULL
|| ! bfd_preserve_save (abfd, &preserve))
goto fail;
if (bfd_sym_scan (abfd, version,
(bfd_sym_data_struct *) preserve.marker) != 0)
goto wrong;
bfd_preserve_finish (abfd, &preserve);
return abfd->xvec; return abfd->xvec;
wrong:
bfd_set_error (bfd_error_wrong_format);
fail:
if (preserve.marker != NULL)
bfd_preserve_restore (abfd, &preserve);
return NULL;
} }
asymbol * asymbol *

View file

@ -683,6 +683,8 @@ extern void bfd_sym_display_constant_pool
PARAMS ((bfd *, FILE *)); PARAMS ((bfd *, FILE *));
extern void bfd_sym_display_type_information_table extern void bfd_sym_display_type_information_table
PARAMS ((bfd *, FILE *)); PARAMS ((bfd *, FILE *));
extern int bfd_sym_scan
PARAMS ((bfd *, bfd_sym_version, bfd_sym_data_struct *));
extern const bfd_target * bfd_sym_object_p extern const bfd_target * bfd_sym_object_p
PARAMS ((bfd *)); PARAMS ((bfd *));
extern asymbol * bfd_sym_make_empty_symbol extern asymbol * bfd_sym_make_empty_symbol