This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

multiple bfd targets, non-default object


bfd, built with --enable-targets=all, has trouble when trying to read
non-default targets.  I was getting segfaults in _bfd_vms_get_record
due to vms_initialize not allocating and initializing a new tdata
structure if one already exists.  The trouble was that the coff object
I was reading matched i386-coff (and other targets), so abfd->tdata
had been allocated and of course contained rubbish when interpreted as
a vms_private_data_struct.  Similar problems happen with other targets,
and some rude object_p functions trash an existing tdata structure.
Hopefully this cleans things up a bit.

	* aoutx.h (some_aout_object_p): Clean up tdata properly on error.
	* archive.c (bfd_generic_archive_p): Likewise.
	* coff-rs6000.c (_bfd_xcoff_archive_p): Likewise.
	(_bfd_xcoff_archive_p): Use bfd_scan_vma in place of strtol.
	* coff64-rs6000.c (xcoff64_slurp_armap): Likewise.
	(xcoff64_archive_p): Likewise.
	(xcoff64_openr_next_archived_file): Likewise.
	(xcoff64_archive_p): Clean up tdata properly on error.
	* coffgen.c (coff_real_object_p): Likewise.
	(coff_object_p): Release filehdr and opthdr.
	* ecoff.c (_bfd_ecoff_archive_p): Clean up tdata properly on error.
	* ieee.c (ieee_archive_p): Likewise.
	* ihex.c (ihex_object_p): Likewise.
	(ihex_mkobject): Always allocate tdata.
	* peicode.h (pe_ILF_object_p): Release bfd_alloc'd buffer on error.
	* srec.c (srec_mkobject): Always allocate tdata.
	(srec_object_p): Clean up tdata properly on error.
	(symbolsrec_object_p): Likewise.
	* versados.c (versados_object_p): Likewise.
	* vms-misc.c (_bfd_vms_get_record): Use bfd_malloc instead of malloc,
	and bfd_realloc instead of realloc.
	(add_new_contents): Use bfd_alloc instead of bfd_malloc for sections.
	* vms.c (vms_initialize): Always allocate tdata.  Use bfd_alloc in
	place of bfd_malloc, simplifying error freeing.  Free hash table too.
	(vms_object_p): Clean up tdata on error.
	(vms_mkobject): Don't complain on stderr if vms_initialize fails.
	(vms_close_and_cleanup): Adjust for bfd_alloc use.

Applying mainline.  Seems too late for the branch.

Index: bfd/aoutx.h
===================================================================
RCS file: /cvs/src/src/bfd/aoutx.h,v
retrieving revision 1.30
diff -u -p -r1.30 aoutx.h
--- bfd/aoutx.h	25 Jun 2002 06:21:47 -0000	1.30
+++ bfd/aoutx.h	30 Jul 2002 05:00:56 -0000
@@ -533,7 +533,7 @@ NAME(aout,some_aout_object_p) (abfd, exe
   obj_aout_sym_hashes (abfd) = NULL;
 
   if (! NAME(aout,make_sections) (abfd))
-    return NULL;
+    goto error_ret;
 
   obj_datasec (abfd)->_raw_size = execp->a_data;
   obj_bsssec (abfd)->_raw_size = execp->a_bss;
@@ -655,13 +655,13 @@ NAME(aout,some_aout_object_p) (abfd, exe
       obj_textsec (abfd)->next = obj_datasec (abfd);
       obj_datasec (abfd)->next = obj_bsssec (abfd);
 #endif
+      return result;
     }
-  else
-    {
-      free (rawptr);
-      abfd->tdata.aout_data = oldrawptr;
-    }
-  return result;
+
+ error_ret:
+  bfd_release (abfd, rawptr);
+  abfd->tdata.aout_data = oldrawptr;
+  return NULL;
 }
 
 /*
Index: bfd/archive.c
===================================================================
RCS file: /cvs/src/src/bfd/archive.c,v
retrieving revision 1.23
diff -u -p -r1.23 archive.c
--- bfd/archive.c	25 Jun 2002 06:21:47 -0000	1.23
+++ bfd/archive.c	30 Jul 2002 05:00:58 -0000
@@ -603,8 +603,6 @@ bfd_generic_archive_p (abfd)
   char armag[SARMAG + 1];
   bfd_size_type amt;
 
-  tdata_hold = abfd->tdata.aout_ar_data;
-
   if (bfd_bread ((PTR) armag, (bfd_size_type) SARMAG, abfd) != SARMAG)
     {
       if (bfd_get_error () != bfd_error_system_call)
@@ -621,13 +619,15 @@ bfd_generic_archive_p (abfd)
     return 0;
 #endif
 
-  /* We are setting bfd_ardata(abfd) here, but since bfd_ardata
-     involves a cast, we can't do it as the left operand of assignment.  */
-  amt = sizeof (struct artdata);
-  abfd->tdata.aout_ar_data = (struct artdata *) bfd_zalloc (abfd, amt);
+  tdata_hold = bfd_ardata (abfd);
 
+  amt = sizeof (struct artdata);
+  bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
   if (bfd_ardata (abfd) == NULL)
-    return NULL;
+    {
+      bfd_ardata (abfd) = tdata_hold;
+      return NULL;
+    }
 
   bfd_ardata (abfd)->first_file_filepos = SARMAG;
   bfd_ardata (abfd)->cache = NULL;
@@ -636,21 +636,13 @@ bfd_generic_archive_p (abfd)
   bfd_ardata (abfd)->extended_names = NULL;
   bfd_ardata (abfd)->tdata = NULL;
 
