aboutsummaryrefslogtreecommitdiff
path: root/bfd/pef.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2002-11-12 15:44:24 +0000
committerAlan Modra <amodra@gmail.com>2002-11-12 15:44:24 +0000
commite84d6fca26caaf6b02718efa0f1a4fb0d344348c (patch)
tree7dfaac5631eded3e7fcacfd1097415db98d4841a /bfd/pef.c
parentc4c41219636642438223c7b46a2c8e1467faba06 (diff)
downloadgdb-e84d6fca26caaf6b02718efa0f1a4fb0d344348c.zip
gdb-e84d6fca26caaf6b02718efa0f1a4fb0d344348c.tar.gz
gdb-e84d6fca26caaf6b02718efa0f1a4fb0d344348c.tar.bz2
* 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.
Diffstat (limited to 'bfd/pef.c')
-rw-r--r--bfd/pef.c863
1 files changed, 484 insertions, 379 deletions
diff --git a/bfd/pef.c b/bfd/pef.c
index bb0d6c5..8273045 100644
--- a/bfd/pef.c
+++ b/bfd/pef.c
@@ -15,7 +15,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
+ along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <ctype.h>
@@ -70,7 +70,7 @@
static void bfd_pef_print_symbol
PARAMS ((bfd *abfd, PTR afile, asymbol *symbol, bfd_print_symbol_type how));
static void bfd_pef_convert_architecture
-PARAMS ((unsigned long architecture,
+PARAMS ((unsigned long architecture,
enum bfd_architecture *type, unsigned long *subtype));
static boolean bfd_pef_mkobject PARAMS ((bfd *abfd));
static int bfd_pef_parse_traceback_table
@@ -78,7 +78,8 @@ PARAMS ((bfd *abfd, asection *section, unsigned char *buf,
size_t len, size_t pos, asymbol *sym, FILE *file));
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 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 const bfd_target *bfd_pef_object_p PARAMS ((bfd *));
static int bfd_pef_parse_traceback_tables
@@ -86,9 +87,10 @@ PARAMS ((bfd *abfd, asection *sec, unsigned char *buf,
size_t len, long *nsym, asymbol **csym));
static int bfd_pef_parse_function_stub
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,
- 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_count_symbols PARAMS ((bfd *abfd));
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 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 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;
{
FILE *file = (FILE *) afile;
- switch (how) {
- case bfd_print_symbol_name:
- fprintf (file, "%s", symbol->name);
- break;
- default:
- bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
- fprintf (file, " %-5s %s", symbol->section->name, symbol->name);
- if (strncmp (symbol->name, "__traceback_", strlen ("__traceback_")) == 0) {
- char *buf = alloca (symbol->udata.i);
- size_t offset = symbol->value + 4;
- size_t len = symbol->udata.i;
- int ret;
-
- bfd_get_section_contents (abfd, symbol->section, buf, offset, len);
- ret = bfd_pef_parse_traceback_table (abfd, symbol->section, buf, len, 0, NULL, file);
- if (ret < 0) {
- fprintf (file, " [ERROR]");
- }
+ switch (how)
+ {
+ case bfd_print_symbol_name:
+ fprintf (file, "%s", symbol->name);
+ break;
+ default:
+ bfd_print_symbol_vandf (abfd, (PTR) file, symbol);
+ fprintf (file, " %-5s %s", symbol->section->name, symbol->name);
+ if (strncmp (symbol->name, "__traceback_", strlen ("__traceback_")) == 0)
+ {
+ char *buf = alloca (symbol->udata.i);
+ size_t offset = symbol->value + 4;
+ size_t len = symbol->udata.i;
+ int ret;
+
+ bfd_get_section_contents (abfd, symbol->section, buf, offset, len);
+ ret = bfd_pef_parse_traceback_table (abfd, symbol->section, buf,
+ len, 0, NULL, file);
+ if (ret < 0)
+ fprintf (file, " [ERROR]");
+ }
}
- }
}
-static void bfd_pef_convert_architecture (architecture, type, subtype)
+static void
+bfd_pef_convert_architecture (architecture, type, subtype)
unsigned long architecture;
enum bfd_architecture *type;
unsigned long *subtype;
@@ -141,7 +147,7 @@ static void bfd_pef_convert_architecture (architecture, type, subtype)
const unsigned long ARCH_POWERPC = 0x70777063; /* 'pwpc' */
const unsigned long ARCH_M68K = 0x6d36386b; /* 'm68k' */
-
+
if (architecture == ARCH_POWERPC)
*type = bfd_arch_powerpc;
else if (architecture == ARCH_M68K)
@@ -169,8 +175,9 @@ bfd_pef_parse_traceback_table (abfd, section, buf, len, pos, sym, file)
size_t offset;
const char *s;
asymbol tmpsymbol;
-
- if (sym == NULL) { sym = &tmpsymbol; }
+
+ if (sym == NULL)
+ sym = &tmpsymbol;
sym->name = NULL;
sym->value = 0;
@@ -181,150 +188,150 @@ bfd_pef_parse_traceback_table (abfd, section, buf, len, pos, sym, file)
/* 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);
-
- /* calling code relies on returned symbols having a name and correct offset */
- if ((table.lang != TB_C) && (table.lang != TB_CPLUSPLUS)) {
+ /* calling code relies on returned symbols having a name and
+ correct offset */
+
+ if ((table.lang != TB_C) && (table.lang != TB_CPLUSPLUS))
return -1;
- }
- if (! (table.flags2 & TB_NAME_PRESENT)) {
+
+ if (! (table.flags2 & TB_NAME_PRESENT))
return -1;
- }
- if (! table.flags1 & TB_HAS_TBOFF) {
+
+ if (! table.flags1 & TB_HAS_TBOFF)
return -1;
- }
offset = 8;
- if ((table.flags5 & TB_FLOATPARAMS) || (table.fixedparams)) {
- offset += 4;
- }
+ if ((table.flags5 & TB_FLOATPARAMS) || (table.fixedparams))
+ 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; }
- off.tb_offset = bfd_getb32 (buf + pos + offset);
- offset += 4;
+ if ((pos + offset + 4) > len)
+ return -1;
+ off.tb_offset = bfd_getb32 (buf + pos + offset);
+ offset += 4;
- /* need to subtract 4 because the offset includes the 0x0L
- preceding the table */
+ /* need to subtract 4 because the offset includes the 0x0L
+ preceding the table */
- if (file != NULL) {
- fprintf (file, " [offset = 0x%lx]", off.tb_offset);
- }
+ if (file != NULL)
+ fprintf (file, " [offset = 0x%lx]", off.tb_offset);
- if ((file == NULL) && ((off.tb_offset + 4) > (pos + offset))) {
- return -1;
+ if ((file == NULL) && ((off.tb_offset + 4) > (pos + offset)))
+ 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;
- }
- 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;
+ anchors.ctl_info = bfd_getb32 (buf + pos + offset);
+ offset += 4;
- if ((pos + offset + 4) > len) { return -1; }
- anchors.ctl_info = bfd_getb32 (buf + pos + offset);
- offset += 4;
+ if (anchors.ctl_info > 1024)
+ return -1;
- if (anchors.ctl_info > 1024) {
- return -1;
+ offset += anchors.ctl_info * 4;
}
- offset += anchors.ctl_info * 4;
- }
+ if (table.flags2 & TB_NAME_PRESENT)
+ {
+ struct traceback_table_routine name;
+ char *namebuf;
- if (table.flags2 & TB_NAME_PRESENT) {
+ if ((pos + offset + 2) > len)
+ return -1;
+ name.name_len = bfd_getb16 (buf + pos + offset);
+ offset += 2;
- struct traceback_table_routine name;
- char *namebuf;
+ if (name.name_len > 4096)
+ return -1;
- if ((pos + offset + 2) > len) { return -1; }
- name.name_len = bfd_getb16 (buf + pos + offset);
- offset += 2;
+ if ((pos + offset + name.name_len) > len)
+ return -1;
- if (name.name_len > 4096) { return -1; }
+ namebuf = (char *) bfd_alloc (abfd, name.name_len + 1);
+ if (namebuf == NULL)
+ return -1;
- if ((pos + offset + name.name_len) > len) { return -1; }
+ memcpy (namebuf, buf + pos + offset, name.name_len);
+ namebuf[name.name_len] = '\0';
- namebuf = (char *) bfd_alloc (abfd, name.name_len + 1);
- if (namebuf == NULL) { return -1; }
+ /* strip leading period inserted by compiler */
+ if (namebuf[0] == '.')
+ memmove (namebuf, namebuf + 1, name.name_len + 1);
- memcpy (namebuf, buf + pos + offset, name.name_len);
- namebuf[name.name_len] = '\0';
-
- /* strip leading period inserted by compiler */
- if (namebuf[0] == '.') {
- memmove (namebuf, namebuf + 1, name.name_len + 1);
- }
+ sym->name = namebuf;
- sym->name = namebuf;
+ for (s = sym->name; (*s != '\0'); s++)
+ if (! isprint (*s))
+ return -1;
- for (s = sym->name; (*s != '\0'); s++) {
- if (! isprint (*s)) {
- return -1;
- }
+ offset += name.name_len;
}
- offset += name.name_len;
- }
-
- if (table.flags2 & TB_USES_ALLOCA) {
+ if (table.flags2 & TB_USES_ALLOCA)
offset += 4;
- }
- if (table.flags4 & TB_HAS_VEC_INFO) {
+ if (table.flags4 & TB_HAS_VEC_INFO)
offset += 4;
- }
- if (file != NULL) {
+ if (file != NULL)
fprintf (file, " [length = 0x%lx]", (long) offset);
- }
+
return offset;
}
static const char *bfd_pef_section_name (section)
bfd_pef_section *section;
{
- switch (section->section_kind) {
- case BFD_PEF_SECTION_CODE: return "code";
- case BFD_PEF_SECTION_UNPACKED_DATA: return "unpacked-data";
- case BFD_PEF_SECTION_PACKED_DATA: return "packed-data";
- case BFD_PEF_SECTION_CONSTANT: return "constant";
- case BFD_PEF_SECTION_LOADER: return "loader";
- case BFD_PEF_SECTION_DEBUG: return "debug";
- case BFD_PEF_SECTION_EXEC_DATA: return "exec-data";
- case BFD_PEF_SECTION_EXCEPTION: return "exception";
- case BFD_PEF_SECTION_TRACEBACK: return "traceback";
- default: return "unknown";
- }
+ switch (section->section_kind)
+ {
+ case BFD_PEF_SECTION_CODE: return "code";
+ case BFD_PEF_SECTION_UNPACKED_DATA: return "unpacked-data";
+ case BFD_PEF_SECTION_PACKED_DATA: return "packed-data";
+ case BFD_PEF_SECTION_CONSTANT: return "constant";
+ case BFD_PEF_SECTION_LOADER: return "loader";
+ case BFD_PEF_SECTION_DEBUG: return "debug";
+ case BFD_PEF_SECTION_EXEC_DATA: return "exec-data";
+ case BFD_PEF_SECTION_EXCEPTION: return "exception";
+ case BFD_PEF_SECTION_TRACEBACK: return "traceback";
+ default: return "unknown";
+ }
}
static unsigned long bfd_pef_section_flags (section)
bfd_pef_section *section;
{
- switch (section->section_kind) {
- case BFD_PEF_SECTION_CODE:
- return SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
- case BFD_PEF_SECTION_UNPACKED_DATA:
- case BFD_PEF_SECTION_PACKED_DATA:
- case BFD_PEF_SECTION_CONSTANT:
- case BFD_PEF_SECTION_LOADER:
- case BFD_PEF_SECTION_DEBUG:
- case BFD_PEF_SECTION_EXEC_DATA:
- case BFD_PEF_SECTION_EXCEPTION:
- case BFD_PEF_SECTION_TRACEBACK:
- default:
- return SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
- }
+ switch (section->section_kind)
+ {
+ case BFD_PEF_SECTION_CODE:
+ return SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC | SEC_CODE;
+ case BFD_PEF_SECTION_UNPACKED_DATA:
+ case BFD_PEF_SECTION_PACKED_DATA:
+ case BFD_PEF_SECTION_CONSTANT:
+ case BFD_PEF_SECTION_LOADER:
+ case BFD_PEF_SECTION_DEBUG:
+ case BFD_PEF_SECTION_EXEC_DATA:
+ case BFD_PEF_SECTION_EXCEPTION:
+ case BFD_PEF_SECTION_TRACEBACK:
+ default:
+ return SEC_HAS_CONTENTS | SEC_LOAD | SEC_ALLOC;
+ }
}
static asection *
@@ -336,8 +343,9 @@ bfd_pef_make_bfd_section (abfd, section)
const char *name = bfd_pef_section_name (section);
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->lma = section->default_address + section->container_offset;
bfdsec->_raw_size = section->container_length;
@@ -417,9 +425,10 @@ int bfd_pef_scan_section (abfd, section)
bfd_pef_section *section;
{
unsigned char buf[28];
-
+
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->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->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;
}
@@ -450,14 +460,19 @@ bfd_pef_print_loader_header (abfd, header, file)
fprintf (file, "init_offset: %lu\n", header->init_offset);
fprintf (file, "term_section: %ld\n", header->term_section);
fprintf (file, "term_offset: %lu\n", header->term_offset);
- fprintf (file, "imported_library_count: %lu\n", header->imported_library_count);
- fprintf (file, "total_imported_symbol_count: %lu\n", header->total_imported_symbol_count);
+ fprintf (file, "imported_library_count: %lu\n",
+ 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_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_table_power: %lu\n", header->export_hash_table_power);
- fprintf (file, "exported_symbol_count: %lu\n", header->exported_symbol_count);
+ fprintf (file, "export_hash_table_power: %lu\n",
+ header->export_hash_table_power);
+ fprintf (file, "exported_symbol_count: %lu\n",
+ header->exported_symbol_count);
}
int
@@ -472,18 +487,33 @@ bfd_pef_print_loader_section (abfd, file)
int ret;
loadersec = bfd_get_section_by_name (abfd, "loader");
- if (loadersec == NULL) { return -1; }
-
+ if (loadersec == NULL)
+ return -1;
+
loaderlen = bfd_section_size (abfd, loadersec);
loaderbuf = (unsigned char *) bfd_malloc (loaderlen);
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)
- { 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);
- if (ret < 0) { free (loaderbuf); return -1; }
+ if (ret < 0)
+ {
+ free (loaderbuf);
+ return -1;
+ }
bfd_pef_print_loader_header (abfd, &header, file);
return 0;
@@ -502,89 +532,97 @@ bfd_pef_scan_start_address (abfd)
int ret;
loadersec = bfd_get_section_by_name (abfd, "loader");
- if (loadersec == NULL) { goto end; }
-
+ if (loadersec == NULL)
+ goto end;
+
loaderlen = bfd_section_size (abfd, loadersec);
loaderbuf = (unsigned char *) bfd_malloc (loaderlen);
- if (bfd_seek (abfd, loadersec->filepos, SEEK_SET) < 0) { goto error; }
- if (bfd_bread ((PTR) loaderbuf, loaderlen, abfd) != loaderlen) { goto error; }
+ if (bfd_seek (abfd, loadersec->filepos, SEEK_SET) < 0)
+ 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);
- if (ret < 0) { goto error; }
+ if (ret < 0)
+ goto error;
+
+ if (header.main_section < 0)
+ goto end;
+
+ for (section = abfd->sections; section != NULL; section = section->next)
+ if ((section->index + 1) == header.main_section)
+ break;
- if (header.main_section < 0) { goto end; }
+ if (section == NULL)
+ goto error;
- for (section = abfd->sections; section != NULL; section = section->next) {
- if ((section->index + 1) == header.main_section) { break; }
- }
-
- if (section == NULL) { goto error; }
-
abfd->start_address = section->vma + header.main_offset;
end:
- if (loaderbuf != NULL) { free (loaderbuf); }
+ if (loaderbuf != NULL)
+ free (loaderbuf);
return 0;
error:
- if (loaderbuf != NULL) { free (loaderbuf); }
+ if (loaderbuf != NULL)
+ free (loaderbuf);
return -1;
}
int
-bfd_pef_scan (abfd, header)
+bfd_pef_scan (abfd, header, mdata)
bfd *abfd;
bfd_pef_header *header;
+ bfd_pef_data_struct *mdata;
{
unsigned int i;
- bfd_pef_data_struct *mdata = NULL;
enum bfd_architecture cputype;
unsigned long cpusubtype;
- if ((header->tag1 != BFD_PEF_TAG1) || (header->tag2 != BFD_PEF_TAG2)) {
- return -1;
- }
+ mdata->header = *header;
- 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);
- if (cputype == bfd_arch_unknown) {
- fprintf (stderr, "bfd_pef_scan: unknown architecture 0x%lx\n", header->architecture);
- return -1;
- }
+ if (cputype == bfd_arch_unknown)
+ {
+ fprintf (stderr, "bfd_pef_scan: unknown architecture 0x%lx\n",
+ header->architecture);
+ return -1;
+ }
bfd_set_arch_mach (abfd, cputype, cpusubtype);
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) {
-
- mdata->sections =
- ((bfd_pef_section *)
- bfd_alloc (abfd, header->section_count * sizeof (bfd_pef_section)));
- if (mdata->sections == NULL) { return -1; }
+ if (header->section_count != 0)
+ {
+ mdata->sections =
+ ((bfd_pef_section *)
+ bfd_alloc (abfd, header->section_count * sizeof (bfd_pef_section)));
- for (i = 0; i < header->section_count; i++) {
- bfd_pef_section *cur = &mdata->sections[i];
- cur->header_offset = 40 + (i * 28);
- if (bfd_pef_scan_section (abfd, cur) < 0) {
+ if (mdata->sections == NULL)
return -1;
- }
+
+ for (i = 0; i < header->section_count; i++)
+ {
+ bfd_pef_section *cur = &mdata->sections[i];
+ cur->header_offset = 40 + (i * 28);
+ if (bfd_pef_scan_section (abfd, cur) < 0)
+ return -1;
+ }
}
- }
- if (bfd_pef_scan_start_address (abfd) < 0) {
+ if (bfd_pef_scan_start_address (abfd) < 0)
+ {
#if 0
- fprintf (stderr, "bfd_pef_scan: unable to scan start address: %s\n",
- bfd_errmsg (bfd_get_error ()));
- abfd->tdata.pef_data = NULL;
- return -1;
+ fprintf (stderr, "bfd_pef_scan: unable to scan start address: %s\n",
+ bfd_errmsg (bfd_get_error ()));
+ return -1;
#endif
- }
+ }
abfd->tdata.pef_data = mdata;
@@ -600,7 +638,8 @@ bfd_pef_read_header (abfd, header)
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->tag2 = bfd_getb32 (buf + 4);
@@ -621,23 +660,35 @@ static const bfd_target *
bfd_pef_object_p (abfd)
bfd *abfd;
{
+ struct bfd_preserve preserve;
bfd_pef_header header;
-
- abfd->tdata.pef_data = NULL;
- if (bfd_pef_read_header (abfd, &header) != 0) {
- abfd->tdata.pef_data = NULL;
- bfd_set_error (bfd_error_wrong_format);
- return NULL;
- }
+ preserve.marker = NULL;
+ if (bfd_pef_read_header (abfd, &header) != 0)
+ goto wrong;
- if (bfd_pef_scan (abfd, &header) != 0) {
- abfd->tdata.pef_data = NULL;
- bfd_set_error (bfd_error_wrong_format);
- return NULL;
- }
+ if (header.tag1 != BFD_PEF_TAG1 || header.tag2 != BFD_PEF_TAG2)
+ goto wrong;
+
+ preserve.marker = bfd_zalloc (abfd, sizeof (bfd_pef_data_struct));
+ if (preserve.marker == NULL
+ || !bfd_preserve_save (abfd, &preserve))
+ 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;
+
+ 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)
@@ -660,64 +711,65 @@ static int bfd_pef_parse_traceback_tables (abfd, sec, buf, len, nsym, csym)
unsigned long count = 0;
int ret;
- for (;;) {
-
- /* we're reading symbols two at a time */
+ for (;;)
+ {
+ /* we're reading symbols two at a time */
- if (csym && ((csym[count] == NULL) || (csym[count + 1] == NULL))) {
- break;
- }
+ if (csym && ((csym[count] == NULL) || (csym[count + 1] == NULL)))
+ break;
- pos += 3;
- pos -= (pos % 4);
+ pos += 3;
+ pos -= (pos % 4);
- while ((pos + 4) <= len) {
- if (bfd_getb32 (buf + pos) == 0) {
- break;
- }
- pos += 4;
- }
+ while ((pos + 4) <= len)
+ {
+ if (bfd_getb32 (buf + pos) == 0)
+ break;
+ pos += 4;
+ }
- if ((pos + 4) > len) {
- break;
- }
-
- ret = bfd_pef_parse_traceback_table (abfd, sec, buf, len, pos + 4, &function, 0);
- if (ret < 0) {
- /* skip over 0x0L to advance to next possible traceback table */
- pos += 4;
- continue;
- }
-
- BFD_ASSERT (function.name != NULL);
+ if ((pos + 4) > len)
+ break;
- /* Don't bother to compute the name if we are just
- counting symbols */
+ ret = bfd_pef_parse_traceback_table (abfd, sec, buf, len, pos + 4,
+ &function, 0);
+ if (ret < 0)
+ {
+ /* skip over 0x0L to advance to next possible traceback table */
+ pos += 4;
+ continue;
+ }
- if (csym)
- {
- tbnamelen = strlen (tbprefix) + strlen (function.name);
- name = bfd_alloc (abfd, tbnamelen + 1);
- if (name == NULL) {
- bfd_release (abfd, (PTR) function.name);
- function.name = NULL;
- break;
+ BFD_ASSERT (function.name != NULL);
+
+ /* Don't bother to compute the name if we are just
+ counting symbols */
+
+ if (csym)
+ {
+ tbnamelen = strlen (tbprefix) + strlen (function.name);
+ name = bfd_alloc (abfd, tbnamelen + 1);
+ if (name == NULL)
+ {
+ bfd_release (abfd, (PTR) function.name);
+ function.name = NULL;
+ break;
+ }
+ snprintf (name, tbnamelen + 1, "%s%s", tbprefix, function.name);
+ traceback.name = name;
+ traceback.value = pos;
+ traceback.the_bfd = abfd;
+ traceback.section = sec;
+ traceback.flags = 0;
+ traceback.udata.i = ret;
+
+ *(csym[count]) = function;
+ *(csym[count + 1]) = traceback;
}
- snprintf (name, tbnamelen + 1, "%s%s", tbprefix, function.name);
- traceback.name = name;
- traceback.value = pos;
- traceback.the_bfd = abfd;
- traceback.section = sec;
- traceback.flags = 0;
- traceback.udata.i = ret;
-
- *(csym[count]) = function;
- *(csym[count + 1]) = traceback;
- }
- pos += ret;
- count += 2;
- }
+ pos += ret;
+ count += 2;
+ }
*nsym = count;
return 0;
@@ -731,21 +783,27 @@ static int bfd_pef_parse_function_stub (abfd, buf, len, offset)
{
BFD_ASSERT (len == 24);
- if ((bfd_getb32 (buf) & 0xffff0000) != 0x81820000) { return -1; }
- if (bfd_getb32 (buf + 4) != 0x90410014) { return -1; }
- if (bfd_getb32 (buf + 8) != 0x800c0000) { 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 ((bfd_getb32 (buf) & 0xffff0000) != 0x81820000)
+ return -1;
+ if (bfd_getb32 (buf + 4) != 0x90410014)
+ return -1;
+ if (bfd_getb32 (buf + 8) != 0x800c0000)
+ 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)
*offset = (bfd_getb32 (buf) & 0x0000ffff) / 4;
- }
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;
asection *codesec;
unsigned char *codebuf;
@@ -767,113 +825,142 @@ static int bfd_pef_parse_function_stubs (abfd, codesec, codebuf, codelen, loader
unsigned long i;
int ret;
- if (loaderlen < 56) { goto error; }
+ if (loaderlen < 56)
+ goto error;
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
(header.imported_library_count * sizeof (bfd_pef_imported_library));
imports = (bfd_pef_imported_symbol *) bfd_malloc
(header.total_imported_symbol_count * sizeof (bfd_pef_imported_symbol));
-
- if (loaderlen < (56 + (header.imported_library_count * 24))) { goto error; }
- for (i = 0; i < header.imported_library_count; i++) {
- ret = bfd_pef_parse_imported_library
- (abfd, loaderbuf + 56 + (i * 24), 24, &libraries[i]);
- if (ret < 0) { goto error; }
- }
-
- if (loaderlen < (56 + (header.imported_library_count * 24) + (header.total_imported_symbol_count * 4)))
- { goto error; }
- for (i = 0; i < header.total_imported_symbol_count; i++) {
- ret = bfd_pef_parse_imported_symbol
- (abfd, loaderbuf + 56 + (header.imported_library_count * 24) + (i * 4), 4, &imports[i]);
- if (ret < 0) { goto error; }
- }
-
+
+ if (loaderlen < (56 + (header.imported_library_count * 24)))
+ goto error;
+ for (i = 0; i < header.imported_library_count; i++)
+ {
+ ret = bfd_pef_parse_imported_library
+ (abfd, loaderbuf + 56 + (i * 24), 24, &libraries[i]);
+ if (ret < 0)
+ goto error;
+ }
+
+ if (loaderlen < (56 + (header.imported_library_count * 24)
+ + (header.total_imported_symbol_count * 4)))
+ goto error;
+ for (i = 0; i < header.total_imported_symbol_count; i++)
+ {
+ 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;
- for (;;) {
+ for (;;)
+ {
+ asymbol sym;
+ const char *symname;
+ char *name;
+ unsigned long index;
+ int ret;
- asymbol sym;
- const char *symname;
- char *name;
- unsigned long index;
- int ret;
+ if (csym && (csym[count] == NULL))
+ break;
- if (csym && (csym[count] == NULL)) { break; }
+ codepos += 3;
+ codepos -= (codepos % 4);
- codepos += 3;
- codepos -= (codepos % 4);
+ while ((codepos + 4) <= codelen)
+ {
+ if ((bfd_getb32 (codebuf + codepos) & 0xffff0000) == 0x81820000)
+ break;
+ codepos += 4;
+ }
- while ((codepos + 4) <= codelen) {
- if ((bfd_getb32 (codebuf + codepos) & 0xffff0000) == 0x81820000) {
+ if ((codepos + 4) > codelen)
break;
- }
- codepos += 4;
- }
- if ((codepos + 4) > codelen) {
- break;
- }
+ ret = bfd_pef_parse_function_stub (abfd, codebuf + codepos, 24, &index);
+ if (ret < 0)
+ {
+ codepos += 24;
+ continue;
+ }
- ret = bfd_pef_parse_function_stub (abfd, codebuf + codepos, 24, &index);
- 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;
- const char *s;
-
- if (loaderlen < (header.loader_strings_offset + imports[index].name)) { goto error; }
-
- max = loaderlen - (header.loader_strings_offset + imports[index].name);
- symname = loaderbuf + header.loader_strings_offset + imports[index].name;
- namelen = 0;
- for (s = symname; s < (symname + max); s++) {
- if (*s == '\0') { break; }
- if (! isprint (*s)) { goto error; }
- namelen++;
- }
- if (*s != '\0') { goto error; }
+ {
+ size_t max, namelen;
+ const char *s;
+
+ if (loaderlen < (header.loader_strings_offset + imports[index].name))
+ goto error;
+
+ max = loaderlen - (header.loader_strings_offset + imports[index].name);
+ symname = loaderbuf + header.loader_strings_offset + imports[index].name;
+ namelen = 0;
+ for (s = symname; s < (symname + max); s++)
+ {
+ if (*s == '\0')
+ break;
+ if (! isprint (*s))
+ goto error;
+ namelen++;
+ }
+ if (*s != '\0')
+ goto error;
+
+ name = bfd_alloc (abfd, strlen (sprefix) + namelen + 1);
+ if (name == NULL)
+ break;
- name = bfd_alloc (abfd, strlen (sprefix) + namelen + 1);
- if (name == NULL) { break; }
+ snprintf (name, strlen (sprefix) + namelen + 1, "%s%s",
+ sprefix, symname);
+ sym.name = name;
+ }
- snprintf (name, strlen (sprefix) + namelen + 1, "%s%s", sprefix, symname);
- sym.name = name;
- }
+ sym.value = codepos;
+ sym.the_bfd = abfd;
+ sym.section = codesec;
+ sym.flags = 0;
+ sym.udata.i = 0;
- sym.value = codepos;
- sym.the_bfd = abfd;
- sym.section = codesec;
- sym.flags = 0;
- sym.udata.i = 0;
+ codepos += 24;
- codepos += 24;
+ if (csym != NULL)
+ *(csym[count]) = sym;
- if (csym != NULL) {
- *(csym[count]) = sym;
+ count++;
}
- count++;
- }
goto end;
end:
- if (libraries != NULL) { free (libraries); }
- if (imports != NULL) { free (imports); }
+ if (libraries != NULL)
+ free (libraries);
+ if (imports != NULL)
+ free (imports);
*nsym = count;
return 0;
error:
- if (libraries != NULL) { free (libraries); }
- if (imports != NULL) { free (imports); }
+ if (libraries != NULL)
+ free (libraries);
+ if (imports != NULL)
+ free (imports);
*nsym = count;
return -1;
-}
+}
static long bfd_pef_parse_symbols (abfd, csym)
bfd *abfd;
@@ -894,8 +981,10 @@ static long bfd_pef_parse_symbols (abfd, csym)
{
codelen = bfd_section_size (abfd, codesec);
codebuf = (unsigned char *) bfd_malloc (codelen);
- if (bfd_seek (abfd, codesec->filepos, SEEK_SET) < 0) { goto end; }
- if (bfd_bread ((PTR) codebuf, codelen, abfd) != codelen) { goto end; }
+ if (bfd_seek (abfd, codesec->filepos, SEEK_SET) < 0)
+ goto end;
+ if (bfd_bread ((PTR) codebuf, codelen, abfd) != codelen)
+ goto end;
}
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);
loaderbuf = (unsigned char *) bfd_malloc (loaderlen);
- if (bfd_seek (abfd, loadersec->filepos, SEEK_SET) < 0) { goto end; }
- if (bfd_bread ((PTR) loaderbuf, loaderlen, abfd) != loaderlen) { goto end; }
+ if (bfd_seek (abfd, loadersec->filepos, SEEK_SET) < 0)
+ goto end;
+ if (bfd_bread ((PTR) loaderbuf, loaderlen, abfd) != loaderlen)
+ goto end;
}
-
+
count = 0;
if (codesec != NULL)
{
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;
}
@@ -923,18 +1015,17 @@ static long bfd_pef_parse_symbols (abfd, csym)
(csym != NULL) ? (csym + count) : NULL);
count += ncount;
}
-
- if (csym != NULL) {
+
+ if (csym != NULL)
csym[count] = NULL;
- }
-
+
end:
- if (codebuf != NULL)
+ if (codebuf != NULL)
free (codebuf);
- if (loaderbuf != NULL)
- free (loaderbuf);
-
+ if (loaderbuf != NULL)
+ free (loaderbuf);
+
return count;
}
@@ -950,7 +1041,8 @@ bfd_pef_get_symtab_upper_bound (abfd)
bfd *abfd;
{
long nsyms = bfd_pef_count_symbols (abfd);
- if (nsyms < 0) { return nsyms; }
+ if (nsyms < 0)
+ return nsyms;
return ((nsyms + 1) * sizeof (asymbol *));
}
@@ -964,20 +1056,21 @@ bfd_pef_get_symtab (abfd, alocation)
long ret;
long nsyms = bfd_pef_count_symbols (abfd);
- if (nsyms < 0) { return nsyms; }
+ if (nsyms < 0)
+ return nsyms;
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[nsyms] = NULL;
ret = bfd_pef_parse_symbols (abfd, alocation);
- if (ret != nsyms) {
+ if (ret != nsyms)
return 0;
- }
return ret;
}
@@ -1056,7 +1149,7 @@ const bfd_target pef_vec =
BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
NULL,
-
+
NULL
};
@@ -1077,7 +1170,8 @@ bfd_pef_xlib_read_header (abfd, header)
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->tag2 = bfd_getb32 (buf + 4);
@@ -1110,18 +1204,15 @@ bfd_pef_xlib_scan (abfd, header)
{
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))) {
+ mdata = ((bfd_pef_xlib_data_struct *)
+ bfd_alloc (abfd, sizeof (bfd_pef_xlib_data_struct)));
+ if (mdata == NULL)
return -1;
- }
- mdata = ((bfd_pef_xlib_data_struct *)
- bfd_alloc (abfd, sizeof (bfd_pef_xlib_data_struct)));
- if (mdata == NULL) { return -1; }
-
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;
@@ -1132,22 +1223,37 @@ static const bfd_target *
bfd_pef_xlib_object_p (abfd)
bfd *abfd;
{
+ struct bfd_preserve preserve;
bfd_pef_xlib_header header;
-
- abfd->tdata.pef_xlib_data = NULL;
- if (bfd_pef_xlib_read_header (abfd, &header) != 0) {
- abfd->tdata.pef_xlib_data = NULL;
- bfd_set_error (bfd_error_wrong_format);
- return NULL;
- }
+ if (bfd_pef_xlib_read_header (abfd, &header) != 0)
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ return NULL;
+ }
- if (bfd_pef_xlib_scan (abfd, &header) != 0) {
- abfd->tdata.pef_xlib_data = NULL;
- bfd_set_error (bfd_error_wrong_format);
- return NULL;
- }
+ if ((header.tag1 != BFD_PEF_XLIB_TAG1)
+ || ((header.tag2 != BFD_PEF_VLIB_TAG2)
+ && (header.tag2 != BFD_PEF_BLIB_TAG2)))
+ {
+ bfd_set_error (bfd_error_wrong_format);
+ 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;
}
@@ -1201,7 +1307,6 @@ const bfd_target pef_xlib_vec =
BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
NULL,
-
+
NULL
};
-