* bfd.c (struct bfd_preserve): New.
[deliverable/binutils-gdb.git] / bfd / pef.c
index bb0d6c5c96f185df1ebccc2812dccab74ba96829..8273045ae6f041b13067cd8519300bacaec2865f 100644 (file)
--- 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
 };
-
This page took 0.05849 seconds and 4 git commands to generate.