-  if (!BFD_SEND (abfd, _bfd_slurp_armap, (abfd)))
+  if (!BFD_SEND (abfd, _bfd_slurp_armap, (abfd))
+      || !BFD_SEND (abfd, _bfd_slurp_extended_name_table, (abfd)))
     {
-      bfd_release (abfd, bfd_ardata (abfd));
-      abfd->tdata.aout_ar_data = tdata_hold;
       if (bfd_get_error () != bfd_error_system_call)
 	bfd_set_error (bfd_error_wrong_format);
-      return NULL;
-    }
-
-  if (!BFD_SEND (abfd, _bfd_slurp_extended_name_table, (abfd)))
-    {
       bfd_release (abfd, bfd_ardata (abfd));
-      abfd->tdata.aout_ar_data = tdata_hold;
-      if (bfd_get_error () != bfd_error_system_call)
-	bfd_set_error (bfd_error_wrong_format);
+      bfd_ardata (abfd) = tdata_hold;
       return NULL;
     }
 
@@ -686,9 +678,9 @@ bfd_generic_archive_p (abfd)
 		 release bfd_ardata.  FIXME.  */
 	      (void) bfd_close (first);
 	      bfd_release (abfd, bfd_ardata (abfd));
-	      abfd->tdata.aout_ar_data = tdata_hold;
 #endif
 	      bfd_set_error (bfd_error_wrong_object_format);
+	      bfd_ardata (abfd) = tdata_hold;
 	      return NULL;
 	    }
 	  /* And we ought to close `first' here too.  */
Index: bfd/coff-rs6000.c
===================================================================
RCS file: /cvs/src/src/bfd/coff-rs6000.c,v
retrieving revision 1.45
diff -u -p -r1.45 coff-rs6000.c
--- bfd/coff-rs6000.c	25 Jun 2002 07:40:49 -0000	1.45
+++ bfd/coff-rs6000.c	30 Jul 2002 05:01:01 -0000
@@ -1243,10 +1243,11 @@ const bfd_target *
 _bfd_xcoff_archive_p (abfd)
      bfd *abfd;
 {
+  struct artdata *tdata_hold;
   char magic[SXCOFFARMAG];
-  bfd_size_type amt;
+  bfd_size_type amt = SXCOFFARMAG;
 
-  if (bfd_bread ((PTR) magic, (bfd_size_type) SXCOFFARMAG, abfd) != SXCOFFARMAG)
+  if (bfd_bread ((PTR) magic, amt, abfd) != amt)
     {
       if (bfd_get_error () != bfd_error_system_call)
 	bfd_set_error (bfd_error_wrong_format);
@@ -1260,13 +1261,12 @@ _bfd_xcoff_archive_p (abfd)
       return NULL;
     }
 
-  /* We are setting bfd_ardata(abfd) here, but since bfd_ardata
-     involves a cast, we can't do it as the left operand of
-     assignment.  */
+  tdata_hold = bfd_ardata (abfd);
+
   amt = sizeof (struct artdata);
-  abfd->tdata.aout_ar_data = (struct artdata *) bfd_zalloc (abfd, amt);
+  bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
   if (bfd_ardata (abfd) == (struct artdata *) NULL)
-    return NULL;
+    goto error_ret_restore;
 
   bfd_ardata (abfd)->cache = NULL;
   bfd_ardata (abfd)->archive_head = NULL;
@@ -1283,13 +1283,12 @@ _bfd_xcoff_archive_p (abfd)
       memcpy (hdr.magic, magic, SXCOFFARMAG);
 
       /* Now read the rest of the file header.  */
-      if (bfd_bread ((PTR) &hdr.memoff,
-		    (bfd_size_type) SIZEOF_AR_FILE_HDR - SXCOFFARMAG, abfd)
-	  != SIZEOF_AR_FILE_HDR - SXCOFFARMAG)
+      amt = SIZEOF_AR_FILE_HDR - SXCOFFARMAG;
+      if (bfd_bread ((PTR) &hdr.memoff, amt, abfd) != amt)
 	{
 	  if (bfd_get_error () != bfd_error_system_call)
 	    bfd_set_error (bfd_error_wrong_format);
-	  return NULL;
+	  goto error_ret;
 	}
 
       bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff,
@@ -1298,7 +1297,7 @@ _bfd_xcoff_archive_p (abfd)
       amt = SIZEOF_AR_FILE_HDR;
       bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
       if (bfd_ardata (abfd)->tdata == NULL)
-	return NULL;
+	goto error_ret;
 
       memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR);
     }
@@ -1311,33 +1310,32 @@ _bfd_xcoff_archive_p (abfd)
       memcpy (hdr.magic, magic, SXCOFFARMAG);
 
       /* Now read the rest of the file header.  */
-      if (bfd_bread ((PTR) &hdr.memoff,
-		    (bfd_size_type) SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG, abfd)
-	  != SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG)
+      amt = SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG;
+      if (bfd_bread ((PTR) &hdr.memoff, amt, abfd) != amt)
 	{
 	  if (bfd_get_error () != bfd_error_system_call)
 	    bfd_set_error (bfd_error_wrong_format);
-	  return NULL;
+	  goto error_ret;
 	}
 
-      /* XXX This actually has to be a call to strtoll (at least on 32-bit
-	 machines) since the field width is 20 and there numbers with more
-	 than 32 bits can be represented.  */
-      bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff,
-						      (char **) NULL, 10);
+      bfd_ardata (abfd)->first_file_filepos = bfd_scan_vma (hdr.firstmemoff,
+							    (const char **) 0,
+							    10);
 
       amt = SIZEOF_AR_FILE_HDR_BIG;
       bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
       if (bfd_ardata (abfd)->tdata == NULL)
-	return NULL;
+	goto error_ret;
 
       memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR_BIG);
     }
 
   if (! _bfd_xcoff_slurp_armap (abfd))
     {
+    error_ret:
       bfd_release (abfd, bfd_ardata (abfd));
-      abfd->tdata.aout_ar_data = (struct artdata *) NULL;
+    error_ret_restore:
+      bfd_ardata (abfd) = tdata_hold;
       return NULL;
     }
 
Index: bfd/coff64-rs6000.c
===================================================================
RCS file: /cvs/src/src/bfd/coff64-rs6000.c,v
retrieving revision 1.33
diff -u -p -r1.33 coff64-rs6000.c
--- bfd/coff64-rs6000.c	25 Jun 2002 06:21:47 -0000	1.33
+++ bfd/coff64-rs6000.c	30 Jul 2002 05:01:04 -0000
@@ -1840,7 +1840,8 @@ xcoff64_slurp_armap (abfd)
       return true;
     }
 
-  off = strtol (xcoff_ardata_big (abfd)->symoff64, (char **) NULL, 10);
+  off = bfd_scan_vma (xcoff_ardata_big (abfd)->symoff64,
+		      (const char **) NULL, 10);
   if (off == 0)
     {
       bfd_has_map (abfd) = false;
@@ -1861,10 +1862,7 @@ xcoff64_slurp_armap (abfd)
   if (bfd_seek (abfd, pos, SEEK_CUR) != 0)
     return false;
 
-  /* XXX This actually has to be a call to strtoll (at least on 32-bit
-     machines) since the field width is 20 and there numbers with more
-     than 32 bits can be represented.  */
-  sz = strtol (hdr.size, (char **) NULL, 10);
+  sz = bfd_scan_vma (hdr.size, (const char **) NULL, 10);
 
   /* Read in the entire symbol table.  */
   contents = (bfd_byte *) bfd_alloc (abfd, sz);
@@ -1920,6 +1918,7 @@ static const bfd_target *
 xcoff64_archive_p (abfd)
      bfd *abfd;
 {
+  struct artdata *tdata_hold;
   char magic[SXCOFFARMAG];
   /* This is the new format.  */
   struct xcoff_ar_file_hdr_big hdr;
@@ -1938,50 +1937,46 @@ xcoff64_archive_p (abfd)
       return NULL;
     }
 
-  /* We are setting bfd_ardata(abfd) here, but since bfd_ardata
-     involves a cast, we can't do it as the left operand of
-     assignment.  */
-  amt = sizeof (struct artdata);
-  abfd->tdata.aout_ar_data = (struct artdata *) bfd_zalloc (abfd, amt);
-
-  if (bfd_ardata (abfd) == (struct artdata *) NULL)
-    return NULL;
-
-  bfd_ardata (abfd)->cache = NULL;
-  bfd_ardata (abfd)->archive_head = NULL;
-  bfd_ardata (abfd)->symdefs = NULL;
-  bfd_ardata (abfd)->extended_names = NULL;
-
   /* Copy over the magic string.  */
   memcpy (hdr.magic, magic, SXCOFFARMAG);
 
   /* Now read the rest of the file header.  */
-  if (bfd_bread ((PTR) &hdr.memoff,
-		(bfd_size_type) (SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG),
-		abfd) != SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG)
+  amt = SIZEOF_AR_FILE_HDR_BIG - SXCOFFARMAG;
+  if (bfd_bread ((PTR) &hdr.memoff, amt, abfd) != amt)
     {
       if (bfd_get_error () != bfd_error_system_call)
 	bfd_set_error (bfd_error_wrong_format);
       return NULL;
     }
 
-  /* XXX This actually has to be a call to strtoll (at least on 32-bit
-     machines) since the field width is 20 and there numbers with more
-     than 32 bits can be represented.  */
-  bfd_ardata (abfd)->first_file_filepos = strtol (hdr.firstmemoff,
-						  (char **) NULL, 10);
+  tdata_hold = bfd_ardata (abfd);
+
+  amt = sizeof (struct artdata);
+  bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
+  if (bfd_ardata (abfd) == (struct artdata *) NULL)
+    goto error_ret_restore;
+
+  bfd_ardata (abfd)->cache = NULL;
+  bfd_ardata (abfd)->archive_head = NULL;
+  bfd_ardata (abfd)->symdefs = NULL;
+  bfd_ardata (abfd)->extended_names = NULL;
+  bfd_ardata (abfd)->first_file_filepos = bfd_scan_vma (hdr.firstmemoff,
+							(const char **) NULL,
+							10);
 
   amt = SIZEOF_AR_FILE_HDR_BIG;
   bfd_ardata (abfd)->tdata = bfd_zalloc (abfd, amt);
   if (bfd_ardata (abfd)->tdata == NULL)
-    return NULL;
+    goto error_ret;
 
   memcpy (bfd_ardata (abfd)->tdata, &hdr, SIZEOF_AR_FILE_HDR_BIG);
 
   if (! xcoff64_slurp_armap (abfd))
     {
+    error_ret:
       bfd_release (abfd, bfd_ardata (abfd));
-      abfd->tdata.aout_ar_data = (struct artdata *) NULL;
+    error_ret_restore:
+      bfd_ardata (abfd) = tdata_hold;
       return NULL;
     }
 
@@ -2011,20 +2006,15 @@ xcoff64_openr_next_archived_file (archiv
     }
   else
     {
-      /* XXX These actually have to be a calls to strtoll (at least
-	 on 32-bit machines) since the fields's width is 20 and
-	 there numbers with more than 32 bits can be represented.  */
-      filestart = strtol (arch_xhdr_big (last_file)->nextoff, (char **) NULL,
-			  10);
-    }
-  /* XXX These actually have to be calls to strtoll (at least on 32-bit
-     machines) since the fields's width is 20 and there numbers with more
-     than 32 bits can be represented.  */
+      filestart = bfd_scan_vma (arch_xhdr_big (last_file)->nextoff,
+				(const char **) NULL, 10);
+    }
+
   if (filestart == 0
-      || filestart == strtol (xcoff_ardata_big (archive)->memoff,
-			      (char **) NULL, 10)
-      || filestart == strtol (xcoff_ardata_big (archive)->symoff,
-			      (char **) NULL, 10))
+      || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->memoff,
+				    (const char **) NULL, 10)
+      || filestart == bfd_scan_vma (xcoff_ardata_big (archive)->symoff,
+				    (const char **) NULL, 10))
     {
       bfd_set_error (bfd_error_no_more_archived_files);
       return NULL;
Index: bfd/coffgen.c
===================================================================
RCS file: /cvs/src/src/bfd/coffgen.c,v
retrieving revision 1.33
diff -u -p -r1.33 coffgen.c
--- bfd/coffgen.c	25 Jun 2002 06:21:48 -0000	1.33
+++ bfd/coffgen.c	30 Jul 2002 05:01:07 -0000
@@ -178,6 +178,7 @@ coff_real_object_p (abfd, nscns, interna
   flagword oflags = abfd->flags;
   bfd_vma ostart = bfd_get_start_address (abfd);
   PTR tdata;
+  PTR tdata_save;
   bfd_size_type readsize;	/* length of file_info */
   unsigned int scnhsz;
   char *external_sections;
@@ -206,9 +207,10 @@ coff_real_object_p (abfd, nscns, interna
 
   /* Set up the tdata area.  ECOFF uses its own routine, and overrides
      abfd->flags.  */
+  tdata_save = abfd->tdata.any;
   tdata = bfd_coff_mkobject_hook (abfd, (PTR) internal_f, (PTR) internal_a);
   if (tdata == NULL)
-    return 0;
+    goto fail2;
 
   scnhsz = bfd_coff_scnhsz (abfd);
   readsize = (bfd_size_type) nscns * scnhsz;
@@ -245,6 +247,8 @@ coff_real_object_p (abfd, nscns, interna
 
  fail:
   bfd_release (abfd, tdata);
+ fail2:
+  abfd->tdata.any = tdata_save;
   abfd->flags = oflags;
   bfd_get_start_address (abfd) = ostart;
   return (const bfd_target *) NULL;
@@ -270,12 +274,13 @@ coff_object_p (abfd)
 
   filehdr = bfd_alloc (abfd, filhsz);
   if (filehdr == NULL)
-    return 0;
+    return NULL;
   if (bfd_bread (filehdr, filhsz, abfd) != filhsz)
     {
       if (bfd_get_error () != bfd_error_system_call)
 	bfd_set_error (bfd_error_wrong_format);
-      return 0;
+      bfd_release (abfd, filehdr);
+      return NULL;
     }
   bfd_coff_swap_filehdr_in (abfd, filehdr, &internal_f);
   bfd_release (abfd, filehdr);
@@ -292,7 +297,7 @@ coff_object_p (abfd)
       || internal_f.f_opthdr > aoutsz)
     {
       bfd_set_error (bfd_error_wrong_format);
-      return 0;
+      return NULL;
     }
   nscns = internal_f.f_nscns;
 
@@ -302,13 +307,15 @@ coff_object_p (abfd)
 
       opthdr = bfd_alloc (abfd, aoutsz);
       if (opthdr == NULL)
-	return 0;
+	return NULL;
       if (bfd_bread (opthdr, (bfd_size_type) internal_f.f_opthdr, abfd)
 	  != internal_f.f_opthdr)
 	{
-	  return 0;
+	  bfd_release (abfd, opthdr);
+	  return NULL;
 	}
       bfd_coff_swap_aouthdr_in (abfd, opthdr, (PTR) &internal_a);
+      bfd_release (abfd, opthdr);
     }
 
   return coff_real_object_p (abfd, nscns, &internal_f,
Index: bfd/ecoff.c
===================================================================
RCS file: /cvs/src/src/bfd/ecoff.c,v
retrieving revision 1.18
diff -u -p -r1.18 ecoff.c
--- bfd/ecoff.c	25 Jun 2002 08:47:31 -0000	1.18
+++ bfd/ecoff.c	30 Jul 2002 05:01:11 -0000
@@ -3289,8 +3289,6 @@ _bfd_ecoff_archive_p (abfd)
   char armag[SARMAG + 1];
   bfd_size_type amt;
 
-  tdata_hold = abfd->tdata.aout_ar_data;
-
   if (bfd_bread ((PTR) armag, (bfd_size_type) SARMAG, abfd) != SARMAG)
     {
       if (bfd_get_error () != bfd_error_system_call)
@@ -3304,15 +3302,13 @@ _bfd_ecoff_archive_p (abfd)
       return NULL;
     }
 
-  /* We are setting bfd_ardata(abfd) here, but since bfd_ardata
-     involves a cast, we can't do it as the left operand of
-     assignment.  */
-  amt = sizeof (struct artdata);
-  abfd->tdata.aout_ar_data = (struct artdata *) bfd_zalloc (abfd, amt);
+  tdata_hold = bfd_ardata (abfd);
 
+  amt = sizeof (struct artdata);
+  bfd_ardata (abfd) = (struct artdata *) bfd_zalloc (abfd, amt);
   if (bfd_ardata (abfd) == (struct artdata *) NULL)
     {
-      abfd->tdata.aout_ar_data = tdata_hold;
+      bfd_ardata (abfd) = tdata_hold;
       return (const bfd_target *) NULL;
     }
 
@@ -3327,7 +3323,7 @@ _bfd_ecoff_archive_p (abfd)
       || ! _bfd_ecoff_slurp_extended_name_table (abfd))
     {
       bfd_release (abfd, bfd_ardata (abfd));
-      abfd->tdata.aout_ar_data = tdata_hold;
+      bfd_ardata (abfd) = tdata_hold;
       return (const bfd_target *) NULL;
     }
 
@@ -3345,22 +3341,23 @@ _bfd_ecoff_archive_p (abfd)
       first = bfd_openr_next_archived_file (abfd, (bfd *) NULL);
       if (first != NULL)
 	{
-	  boolean fail;
-
 	  first->target_defaulted = false;
-	  fail = false;
 	  if (bfd_check_format (first, bfd_object)
 	      && first->xvec != abfd->xvec)
 	    {
+#if 0
+	      /* We ought to close `first' here, but we can't, because
+		 we have no way to remove it from the archive cache.
+		 It's close to impossible to figure out when we can
+		 release bfd_ardata.  FIXME.  */
 	      (void) bfd_close (first);
 	      bfd_release (abfd, bfd_ardata (abfd));
-	      abfd->tdata.aout_ar_data = tdata_hold;
-	      bfd_set_error (bfd_error_wrong_format);
+#endif
+	      bfd_set_error (bfd_error_wrong_object_format);
+	      bfd_ardata (abfd) = tdata_hold;
 	      return NULL;
 	    }
-
-	  /* We ought to close first here, but we can't, because we
-             have no way to remove it from the archive cache.  FIXME.  */
+	  /* And we ought to close `first' here too.  */
 	}
     }
 
Index: bfd/ieee.c
===================================================================
RCS file: /cvs/src/src/bfd/ieee.c,v
retrieving revision 1.27
diff -u -p -r1.27 ieee.c
--- bfd/ieee.c	25 Jun 2002 06:21:54 -0000	1.27
+++ bfd/ieee.c	30 Jul 2002 05:01:17 -0000
@@ -1414,7 +1414,7 @@ ieee_archive_p (abfd)
 
   abfd->tdata.ieee_ar_data = (ieee_ar_data_type *) bfd_alloc (abfd, amt);
   if (!abfd->tdata.ieee_ar_data)
-    goto error_return;
+    goto error_ret_restore;
   ieee = IEEE_AR_DATA (abfd);
 
   /* Ignore the return value here.  It doesn't matter if we don't read
@@ -1530,13 +1530,13 @@ ieee_archive_p (abfd)
   return abfd->xvec;
 
  got_wrong_format_error:
-  bfd_release (abfd, ieee);
-  abfd->tdata.ieee_ar_data = save;
   bfd_set_error (bfd_error_wrong_format);
-
  error_return:
   if (elts != NULL)
     free (elts);
+  bfd_release (abfd, ieee);
+ error_ret_restore:
+  abfd->tdata.ieee_ar_data = save;
 
   return NULL;
 }
@@ -1732,7 +1732,7 @@ ieee_object_p (abfd)
 got_wrong_format:
   bfd_set_error (bfd_error_wrong_format);
 fail:
-  (void) bfd_release (abfd, ieee);
+  bfd_release (abfd, ieee);
   abfd->tdata.ieee_data = save;
   return (const bfd_target *) NULL;
 }
Index: bfd/ihex.c
===================================================================
RCS file: /cvs/src/src/bfd/ihex.c,v
retrieving revision 1.16
diff -u -p -r1.16 ihex.c
--- bfd/ihex.c	5 Jun 2002 03:43:10 -0000	1.16
+++ bfd/ihex.c	30 Jul 2002 05:01:18 -0000
@@ -193,19 +193,16 @@ static boolean
 ihex_mkobject (abfd)
      bfd *abfd;
 {
-  if (abfd->tdata.ihex_data == NULL)
-    {
-      struct ihex_data_struct *tdata;
-      bfd_size_type amt = sizeof (struct ihex_data_struct);
-
-      tdata = (struct ihex_data_struct *) bfd_alloc (abfd, amt);
-      if (tdata == NULL)
-	return false;
-      abfd->tdata.ihex_data = tdata;
-      tdata->head = NULL;
-      tdata->tail = NULL;
-    }
+  struct ihex_data_struct *tdata;
+  bfd_size_type amt = sizeof (struct ihex_data_struct);
 
+  tdata = (struct ihex_data_struct *) bfd_alloc (abfd, amt);
+  if (tdata == NULL)
+    return false;
+
+  abfd->tdata.ihex_data = tdata;
+  tdata->head = NULL;
+  tdata->tail = NULL;
   return true;
 }
 
@@ -513,6 +510,7 @@ static const bfd_target *
 ihex_object_p (abfd)
      bfd *abfd;
 {
+  PTR tdata_save;
   bfd_byte b[9];
   unsigned int i;
   unsigned int type;
@@ -551,9 +549,14 @@ ihex_object_p (abfd)
     }
 
   /* OK, it looks like it really is an Intel Hex file.  */
-  if (! ihex_mkobject (abfd)
-      || ! ihex_scan (abfd))
-    return NULL;
+  tdata_save = abfd->tdata.any;
+  if (! ihex_mkobject (abfd) || ! ihex_scan (abfd))
+    {
+      if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL)
+	bfd_release (abfd, abfd->tdata.any);
+      abfd->tdata.any = tdata_save;
+      return NULL;
+    }
 
   return abfd->xvec;
 }
Index: bfd/peicode.h
===================================================================
RCS file: /cvs/src/src/bfd/peicode.h,v
retrieving revision 1.33
diff -u -p -r1.33 peicode.h
--- bfd/peicode.h	25 Jun 2002 06:21:54 -0000	1.33
+++ bfd/peicode.h	30 Jul 2002 05:01:19 -0000
@@ -1207,7 +1207,10 @@ _("%s: Recognised but unhandled machine 
     return NULL;
 
   if (bfd_bread (ptr, size, abfd) != size)
-    return NULL;
+    {
+      bfd_release (abfd, ptr);
+      return NULL;
+    }
 
   symbol_name = ptr;
   source_dll  = ptr + strlen (ptr) + 1;
@@ -1219,14 +1222,17 @@ _("%s: Recognised but unhandled machine 
 	(_("%s: string not null terminated in ILF object file."),
 	 bfd_archive_filename (abfd));
       bfd_set_error (bfd_error_malformed_archive);
-
+      bfd_release (abfd, ptr);
       return NULL;
     }
 
   /* Now construct the bfd.  */
   if (! pe_ILF_build_a_bfd (abfd, magic, symbol_name,
 			    source_dll, ordinal, types))
-    return NULL;
+    {
+      bfd_release (abfd, ptr);
+      return NULL;
+    }
 
   return abfd->xvec;
 }
Index: bfd/srec.c
===================================================================
RCS file: /cvs/src/src/bfd/srec.c,v
retrieving revision 1.20
diff -u -p -r1.20 srec.c
--- bfd/srec.c	25 Jun 2002 06:21:54 -0000	1.20
+++ bfd/srec.c	30 Jul 2002 05:01:19 -0000
@@ -230,22 +230,23 @@ static boolean
 srec_mkobject (abfd)
      bfd *abfd;
 {
+  bfd_size_type amt;
+  tdata_type *tdata;
+
   srec_init ();
 
-  if (abfd->tdata.srec_data == NULL)
-    {
-      bfd_size_type amt = sizeof (tdata_type);
-      tdata_type *tdata = (tdata_type *) bfd_alloc (abfd, amt);
-      if (tdata == NULL)
-	return false;
-      abfd->tdata.srec_data = tdata;
-      tdata->type = 1;
-      tdata->head = NULL;
-      tdata->tail = NULL;
-      tdata->symbols = NULL;
-      tdata->symtail = NULL;
-      tdata->csymbols = NULL;
-    }
+  amt = sizeof (tdata_type);
+  tdata = (tdata_type *) bfd_alloc (abfd, amt);
+  if (tdata == NULL)
+    return false;
+    
+  abfd->tdata.srec_data = tdata;
+  tdata->type = 1;
+  tdata->head = NULL;
+  tdata->tail = NULL;
+  tdata->symbols = NULL;
+  tdata->symtail = NULL;
+  tdata->csymbols = NULL;
 
   return true;
 }
@@ -640,6 +641,7 @@ static const bfd_target *
 srec_object_p (abfd)
      bfd *abfd;
 {
+  PTR tdata_save;
   bfd_byte b[4];
 
   srec_init ();
@@ -654,9 +656,14 @@ srec_object_p (abfd)
       return NULL;
     }
 
-  if (! srec_mkobject (abfd)
-      || ! srec_scan (abfd))
-    return NULL;
+  tdata_save = abfd->tdata.any;
+  if (! srec_mkobject (abfd) || ! srec_scan (abfd))
+    {
+      if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL)
+	bfd_release (abfd, abfd->tdata.any);
+      abfd->tdata.any = tdata_save;
+      return NULL;
+    }
 
   if (abfd->symcount > 0)
     abfd->flags |= HAS_SYMS;
@@ -670,6 +677,7 @@ static const bfd_target *
 symbolsrec_object_p (abfd)
      bfd *abfd;
 {
+  PTR tdata_save;
   char b[2];
 
   srec_init ();
@@ -684,9 +692,14 @@ symbolsrec_object_p (abfd)
       return NULL;
     }
 
-  if (! srec_mkobject (abfd)
-      || ! srec_scan (abfd))
-    return NULL;
+  tdata_save = abfd->tdata.any;
+  if (! srec_mkobject (abfd) || ! srec_scan (abfd))
+    {
+      if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL)
+	bfd_release (abfd, abfd->tdata.any);
+      abfd->tdata.any = tdata_save;
+      return NULL;
+    }
 
   if (abfd->symcount > 0)
     abfd->flags |= HAS_SYMS;
Index: bfd/versados.c
===================================================================
RCS file: /cvs/src/src/bfd/versados.c,v
retrieving revision 1.14
diff -u -p -r1.14 versados.c
--- bfd/versados.c	5 Jun 2002 03:43:11 -0000	1.14
+++ bfd/versados.c	30 Jul 2002 05:01:21 -0000
@@ -612,6 +612,7 @@ versados_object_p (abfd)
 {
   struct ext_vheader ext;
   unsigned char len;
+  tdata_type *tdata_save;
 
   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
     return NULL;
@@ -642,9 +643,12 @@ versados_object_p (abfd)
 
   /* OK, looks like a record, build the tdata and read in.  */
 
-  if (!versados_mkobject (abfd)
-      || !versados_scan (abfd))
-    return NULL;
+  tdata_save = abfd->tdata.versados_data;
+  if (!versados_mkobject (abfd) || !versados_scan (abfd))
+    {
+      abfd->tdata.versados_data = tdata_save;
+      return NULL;
+    }
 
   return abfd->xvec;
 }
Index: bfd/vms-misc.c
===================================================================
RCS file: /cvs/src/src/bfd/vms-misc.c,v
retrieving revision 1.13
diff -u -p -r1.13 vms-misc.c
--- bfd/vms-misc.c	6 Jan 2002 07:30:35 -0000	1.13
+++ bfd/vms-misc.c	30 Jul 2002 05:01:22 -0000
@@ -292,23 +292,23 @@ _bfd_vms_get_record (abfd)
 
   if (PRIV (buf_size) == 0)
     {
+      bfd_size_type amt;
+
       if (PRIV (is_vax))
 	{
-	  PRIV (vms_buf) = (unsigned char *) malloc (OBJ_S_C_MAXRECSIZ);
-	  PRIV (buf_size) = OBJ_S_C_MAXRECSIZ;
+	  amt = OBJ_S_C_MAXRECSIZ;
 	  PRIV (file_format) = FF_VAX;
 	}
       else
-	PRIV (vms_buf) = (unsigned char *) malloc (6);
+	amt = 6;
+      PRIV (vms_buf) = (unsigned char *) bfd_malloc (amt);
+      PRIV (buf_size) = amt;
     }
 
   vms_buf = PRIV (vms_buf);
 
   if (vms_buf == 0)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return -1;
-    }
+    return -1;
 
   switch (PRIV (file_format))
     {
@@ -371,7 +371,7 @@ _bfd_vms_get_record (abfd)
   if (PRIV (is_vax))
     {
       PRIV (rec_length) = bfd_bread (vms_buf, (bfd_size_type) PRIV (buf_size),
-				    abfd);
+				     abfd);
       if (PRIV (rec_length) <= 0)
 	{
 	  bfd_set_error (bfd_error_file_truncated);
@@ -383,7 +383,7 @@ _bfd_vms_get_record (abfd)
     {
       /* extract vms record length  */
 
-      _bfd_vms_get_header_values (abfd, vms_buf+test_start, NULL,
+      _bfd_vms_get_header_values (abfd, vms_buf + test_start, NULL,
 				  &PRIV (rec_length));
 
       if (PRIV (rec_length) <= 0)
@@ -405,13 +405,11 @@ _bfd_vms_get_record (abfd)
       if (PRIV (rec_length) > PRIV (buf_size))
 	{
 	  PRIV (vms_buf) = ((unsigned char *)
-			    realloc (vms_buf, (size_t) PRIV (rec_length)));
+			    bfd_realloc (vms_buf,
+					 (bfd_size_type) PRIV (rec_length)));
 	  vms_buf = PRIV (vms_buf);
 	  if (vms_buf == 0)
-	    {
-	      bfd_set_error (bfd_error_no_memory);
-	      return -1;
-	    }
+	    return -1;
 	  PRIV (buf_size) = PRIV (rec_length);
 	}
 
@@ -593,7 +591,8 @@ add_new_contents (abfd, section)
   if (sptr != NULL)
     return sptr;
 
-  newptr = (vms_section *) bfd_malloc ((bfd_size_type) sizeof (vms_section));
+  newptr = (vms_section *) bfd_alloc (abfd,
+				      (bfd_size_type) sizeof (vms_section));
   if (newptr == (vms_section *) NULL)
     return NULL;
   newptr->contents = (unsigned char *) bfd_alloc (abfd, section->_raw_size);
Index: bfd/vms.c
===================================================================
RCS file: /cvs/src/src/bfd/vms.c,v
retrieving revision 1.20
diff -u -p -r1.20 vms.c
--- bfd/vms.c	25 Jun 2002 06:21:54 -0000	1.20
+++ bfd/vms.c	30 Jul 2002 05:01:22 -0000
@@ -238,13 +238,10 @@ vms_initialize (abfd)
   int i;
   bfd_size_type amt;
 
-  if (abfd->tdata.any != 0)
-    return true;
-
   bfd_set_start_address (abfd, (bfd_vma) -1);
 
   amt = sizeof (struct vms_private_data_struct);
-  abfd->tdata.any = (struct vms_private_data_struct*) bfd_malloc (amt);
+  abfd->tdata.any = (struct vms_private_data_struct*) bfd_alloc (abfd, amt);
   if (abfd->tdata.any == 0)
     return false;
 
@@ -261,49 +258,32 @@ vms_initialize (abfd)
   PRIV (sections) = NULL;
 
   amt = sizeof (struct stack_struct) * STACKSIZE;
-  PRIV (stack) = (struct stack_struct *) bfd_malloc (amt);
+  PRIV (stack) = (struct stack_struct *) bfd_alloc (abfd, amt);
   if (PRIV (stack) == 0)
-    {
-     vms_init_no_mem1:
-      free (abfd->tdata.any);
-      abfd->tdata.any = 0;
-      return false;
-    }
+    goto error_ret1;
   PRIV (stackptr) = 0;
 
   amt = sizeof (struct bfd_hash_table);
-  PRIV (vms_symbol_table) = (struct bfd_hash_table *) bfd_malloc (amt);
+  PRIV (vms_symbol_table) = (struct bfd_hash_table *) bfd_alloc (abfd, amt);
   if (PRIV (vms_symbol_table) == 0)
-    {
-     vms_init_no_mem2:
-      free (PRIV (stack));
-      PRIV (stack) = 0;
-      goto vms_init_no_mem1;
-    }
+    goto error_ret1;
 
   if (!bfd_hash_table_init (PRIV (vms_symbol_table), _bfd_vms_hash_newfunc))
-    return false;
+    goto error_ret1;
 
   amt = sizeof (struct location_struct) * LOCATION_SAVE_SIZE;
-  PRIV (location_stack) = (struct location_struct *) bfd_malloc (amt);
+  PRIV (location_stack) = (struct location_struct *) bfd_alloc (abfd, amt);
   if (PRIV (location_stack) == 0)
-    {
-     vms_init_no_mem3:
-      free (PRIV (vms_symbol_table));
-      PRIV (vms_symbol_table) = 0;
-      goto vms_init_no_mem2;
-    }
+    goto error_ret2;
 
   for (i = 0; i < VMS_SECTION_COUNT; i++)
     PRIV (vms_section_table)[i] = NULL;
 
-  PRIV (output_buf) = (unsigned char *) malloc (MAX_OUTREC_SIZE);
+  amt = MAX_OUTREC_SIZE;
+  PRIV (output_buf) = (unsigned char *) bfd_alloc (abfd, amt);
   if (PRIV (output_buf) == 0)
-    {
-      free (PRIV (location_stack));
-      PRIV (location_stack) = 0;
-      goto vms_init_no_mem3;
-    }
+    goto error_ret2;
+
   PRIV (push_level) = 0;
   PRIV (pushed_size) = 0;
   PRIV (length_pos) = 2;
@@ -311,6 +291,13 @@ vms_initialize (abfd)
   PRIV (output_alignment) = 1;
 
   return true;
+
+ error_ret2:
+  bfd_hash_table_free (PRIV (vms_symbol_table));
+ error_ret1:
+  bfd_release (abfd, abfd->tdata.any);
+  abfd->tdata.any = 0;
+  return false;
 }
 
 /* Fill symbol->section with section ptr
@@ -394,22 +381,17 @@ vms_object_p (abfd)
   int prev_type;
   const struct bfd_target *target_vector = 0;
   const bfd_arch_info_type *arch = 0;
+  PTR tdata_save = abfd->tdata.any;
 
 #if VMS_DEBUG
   vms_debug (1, "vms_object_p(%p)\n", abfd);
 #endif
 
   if (!vms_initialize (abfd))
-    {
-      fprintf (stderr, "vms_initialize () failed !!\n");
-      return 0;
-    }
+    goto error_ret;
 
   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET))
-    {
-      bfd_set_error (bfd_error_file_truncated);
-      return 0;
-    }
+    goto err_wrong_format;
 
   prev_type = -1;
 
@@ -423,8 +405,7 @@ vms_object_p (abfd)
 #if VMS_DEBUG
 	  vms_debug (2, "next_record failed\n");
 #endif
-	  bfd_set_error (bfd_error_wrong_format);
-	  return 0;
+	  goto err_wrong_format;
 	}
 
       if ((prev_type == EOBJ_S_C_EGSD)
@@ -435,8 +416,7 @@ vms_object_p (abfd)
 #if VMS_DEBUG
 	      vms_debug (2, "vms_fixup_sections failed\n");
 #endif
-	      bfd_set_error (bfd_error_wrong_format);
-	      return 0;
+	      goto err_wrong_format;
 	    }
 	}
 
@@ -488,8 +468,7 @@ vms_object_p (abfd)
 #if VMS_DEBUG
 	  vms_debug (2, "slurp type %d failed with %d\n", prev_type, err);
 #endif
-	  bfd_set_error (bfd_error_wrong_format);
-	  return 0;
+	  goto err_wrong_format;
 	}
     }
   while ((prev_type != EOBJ_S_C_EEOM) && (prev_type != OBJ_S_C_EOM) && (prev_type != OBJ_S_C_EOMW));
@@ -501,8 +480,7 @@ vms_object_p (abfd)
 #if VMS_DEBUG
 	  vms_debug (2, "vms_fixup_sections failed\n");
 #endif
-	  bfd_set_error (bfd_error_wrong_format);
-	  return 0;
+	  goto err_wrong_format;
 	}
 
       /* set arch_info to vax  */
@@ -529,12 +507,19 @@ vms_object_p (abfd)
 #if VMS_DEBUG
       vms_debug (2, "arch not found\n");
 #endif
-      bfd_set_error (bfd_error_wrong_format);
-      return 0;
+      goto err_wrong_format;
     }
   abfd->arch_info = arch;
 
   return target_vector;
+
+ err_wrong_format:
+  bfd_set_error (bfd_error_wrong_format);
+ error_ret:
+  if (abfd->tdata.any != tdata_save && abfd->tdata.any != NULL)
+    bfd_release (abfd, abfd->tdata.any);
+  abfd->tdata.any = tdata_save;
+  return NULL;
 }
 
 /* Check the format for a file being read.
@@ -562,10 +547,7 @@ vms_mkobject (abfd)
 #endif
 
   if (!vms_initialize (abfd))
-    {
-      fprintf (stderr, "vms_initialize () failed !!\n");
-      return 0;
-    }
+    return 0;
 
   {
 #ifdef __VAX
@@ -646,10 +628,6 @@ static boolean
 vms_close_and_cleanup (abfd)
      bfd *abfd;
 {
-  asection *sec;
-  vms_section *es, *es1;
-  int i;
-
 #if VMS_DEBUG
   vms_debug (1, "vms_close_and_cleanup(%p)\n", abfd);
 #endif
@@ -657,63 +635,15 @@ vms_close_and_cleanup (abfd)
     return true;
 
   if (PRIV (vms_buf) != NULL)
-    {
-      free (PRIV (vms_buf));
-      PRIV (vms_buf) = NULL;
-    }
-  PRIV (buf_size) = 0;
-
-  if (PRIV (output_buf) != 0)
-    {
-      free (PRIV (output_buf));
-      PRIV (output_buf) = 0;
-    }
-
-  sec = abfd->sections;
-  while (sec != NULL)
-    {
-      if (sec->contents)
-	free (sec->contents);
-      sec = sec->next;
-    }
+    free (PRIV (vms_buf));
 
   if (PRIV (sections) != NULL)
-    {
-      free (PRIV (sections));
-      PRIV (sections) = NULL;
-    }
+    free (PRIV (sections));
 
   if (PRIV (vms_symbol_table))
-    {
-      bfd_hash_table_free (PRIV (vms_symbol_table));
-      PRIV (vms_symbol_table) = 0;
-    }
-
-  if (PRIV (stack))
-    {
-      free (PRIV (stack));
-      PRIV (stack) = 0;
-    }
-
-  if (PRIV (location_stack))
-    {
-      free (PRIV (location_stack));
-      PRIV (location_stack) = 0;
-    }
-
-  for (i = 0; i < VMS_SECTION_COUNT; i++)
-    {
-      es = PRIV (vms_section_table)[i];
-      while (es != NULL)
-	{
-	  es1 = es->next;
-	  free (es);
-	  es = es1;
-	}
-      PRIV (vms_section_table)[i] = NULL;
-   }
+    bfd_hash_table_free (PRIV (vms_symbol_table));
 
-  free (abfd->tdata.any);
+  bfd_release (abfd, abfd->tdata.any);
   abfd->tdata.any = NULL;
 
   return true;

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]