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]

Re: patch, xcoff linker pad section


On Thu, Jan 03, 2002 at 01:47:27PM -0600, Tom Rix wrote:
> 
> 	* xcofflink.c (_bfd_xcoff_bfd_final_link): Update .pad section ordering
> 	for recent bfd_make_section_anyway change.

I should have noticed this, along with all these other places where
the bfd section list is manipulated.  :-(  With this patch, I'm
introducing a couple of new macros to manipulate the section list,
mainly so that all such places can be easily found.  I've also
tidied error handling in the core file predicate functions, and
hopefully left the bfd in a sane state.

***POSSIBLE BREAKAGE***
netbsd_core_file_p used to tack sections on to the start of the section
list as they were created, thus reversing them from the order in the
core file.  We're now creating them in the natural order.  I don't
think it matters, but figure I ought to give fair warning.  A similar
re-ordering used to happen with gas ecoff files.  Oh, and some of the
core file handling code can only be compiled natively, so I haven't
been able to test it.

bfd/ChangeLog
	* section.c (bfd_section_init): Remove unnecessary initialisations.
	(bfd_section_list_clear): New function.
	(bfd_section_list_remove, bfd_section_list_insert): New macros.
	(_bfd_strip_section_from_output): Use them.
	* xcofflink.c (_bfd_xcoff_bfd_final_link): Likewise.
	* elf64-mmix.c (mmix_elf_final_link): Likewise.
	* elf32-mips.c (_bfd_mips_elf_final_link): Likewise.
	* elf64-mips.c (mips_elf64_final_link): Likewise.
	* coffcode.h (coff_set_alignment_hook): Likewise.
	* sunos.c (sunos_add_dynamic_symbols): Likewise.

	* netbsd-core.c (netbsd_core_file_p): Use bfd_make_section_anyway
	rather than doing our own section handling.  Clean up after errors
	with bfd_release and bfd_section_list_clear.  Handle unexpected
	flags.
	* aoutf1.h (sunos4_core_file_p): Likewise.
	* aix386-core.c (aix386_core_file_p): Likewise.
	* cisco-core.c (cisco_core_file_validate): Likewise.
	* trad-core.c (trad_unix_core_file_p): Likewise.

	* hppabsd-core.c (hppabsd_core_core_file_p):  Clean up after errors
	with bfd_release and bfd_section_list_clear.
	* hpux-core.c (hpux_core_core_file_p): Likewise.
	* irix-core.c (irix_core_core_file_p): Likewise.
	* lynx-core.c (lynx_core_file_p): Likewise.
	* osf-core.c (osf_core_core_file_p): Likewise.
	* ptrace-core.c (ptrace_unix_core_file_p): Likewise.
	* rs6000-core.c (rs6000coff_core_p): Likewise.
	* sco5-core.c (sco5_core_file_p): Likewise.

gas/ChangeLog
	* write.c (write_object_file): Make use of bfd_section_list_remove.
	* config/obj-ecoff.c (ecoff_frob_file): Likewise.
	* config/tc-mmix.c (mmix_frob_file): Likewise.

ld/ChangeLog
	* emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Make use
	of bfd_section_list_remove and bfd_section_list_insert macros.
	* emultempl/pe.em (gld_${EMULATION_NAME}_place_orphan): Likewise.
	* emultempl/mmo.em (mmo_place_orphan): Likewise.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

Index: bfd/aix386-core.c
===================================================================
RCS file: /cvs/src/src/bfd/aix386-core.c,v
retrieving revision 1.7
diff -u -p -r1.7 aix386-core.c
--- aix386-core.c	2001/09/18 09:57:21	1.7
+++ aix386-core.c	2002/01/05 09:56:51
@@ -2,7 +2,7 @@
    This was based on trad-core.c, which was written by John Gilmore of
         Cygnus Support.
    Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1996, 1998, 1999, 2000,
-   2001
+   2001, 2002
    Free Software Foundation, Inc.
    Written by Minh Tran-Le <TRANLE@INTELLICORP.COM>.
    Converted to back end form by Ian Lance Taylor <ian@cygnus.com>.
@@ -108,95 +108,84 @@ aix386_core_file_p (abfd)
 	bfd_set_error (bfd_error_wrong_format);
     loser:
       bfd_release (abfd, (char *) mergem);
+      abfd->tdata.any = NULL;
+      bfd_section_list_clear (abfd);
       return 0;
     }
 
   set_tdata (abfd, &mergem->coredata);
   core_hdr (abfd) = core;
 
-  /* Create the sections.  This is raunchy, but bfd_close wants to
-     reclaim them.  */
-  amt = sizeof (asection);
-  core_regsec (abfd) = (asection *) bfd_zalloc (abfd, amt);
+  /* Create the sections.  */
+  core_regsec (abfd) = bfd_make_section_anyway (abfd, ".reg");
   if (core_regsec (abfd) == NULL)
     goto loser;
 
-  core_reg2sec (abfd) = (asection *) bfd_zalloc (abfd, amt);
+  core_regsec (abfd)->flags = SEC_HAS_CONTENTS;
+  core_regsec (abfd)->_raw_size = sizeof (core->cd_regs);
+  core_regsec (abfd)->vma = (bfd_vma) -1;
+
+  /* We'll access the regs afresh in the core file, like any section.  */
+  core_regsec (abfd)->filepos =
+    (file_ptr) offsetof (struct corehdr, cd_regs[0]);
+
+  core_reg2sec (abfd) = bfd_make_section_anyway (abfd, ".reg2");
   if (core_reg2sec (abfd) == NULL)
     /* bfd_release frees everything allocated after it's arg.  */
     goto loser;
 
+  core_reg2sec (abfd)->flags = SEC_HAS_CONTENTS;
+  core_reg2sec (abfd)->_raw_size = sizeof (core->cd_fpregs);
+  core_reg2sec (abfd)->vma = (bfd_vma) -1;
+  core_reg2sec (abfd)->filepos =
+    (file_ptr) offsetof (struct corehdr, cd_fpregs);
+
   for (i = 0, n = 0; (i < MAX_CORE_SEGS) && (core->cd_segs[i].cs_type); i++)
     {
+      const char *sname;
+      flagword flags;
+
       if (core->cd_segs[i].cs_offset == 0)
 	continue;
-      core_section (abfd, n) = (asection *) bfd_zalloc (abfd, amt);
-      if (core_section (abfd, n) == NULL)
-	goto loser;
 
       switch (core->cd_segs[i].cs_type)
 	{
 	case COR_TYPE_DATA:
-	  core_section (abfd, n)->name = ".data";
-	  core_section (abfd, n)->flags = (SEC_ALLOC + SEC_LOAD +
-					   SEC_HAS_CONTENTS);
+	  sname = ".data";
+	  flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
 	  break;
 	case COR_TYPE_STACK:
-	  core_section (abfd, n)->name = ".stack";
-	  core_section (abfd, n)->flags = (SEC_ALLOC + SEC_LOAD +
-					   SEC_HAS_CONTENTS);
+	  sname = ".stack";
+	  flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
 	  break;
 	case COR_TYPE_LIBDATA:
-	  core_section (abfd, n)->name = ".libdata";
-	  core_section (abfd, n)->flags = (SEC_ALLOC + SEC_HAS_CONTENTS);
+	  sname = ".libdata";
+	  flags = SEC_ALLOC + SEC_HAS_CONTENTS;
 	  break;
 	case COR_TYPE_WRITE:
-	  core_section (abfd, n)->name = ".writeable";
-	  core_section (abfd, n)->flags = (SEC_ALLOC + SEC_HAS_CONTENTS);
+	  sname = ".writeable";
+	  flags = SEC_ALLOC + SEC_HAS_CONTENTS;
 	  break;
 	case COR_TYPE_MSC:
-	  core_section (abfd, n)->name = ".misc";
-	  core_section (abfd, n)->flags = (SEC_ALLOC + SEC_HAS_CONTENTS);
+	  sname = ".misc";
+	  flags = SEC_ALLOC + SEC_HAS_CONTENTS;
 	  break;
 	default:
-	  core_section (abfd, n)->name = ".unknown";
-	  core_section (abfd, n)->flags = (SEC_ALLOC + SEC_HAS_CONTENTS);
+	  sname = ".unknown";
+	  flags = SEC_ALLOC + SEC_HAS_CONTENTS;
 	  break;
 	}
+      core_section (abfd, n) = bfd_make_section_anyway (abfd, sname);
+      if (core_section (abfd, n) == NULL)
+	goto loser;
+
+      core_section (abfd, n)->flags = flags;
       core_section (abfd, n)->_raw_size = core->cd_segs[i].cs_len;
       core_section (abfd, n)->vma       = core->cd_segs[i].cs_address;
       core_section (abfd, n)->filepos   = core->cd_segs[i].cs_offset;
       core_section (abfd, n)->alignment_power = 2;
-      core_section (abfd, n)->next      = NULL;
-      if (n > 0)
-	core_section (abfd, (n - 1))->next = core_section (abfd, n);
-
-      abfd->section_count = ++n;
+      n++;
     }
-
-  core_regsec (abfd)->name = ".reg";
-  core_reg2sec (abfd)->name = ".reg2";
-
-  core_regsec (abfd)->flags = SEC_HAS_CONTENTS;
-  core_reg2sec (abfd)->flags = SEC_HAS_CONTENTS;
-
-  core_regsec (abfd)->_raw_size = sizeof (core->cd_regs);
-  core_reg2sec (abfd)->_raw_size = sizeof (core->cd_fpregs);
-
-  core_regsec (abfd)->vma = (bfd_vma) -1;
-  core_reg2sec (abfd)->vma = (bfd_vma) -1;
-
-  /* We'll access the regs afresh in the core file, like any section.  */
-  core_regsec (abfd)->filepos =
-    (file_ptr) offsetof (struct corehdr, cd_regs[0]);
-  core_reg2sec (abfd)->filepos =
-    (file_ptr) offsetof (struct corehdr, cd_fpregs);
-
-  /* Add the 2 reg fake sections to abfd.  */
-  abfd->section_count += 2;
-  abfd->sections = core_regsec (abfd);
-  core_regsec (abfd)->next = core_reg2sec (abfd);
-  core_reg2sec (abfd)->next = core_section (abfd, 0);
 
   return abfd->xvec;
 }
Index: bfd/aoutf1.h
===================================================================
RCS file: /cvs/src/src/bfd/aoutf1.h,v
retrieving revision 1.6
diff -u -p -r1.6 aoutf1.h
--- aoutf1.h	2001/09/18 09:57:21	1.6
+++ aoutf1.h	2002/01/05 09:56:53
@@ -1,6 +1,6 @@
 /* A.out "format 1" file handling code for BFD.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
-   2001
+   2001, 2002
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
@@ -641,6 +641,8 @@ sunos4_core_file_p (abfd)
     {
     loser:
       bfd_release (abfd, (char *) mergem);
+      abfd->tdata.any = NULL;
+      bfd_section_list_clear (abfd);
       return 0;
     }
 
@@ -667,31 +669,24 @@ sunos4_core_file_p (abfd)
   abfd->tdata.sun_core_data = &mergem->suncoredata;
   abfd->tdata.sun_core_data->hdr = core;
 
-  /* create the sections.  This is raunchy, but bfd_close wants to reclaim
-     them */
-  amt = sizeof (asection);
-  core_stacksec (abfd) = (asection *) bfd_zalloc (abfd, amt);
+  /* Create the sections.  */
+  core_stacksec (abfd) = bfd_make_section_anyway (abfd, ".stack");
   if (core_stacksec (abfd) == NULL)
     /* bfd_release frees everything allocated after it's arg.  */
     goto loser;
 
-  core_datasec (abfd) = (asection *) bfd_zalloc (abfd, amt);
+  core_datasec (abfd) = bfd_make_section_anyway (abfd, ".data");
   if (core_datasec (abfd) == NULL)
     goto loser;
 
-  core_regsec (abfd) = (asection *) bfd_zalloc (abfd, amt);
+  core_regsec (abfd) = bfd_make_section_anyway (abfd, ".reg");
   if (core_regsec (abfd) == NULL)
     goto loser;
 
-  core_reg2sec (abfd) = (asection *) bfd_zalloc (abfd, amt);
+  core_reg2sec (abfd) = bfd_make_section_anyway (abfd, ".reg2");
   if (core_reg2sec (abfd) == NULL)
     goto loser;
 
-  core_stacksec (abfd)->name = ".stack";
-  core_datasec (abfd)->name = ".data";
-  core_regsec (abfd)->name = ".reg";
-  core_reg2sec (abfd)->name = ".reg2";
-
   core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
   core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
   core_regsec (abfd)->flags = SEC_HAS_CONTENTS;
@@ -718,13 +712,6 @@ sunos4_core_file_p (abfd)
   core_datasec (abfd)->alignment_power = 2;
   core_regsec (abfd)->alignment_power = 2;
   core_reg2sec (abfd)->alignment_power = 2;
-
-  abfd->sections = core_stacksec (abfd);
-  core_stacksec (abfd)->next = core_datasec (abfd);
-  core_datasec (abfd)->next = core_regsec (abfd);
-  core_regsec (abfd)->next = core_reg2sec (abfd);
-
-  abfd->section_count = 4;
 
   return abfd->xvec;
 }
Index: bfd/cisco-core.c
===================================================================
RCS file: /cvs/src/src/bfd/cisco-core.c,v
retrieving revision 1.6
diff -u -p -r1.6 cisco-core.c
--- cisco-core.c	2001/09/18 09:57:21	1.6
+++ cisco-core.c	2002/01/05 09:56:57
@@ -1,5 +1,6 @@
 /* BFD back-end for CISCO crash dumps.
-   Copyright 1994, 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
+   Copyright 1994, 1997, 1999, 2000, 2001, 2002
+   Free Software Foundation, Inc.
 
 This file is part of BFD, the Binary File Descriptor library.
 
@@ -237,58 +238,43 @@ cisco_core_file_validate (abfd, crash_in
       break;
     }
 
-  abfd->sections = NULL;
-  abfd->section_count = 0;
-
-  /* Create a ".reg" section to allow access to the saved
-     registers.  */
+  /* Create a ".data" section that maps the entire file, which is
+     essentially a dump of the target system's RAM.  */
 
-  asect = (asection *) bfd_zmalloc ((bfd_size_type) sizeof (asection));
+  asect = bfd_make_section_anyway (abfd, ".data");
   if (asect == NULL)
     goto error_return;
-  asect->name = ".reg";
-  asect->flags = SEC_HAS_CONTENTS;
-  asect->vma = 0;
-  asect->filepos = bfd_get_32 (abfd, crashinfo.registers) - rambase;
-  /* Since we don't know the exact size of the saved register info,
-     choose a register section size that is either the remaining part
-     of the file, or 1024, whichever is smaller.  */
-  nread = statbuf.st_size - asect->filepos;
-  asect->_raw_size = (nread < 1024) ? nread : 1024;
-  asect->next = abfd->sections;
-  abfd->sections = asect;
-  ++abfd->section_count;
+  asect->flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
+  /* The size of memory is the size of the core file itself.  */
+  asect->_raw_size = statbuf.st_size;
+  asect->vma = rambase;
+  asect->filepos = 0;
 
   /* Create a ".crash" section to allow access to the saved
      crash information.  */
 
-  asect = (asection *) bfd_zmalloc ((bfd_size_type) sizeof (asection));
+  asect = bfd_make_section_anyway (abfd, ".crash");
   if (asect == NULL)
     goto error_return;
-  asect->name = ".crash";
   asect->flags = SEC_HAS_CONTENTS;
   asect->vma = 0;
   asect->filepos = crashinfo_offset;
   asect->_raw_size = sizeof (crashinfo);
-  asect->next = abfd->sections;
-  abfd->sections = asect;
-  ++abfd->section_count;
 
-  /* Create a ".data" section that maps the entire file, which is
-     essentially a dump of the target system's RAM.  */
+  /* Create a ".reg" section to allow access to the saved
+     registers.  */
 
-  asect = (asection *) bfd_zmalloc ((bfd_size_type) sizeof (asection));
+  asect = bfd_make_section_anyway (abfd, ".reg");
   if (asect == NULL)
     goto error_return;
-  asect->name = ".data";
-  asect->flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
-  /* The size of memory is the size of the core file itself.  */
-  asect->_raw_size = statbuf.st_size;
-  asect->vma = rambase;
-  asect->filepos = 0;
-  asect->next = abfd->sections;
-  abfd->sections = asect;
-  ++abfd->section_count;
+  asect->flags = SEC_HAS_CONTENTS;
+  asect->vma = 0;
+  asect->filepos = bfd_get_32 (abfd, crashinfo.registers) - rambase;
+  /* Since we don't know the exact size of the saved register info,
+     choose a register section size that is either the remaining part
+     of the file, or 1024, whichever is smaller.  */
+  nread = statbuf.st_size - asect->filepos;
+  asect->_raw_size = (nread < 1024) ? nread : 1024;
 
   return abfd->xvec;
 
@@ -296,17 +282,10 @@ cisco_core_file_validate (abfd, crash_in
      and there is an error of some kind.  */
 
  error_return:
-  {
-    sec_ptr nextsect;
-    for (asect = abfd->sections; asect != NULL;)
-      {
-	nextsect = asect->next;
-	free (asect);
-	asect = nextsect;
-      }
-    free (abfd->tdata.cisco_core_data);
-    return NULL;
-  }
+  bfd_release (abfd, abfd->tdata.any);
+  abfd->tdata.any = NULL;
+  bfd_section_list_clear (abfd);
+  return NULL;
 }
 
 static const bfd_target *
Index: bfd/coffcode.h
===================================================================
RCS file: /cvs/src/src/bfd/coffcode.h,v
retrieving revision 1.66
diff -u -p -r1.66 coffcode.h
--- coffcode.h	2001/12/20 21:29:21	1.66
+++ coffcode.h	2002/01/05 09:57:01
@@ -1,6 +1,6 @@
 /* Support for the generic parts of most COFF variants, for BFD.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001
+   2000, 2001, 2002
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
@@ -1680,7 +1680,7 @@ coff_set_alignment_hook (abfd, section, 
     {
       if (*ps == section)
 	{
-	  *ps = (*ps)->next;
+	  bfd_section_list_remove (abfd, ps);
 	  --abfd->section_count;
 	  break;
 	}
Index: bfd/elf32-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-mips.c,v
retrieving revision 1.134
diff -u -p -r1.134 elf32-mips.c
--- elf32-mips.c	2002/01/05 12:36:18	1.134
+++ elf32-mips.c	2002/01/05 12:38:01
@@ -5177,7 +5177,7 @@ _bfd_mips_elf_final_link (abfd, info)
 	      if (p->type == bfd_indirect_link_order)
 		p->u.indirect.section->flags &= ~SEC_HAS_CONTENTS;
 	    (*secpp)->link_order_head = NULL;
-	    *secpp = (*secpp)->next;
+	    bfd_section_list_remove (abfd, secpp);
 	    --abfd->section_count;
 
 	    break;
@@ -5547,7 +5547,7 @@ _bfd_mips_elf_final_link (abfd, info)
 		   *secpp != o;
 		   secpp = &(*secpp)->next)
 		;
-	      *secpp = (*secpp)->next;
+	      bfd_section_list_remove (abfd, secpp);
 	      --abfd->section_count;
 
 	      continue;
Index: bfd/elf64-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-mips.c,v
retrieving revision 1.25
diff -u -p -r1.25 elf64-mips.c
--- elf64-mips.c	2001/12/18 17:59:59	1.25
+++ elf64-mips.c	2002/01/05 09:57:21
@@ -1,5 +1,5 @@
 /* MIPS-specific support for 64-bit ELF
-   Copyright 1996, 1997, 1998, 1999, 2000, 2001
+   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
    Free Software Foundation, Inc.
    Ian Lance Taylor, Cygnus Support
    Linker support added by Mark Mitchell, CodeSourcery, LLC.
@@ -6392,7 +6392,7 @@ mips_elf64_final_link (abfd, info)
 	    if (p->type == bfd_indirect_link_order)
 	      p->u.indirect.section->flags &=~ SEC_HAS_CONTENTS;
 	  (*secpp)->link_order_head = NULL;
-	  *secpp = (*secpp)->next;
+	  bfd_section_list_remove (abfd, secpp);
 	  --abfd->section_count;
 	    
 	  break;
@@ -6676,7 +6676,7 @@ mips_elf64_final_link (abfd, info)
 		   *secpp != o;
 		   secpp = &(*secpp)->next)
 		;
-	      *secpp = (*secpp)->next;
+	      bfd_section_list_remove (abfd, secpp);
 	      --abfd->section_count;
 
 	      continue;
Index: bfd/elf64-mmix.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-mmix.c,v
retrieving revision 1.4
diff -u -p -r1.4 elf64-mmix.c
--- elf64-mmix.c	2001/12/17 00:52:35	1.4
+++ elf64-mmix.c	2002/01/05 09:57:22
@@ -1,5 +1,5 @@
 /* MMIX-specific support for 64-bit ELF.
-   Copyright (C) 2001 Free Software Foundation, Inc.
+   Copyright 2001, 2002 Free Software Foundation, Inc.
    Contributed by Hans-Peter Nilsson <hp@bitrange.com>
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -1667,14 +1667,12 @@ mmix_elf_final_link (abfd, info)
       if (bfd_get_section_flags (abfd, reg_section) & SEC_HAS_CONTENTS)
 	_bfd_abort (__FILE__, __LINE__, _("Register section has contents\n"));
 
-      /* FIXME: This does not seem like the proper way to kill a section,
-	 but it's the way it's done elsewhere, like elf64-alpha.c.  */
       /* Really remove the section.  */
       for (secpp = &abfd->sections;
 	   *secpp != reg_section;
 	   secpp = &(*secpp)->next)
 	;
-      *secpp = (*secpp)->next;
+      bfd_section_list_remove (abfd, secpp);
       --abfd->section_count;
     }
 
Index: bfd/hppabsd-core.c
===================================================================
RCS file: /cvs/src/src/bfd/hppabsd-core.c,v
retrieving revision 1.5
diff -u -p -r1.5 hppabsd-core.c
--- hppabsd-core.c	2001/09/18 09:57:24	1.5
+++ hppabsd-core.c	2002/01/05 09:57:22
@@ -1,5 +1,5 @@
 /* BFD back-end for HPPA BSD core files.
-   Copyright 1993, 1994, 1995, 1998, 1999, 2001
+   Copyright 1993, 1994, 1995, 1998, 1999, 2001, 2002
    Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -183,6 +183,8 @@ hppabsd_core_core_file_p (abfd)
 					   clicksz * u.u_ssize,
 					   NBPG * (USIZE + KSTAKSIZE)
 					     + clicksz * u.u_dsize, 2);
+  if (core_stacksec (abfd) == NULL)
+    goto fail;
   core_stacksec (abfd)->vma = USRSTACK;
 
   core_datasec (abfd) = make_bfd_asection (abfd, ".data",
@@ -190,17 +192,27 @@ hppabsd_core_core_file_p (abfd)
 					    + SEC_HAS_CONTENTS,
 					  clicksz * u.u_dsize,
 					  NBPG * (USIZE + KSTAKSIZE), 2);
+  if (core_datasec (abfd) == NULL)
+    goto fail;
   core_datasec (abfd)->vma = UDATASEG;
 
   core_regsec (abfd) = make_bfd_asection (abfd, ".reg",
 					 SEC_HAS_CONTENTS,
 					 KSTAKSIZE * NBPG,
 					 NBPG * USIZE, 2);
+  if (core_regsec (abfd) == NULL)
+    goto fail;
   core_regsec (abfd)->vma = 0;
 
   strncpy (core_command (abfd), u.u_comm, MAXCOMLEN + 1);
   core_signal (abfd) = u.u_code;
   return abfd->xvec;
+
+ fail:
+  bfd_release (abfd, abfd->tdata.any);
+  abfd->tdata.any = NULL;
+  bfd_section_list_clear (abfd);
+  return NULL;
 }
 
 static char *
Index: bfd/hpux-core.c
===================================================================
RCS file: /cvs/src/src/bfd/hpux-core.c,v
retrieving revision 1.5
diff -u -p -r1.5 hpux-core.c
--- hpux-core.c	2001/09/18 09:57:24	1.5
+++ hpux-core.c	2002/01/05 09:57:22
@@ -1,5 +1,5 @@
 /* BFD back-end for HP/UX core files.
-   Copyright 1993, 1994, 1996, 1998, 1999, 2001
+   Copyright 1993, 1994, 1996, 1998, 1999, 2001, 2002
    Free Software Foundation, Inc.
    Written by Stu Grossman, Cygnus Support.
    Converted to back-end form by Ian Lance Taylor, Cygnus SUpport
@@ -246,7 +246,7 @@ hpux_core_core_file_p (abfd)
                                         core_header.len,
                                         (int) &proc_info - (int) & proc_info.hw_regs,
                                         2))
-                  return NULL;
+		  goto fail;
               }
             else
               {
@@ -259,7 +259,7 @@ hpux_core_core_file_p (abfd)
 					    core_header.len,
 					    (int) &proc_info - (int) & proc_info.hw_regs,
 					    2))
-		      return NULL;
+		      goto fail;
                   }
                 /* We always make one of these sections, for every thread. */
                 sprintf (secname, ".reg/%d", core_kernel_thread_id (abfd));
@@ -268,7 +268,7 @@ hpux_core_core_file_p (abfd)
                                         core_header.len,
                                         (int) &proc_info - (int) & proc_info.hw_regs,
                                         2))
-                  return NULL;
+		  goto fail;
               }
 	    core_signal (abfd) = proc_info.sig;
             if (bfd_seek (abfd, (file_ptr) core_header.len, SEEK_CUR) != 0)
@@ -286,7 +286,7 @@ hpux_core_core_file_p (abfd)
 	  if (!make_bfd_asection (abfd, ".data",
 				  SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
 				  core_header.len, core_header.addr, 2))
-	    return NULL;
+	    goto fail;
 
 	  bfd_seek (abfd, (file_ptr) core_header.len, SEEK_CUR);
           good_sections++;
@@ -302,7 +302,8 @@ hpux_core_core_file_p (abfd)
 	  unknown_sections++;
           break;
 
-         default: return 0; /*unrecognized core file type */
+         default:
+	   goto fail; /*unrecognized core file type */
 	}
     }
 
@@ -320,6 +321,12 @@ hpux_core_core_file_p (abfd)
        abfd->filename);
 
   return abfd->xvec;
+
+ fail:
+  bfd_release (abfd, core_hdr (abfd));
+  core_hdr (abfd) = NULL;
+  bfd_section_list_clear (abfd);
+  return NULL;
 }
 
 static char *
Index: bfd/irix-core.c
===================================================================
RCS file: /cvs/src/src/bfd/irix-core.c,v
retrieving revision 1.5
diff -u -p -r1.5 irix-core.c
--- irix-core.c	2001/09/18 09:57:25	1.5
+++ irix-core.c	2002/01/05 09:57:22
@@ -1,5 +1,6 @@
 /* BFD back-end for Irix core files.
-   Copyright 1993, 1994, 1996, 1999, 2001 Free Software Foundation, Inc.
+   Copyright 1993, 1994, 1996, 1999, 2001, 2002
+   Free Software Foundation, Inc.
    Written by Stu Grossman, Cygnus Support.
    Converted to back-end form by Ian Lance Taylor, Cygnus Support
 
@@ -109,7 +110,7 @@ irix_core_core_file_p (abfd)
   core_signal (abfd) = coreout.c_sigcause;
 
   if (bfd_seek (abfd, coreout.c_vmapoffset, SEEK_SET) != 0)
-    return NULL;
+    goto fail;
 
   for (i = 0; i < coreout.c_nvmap; i++)
     {
@@ -146,7 +147,7 @@ irix_core_core_file_p (abfd)
 			      vmap.v_len,
 			      vmap.v_vaddr,
 			      vmap.v_offset))
-	return NULL;
+	goto fail;
     }
 
   /* Make sure that the regs are contiguous within the core file. */
@@ -157,21 +158,28 @@ irix_core_core_file_p (abfd)
 
   if (idg->i_offset + idg->i_len != idf->i_offset
       || idf->i_offset + idf->i_len != ids->i_offset)
-    return 0;			/* Can't deal with non-contig regs */
+    goto fail;			/* Can't deal with non-contig regs */
 
   if (bfd_seek (abfd, idg->i_offset, SEEK_SET) != 0)
-    return NULL;
+    goto fail;
 
-  make_bfd_asection (abfd, ".reg",
-		     SEC_HAS_CONTENTS,
-		     idg->i_len + idf->i_len + ids->i_len,
-		     0,
-		     idg->i_offset);
+  if (!make_bfd_asection (abfd, ".reg",
+			  SEC_HAS_CONTENTS,
+			  idg->i_len + idf->i_len + ids->i_len,
+			  0,
+			  idg->i_offset))
+    goto fail;
 
   /* OK, we believe you.  You're a core file (sure, sure).  */
   bfd_default_set_arch_mach (abfd, bfd_arch_mips, 0);
 
   return abfd->xvec;
+
+ fail:
+  bfd_release (abfd, core_hdr (abfd));
+  core_hdr (abfd) = NULL;
+  bfd_section_list_clear (abfd);
+  return NULL;
 }
 
 static char *
Index: bfd/lynx-core.c
===================================================================
RCS file: /cvs/src/src/bfd/lynx-core.c,v
retrieving revision 1.4
diff -u -p -r1.4 lynx-core.c
--- lynx-core.c	2001/09/18 09:57:25	1.4
+++ lynx-core.c	2002/01/05 09:57:22
@@ -1,5 +1,5 @@
 /* BFD back end for Lynx core files
-   Copyright 1993, 1994, 1995, 2001 Free Software Foundation, Inc.
+   Copyright 1993, 1994, 1995, 2001, 2002 Free Software Foundation, Inc.
    Written by Stu Grossman of Cygnus Support.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -129,19 +129,19 @@ lynx_core_file_p (abfd)
 
   threadp = (core_st_t *) bfd_alloc (abfd, tcontext_size);
   if (!threadp)
-    return NULL;
+    goto fail;
 
   /* Save thread contexts */
 
   if (bfd_seek (abfd, (file_ptr) pagesize, SEEK_SET) != 0)
-    return NULL;
+    goto fail;
 
   if (bfd_bread ((void *) threadp, tcontext_size, abfd) != tcontext_size)
     {
       /* Probably too small to be a core file */
       if (bfd_get_error () != bfd_error_system_call)
 	bfd_set_error (bfd_error_wrong_format);
-      return NULL;
+      goto fail;
     }
 
   core_signal (abfd) = threadp->currsig;
@@ -152,7 +152,7 @@ lynx_core_file_p (abfd)
 			       pss.slimit,
 			       pagesize + tcontext_size);
   if (!newsect)
-    return NULL;
+    goto fail;
 
   newsect = make_bfd_asection (abfd, ".data",
 			       SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
@@ -170,7 +170,7 @@ lynx_core_file_p (abfd)
 #endif
 			       );
   if (!newsect)
-    return NULL;
+    goto fail;
 
 /* And, now for the .reg/XXX pseudo sections.  Each thread has it's own
    .reg/XXX section, where XXX is the thread id (without leading zeros).  The
@@ -185,7 +185,7 @@ lynx_core_file_p (abfd)
 			       0,
 			       pagesize);
   if (!newsect)
-    return NULL;
+    goto fail;
 
   for (secnum = 0; secnum < pss.threadcnt; secnum++)
     {
@@ -198,10 +198,16 @@ lynx_core_file_p (abfd)
 				   0,
 				   pagesize + secnum * sizeof (core_st_t));
       if (!newsect)
-	return NULL;
+	goto fail;
     }
 
   return abfd->xvec;
+
+ fail:
+  bfd_release (abfd, core_hdr (abfd));
+  core_hdr (abfd) = NULL;
+  bfd_section_list_clear (abfd);
+  return NULL;
 }
 
 char *
Index: bfd/netbsd-core.c
===================================================================
RCS file: /cvs/src/src/bfd/netbsd-core.c,v
retrieving revision 1.5
diff -u -p -r1.5 netbsd-core.c
--- netbsd-core.c	2001/09/18 09:57:25	1.5
+++ netbsd-core.c	2002/01/05 09:57:23
@@ -1,5 +1,6 @@
 /* BFD back end for NetBSD style core files
-   Copyright 1988, 1989, 1991, 1992, 1993, 1996, 1998, 1999, 2000, 2001
+   Copyright 1988, 1989, 1991, 1992, 1993, 1996, 1998, 1999, 2000, 2001,
+   2002
    Free Software Foundation, Inc.
    Written by Paul Kranenburg, EUR
 
@@ -78,10 +79,7 @@ netbsd_core_file_p (abfd)
   amt = sizeof (struct netbsd_core_struct);
   rawptr = (struct netbsd_core_struct *) bfd_zalloc (abfd, amt);
   if (rawptr == NULL)
-    {
-      bfd_set_error (bfd_error_no_memory);
-      return 0;
-    }
+    return 0;
 
   rawptr->core = core;
   abfd->tdata.netbsd_core_data = rawptr;
@@ -89,6 +87,8 @@ netbsd_core_file_p (abfd)
   offset = core.c_hdrsize;
   for (i = 0; i < core.c_nseg; i++)
     {
+      const char *sname;
+      flagword flags;
 
       if (bfd_seek (abfd, offset, SEEK_SET) != 0)
 	goto punt;
@@ -107,78 +107,63 @@ netbsd_core_file_p (abfd)
 
       offset += core.c_seghdrsize;
 
-      amt = sizeof (asection);
-      asect = (asection *) bfd_zalloc (abfd, amt);
-      if (asect == NULL)
+      switch (CORE_GETFLAG (coreseg))
 	{
-	  bfd_set_error (bfd_error_no_memory);
-	  goto punt;
+	case CORE_CPU:
+	  sname = ".reg";
+	  flags = SEC_ALLOC + SEC_HAS_CONTENTS;
+	  break;
+	case CORE_DATA:
+	  sname = ".data";
+	  flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
+	  break;
+	case CORE_STACK:
+	  sname = ".stack";
+	  flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
+	  break;
+	default:
+	  sname = ".unknown";
+	  flags = SEC_ALLOC + SEC_HAS_CONTENTS;
+	  break;
 	}
+      asect = bfd_make_section_anyway (abfd, sname);
+      if (asect == NULL)
+	goto punt;
 
+      asect->flags = flags;
       asect->_raw_size = coreseg.c_size;
       asect->vma = coreseg.c_addr;
       asect->filepos = offset;
       asect->alignment_power = 2;
-      asect->next = abfd->sections;
-      abfd->sections = asect;
-      abfd->section_count++;
+
       offset += coreseg.c_size;
 
-      switch (CORE_GETFLAG(coreseg))
+#ifdef CORE_FPU_OFFSET
+      switch (CORE_GETFLAG (coreseg))
 	{
 	case CORE_CPU:
-	  asect->name = ".reg";
-	  asect->flags = SEC_ALLOC + SEC_HAS_CONTENTS;
-#ifdef CORE_FPU_OFFSET
 	  /* Hackish...  */
 	  asect->_raw_size = CORE_FPU_OFFSET;
-	  amt = sizeof (asection);
-	  asect2 = (asection *) bfd_zalloc (abfd, amt);
+	  asect2 = bfd_make_section_anyway (abfd, ".reg2");
 	  if (asect2 == NULL)
-	    {
-	      bfd_set_error (bfd_error_no_memory);
-	      goto punt;
-	    }
+	    goto punt;
 	  asect2->_raw_size = coreseg.c_size - CORE_FPU_OFFSET;
 	  asect2->vma = 0;
 	  asect2->filepos = asect->filepos + CORE_FPU_OFFSET;
 	  asect2->alignment_power = 2;
-	  asect2->next = abfd->sections;
-	  asect2->name = ".reg2";
 	  asect2->flags = SEC_ALLOC + SEC_HAS_CONTENTS;
-	  abfd->sections = asect2;
-	  abfd->section_count++;
-#endif
-
-	  break;
-	case CORE_DATA:
-	  asect->name = ".data";
-	  asect->flags = SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS;
 	  break;
-	case CORE_STACK:
-	  asect->name = ".stack";
-	  asect->flags = SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS;
-	  break;
 	}
+#endif
     }
 
   /* OK, we believe you.  You're a core file (sure, sure).  */
   return abfd->xvec;
 
  punt:
-  {
-    asection *anext;
-    for (asect = abfd->sections; asect; asect = anext)
-      {
-	anext = asect->next;
-	free ((void *) asect);
-      }
-  }
-
-  free ((void *) rawptr);
-  abfd->tdata.netbsd_core_data = NULL;
-  abfd->sections = NULL;
-  abfd->section_count = 0;
+  bfd_release (abfd, abfd->tdata.any);
+  abfd->tdata.any = NULL;
+  bfd_section_list_clear (abfd);
   return 0;
 }
 
Index: bfd/osf-core.c
===================================================================
RCS file: /cvs/src/src/bfd/osf-core.c,v
retrieving revision 1.4
diff -u -p -r1.4 osf-core.c
--- osf-core.c	2001/09/18 09:57:25	1.4
+++ osf-core.c	2002/01/05 09:57:23
@@ -1,5 +1,5 @@
 /* BFD back-end for OSF/1 core files.
-   Copyright 1993, 1994, 1995, 1998, 1999, 2001
+   Copyright 1993, 1994, 1995, 1998, 1999, 2001, 2002
    Free Software Foundation, Inc.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -158,12 +158,18 @@ osf_core_core_file_p (abfd)
 			      (bfd_size_type) core_scnhdr.size,
 			      (bfd_vma) core_scnhdr.vaddr,
 			      (file_ptr) core_scnhdr.scnptr))
-	return NULL;
+	goto fail;
     }
 
   /* OK, we believe you.  You're a core file (sure, sure).  */
 
   return abfd->xvec;
+
+ fail:
+  bfd_release (abfd, core_hdr (abfd));
+  core_hdr (abfd) = NULL;
+  bfd_section_list_clear (abfd);
+  return NULL;
 }
 
 static char *
Index: bfd/ptrace-core.c
===================================================================
RCS file: /cvs/src/src/bfd/ptrace-core.c,v
retrieving revision 1.5
diff -u -p -r1.5 ptrace-core.c
--- ptrace-core.c	2001/09/18 09:57:26	1.5
+++ ptrace-core.c	2002/01/05 09:57:23
@@ -1,5 +1,5 @@
 /* BFD backend for core files which use the ptrace_user structure
-   Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2001
+   Copyright 1993, 1994, 1995, 1996, 1998, 1999, 2001, 2002
    Free Software Foundation, Inc.
    The structure of this file is based on trad-core.c written by John Gilmore
    of Cygnus Support.
@@ -89,24 +89,18 @@ ptrace_unix_core_file_p (abfd)
 
   rawptr->u = u; /*Copy the uarea into the tdata part of the bfd */
 
-  /* Create the sections.  This is raunchy, but bfd_close wants to free
-     them separately.  */
+  /* Create the sections.  */
 
-  amt = sizeof (asection);
-  core_stacksec (abfd) = (asection *) bfd_zalloc (abfd, amt);
+  core_stacksec (abfd) = bfd_make_section_anyway (abfd, ".stack");
   if (core_stacksec (abfd) == NULL)
-    return NULL;
-  core_datasec (abfd) = (asection *) bfd_zalloc (abfd, amt);
+    goto fail;
+  core_datasec (abfd) = bfd_make_section_anyway (abfd, ".data");
   if (core_datasec (abfd) == NULL)
-    return NULL;
-  core_regsec (abfd) = (asection *) bfd_zalloc (abfd, amt);
+    goto fail;
+  core_regsec (abfd) = bfd_make_section_anyway (abfd, ".reg");
   if (core_regsec (abfd) == NULL)
-    return NULL;
+    goto fail;
 
-  core_stacksec (abfd)->name = ".stack";
-  core_datasec (abfd)->name = ".data";
-  core_regsec (abfd)->name = ".reg";
-
   /* FIXME:  Need to worry about shared memory, library data, and library
      text.  I don't think that any of these things are supported on the
      system on which I am developing this for though.  */
@@ -132,12 +126,13 @@ ptrace_unix_core_file_p (abfd)
   core_datasec (abfd)->alignment_power = 2;
   core_regsec (abfd)->alignment_power = 2;
 
-  abfd->sections = core_stacksec (abfd);
-  core_stacksec (abfd)->next = core_datasec (abfd);
-  core_datasec (abfd)->next = core_regsec (abfd);
-  abfd->section_count = 3;
-
   return abfd->xvec;
+
+ fail:
+  bfd_release (abfd, abfd->tdata.any);
+  abfd->tdata.any = NULL;
+  bfd_section_list_clear (abfd);
+  return NULL;
 }
 
 char *
Index: bfd/rs6000-core.c
===================================================================
RCS file: /cvs/src/src/bfd/rs6000-core.c,v
retrieving revision 1.9
diff -u -p -r1.9 rs6000-core.c
--- rs6000-core.c	2001/09/18 09:57:26	1.9
+++ rs6000-core.c	2002/01/05 09:57:24
@@ -1,6 +1,6 @@
 /* IBM RS/6000 "XCOFF" back-end for BFD.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
-   2001
+   2001, 2002
    Free Software Foundation, Inc.
    FIXME: Can someone provide a transliteration of this name into ASCII?
    Using the following chars caused a compiler warning on HIUX (so I replaced
@@ -462,13 +462,13 @@ rs6000coff_core_p (abfd)
   if (!make_bfd_asection (abfd, ".stack",
 			  SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
 			  c_size, c_stackend - c_size, c_stack))
-    return NULL;
+    goto fail;
 
   /* .reg section for all registers.  */
   if (!make_bfd_asection (abfd, ".reg",
 			  SEC_HAS_CONTENTS,
 			  c_regsize, (bfd_vma) 0, c_regoff))
-    return NULL;
+    goto fail;
 
   /* .ldinfo section.
      To actually find out how long this section is in this particular
@@ -477,7 +477,7 @@ rs6000coff_core_p (abfd)
   if (!make_bfd_asection (abfd, ".ldinfo",
 			  SEC_HAS_CONTENTS,
 			  c_lsize, (bfd_vma) 0, c_loader))
-    return NULL;
+    goto fail;
 
 #ifndef CORE_VERSION_1
   /* .data section if present.
@@ -494,7 +494,7 @@ rs6000coff_core_p (abfd)
 			      (bfd_vma)
 				CDATA_ADDR (core.old.c_u.u_dsize),
 			      c_stack + c_size))
-	return NULL;
+	goto fail;
     }
 #endif
 
@@ -536,7 +536,7 @@ rs6000coff_core_p (abfd)
 				c_datasize,
 				(bfd_vma) CDATA_ADDR (c_datasize),
 				c_data))
-	  return NULL;
+	  goto fail;
       }
 
     /* .data sections from loaded objects.  */
@@ -548,9 +548,9 @@ rs6000coff_core_p (abfd)
     while (1)
       {
 	if (bfd_seek (abfd, c_loader, SEEK_SET) != 0)
-	  return NULL;
+	  goto fail;
 	if (bfd_bread (&ldinfo, size, abfd) != size)
-	  return NULL;
+	  goto fail;
 
 	if (proc64)
 	  {
@@ -571,7 +571,7 @@ rs6000coff_core_p (abfd)
 	  if (!make_bfd_asection (abfd, ".data",
 				  SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
 				  ldi_datasize, ldi_dataorg, ldi_core))
-	    return NULL;
+	    goto fail;
 
 	if (ldi_next == 0)
 	  break;
@@ -584,7 +584,7 @@ rs6000coff_core_p (abfd)
 	bfd_size_type i;
 
 	if (bfd_seek (abfd, c_vmm, SEEK_SET) != 0)
-	  return NULL;
+	  goto fail;
 
 	for (i = 0; i < c_vmregions; i++)
 	  {
@@ -595,7 +595,7 @@ rs6000coff_core_p (abfd)
 
 	    size = CORE_NEW (core) ? sizeof (vminfo.new) : sizeof (vminfo.old);
 	    if (bfd_bread (&vminfo, size, abfd) != size)
-	      return NULL;
+	      goto fail;
 
 	    if (CORE_NEW (core))
 	      {
@@ -615,13 +615,19 @@ rs6000coff_core_p (abfd)
 				      SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,
 				      vminfo_size, vminfo_addr,
 				      vminfo_offset))
-		return NULL;
+		goto fail;
 	  }
       }
   }
 #endif
 
   return abfd->xvec;		/* This is garbage for now.  */
+
+ fail:
+  bfd_release (abfd, abfd->tdata.any);
+  abfd->tdata.any = NULL;
+  bfd_section_list_clear (abfd);
+  return NULL;
 }
 
 /* Return `true' if given core is from the given executable.  */
Index: bfd/sco5-core.c
===================================================================
RCS file: /cvs/src/src/bfd/sco5-core.c,v
retrieving revision 1.5
diff -u -p -r1.5 sco5-core.c
--- sco5-core.c	2001/09/18 09:57:26	1.5
+++ sco5-core.c	2002/01/05 09:57:24
@@ -1,5 +1,5 @@
 /* BFD back end for SCO5 core files (U-area and raw sections)
-   Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+   Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
    Written by Jouke Numan <jnuman@hiscom.nl>
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -176,15 +176,15 @@ sco5_core_file_p (abfd)
     {
       /* Old version, no section heads, read info from user struct */
 
-      u = read_uarea(abfd, coffsets.u_user);
+      u = read_uarea (abfd, coffsets.u_user);
       if (! u)
-          return NULL;
+	goto fail;
 
       if (!make_bfd_asection (abfd, ".reg", SEC_HAS_CONTENTS,
                               (bfd_size_type) coffsets.u_usize,
                               0 - (bfd_vma) u->u_ar0,
                               (file_ptr) coffsets.u_user))
-        return NULL;
+	goto fail;
 
       if (!make_bfd_asection (abfd, ".data",
 			      SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
@@ -192,14 +192,14 @@ sco5_core_file_p (abfd)
 			       + u->u_exdata.ux_bsize),
                               (bfd_vma) u->u_exdata.ux_datorg,
                               (file_ptr) coffsets.u_data))
-        return NULL;
+	goto fail;
 
       if (!make_bfd_asection (abfd, ".stack",
 			      SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
                               (bfd_size_type) u->u_ssize * NBPC,
                               (bfd_vma) u->u_sub,
                               (file_ptr) coffsets.u_stack))
-        return NULL;
+	goto fail;
 
       return abfd->xvec;		/* Done for version 1 */
     }
@@ -223,7 +223,7 @@ sco5_core_file_p (abfd)
       || (chead.cs_x.csx_magic != COREMAGIC_NUMBER))
     {
       bfd_set_error (bfd_error_wrong_format);
-      return NULL;
+      goto fail;
     }
 
   /* OK, we believe you.  You're a core file (sure, sure).  */
@@ -237,7 +237,7 @@ sco5_core_file_p (abfd)
 	      != sizeof chead))
         {
           bfd_set_error (bfd_error_wrong_format);
-          return NULL;
+	  goto fail;
         }
 
       switch (chead.cs_stype)
@@ -246,15 +246,15 @@ sco5_core_file_p (abfd)
 	  if (chead.cs_x.csx_magic != COREMAGIC_NUMBER)
 	    {
 	      bfd_set_error (bfd_error_wrong_format);
-	      return NULL;
+	      goto fail;
 	    }
 	  secname = NULL;
 	  nsecs++;				/* MAGIC not in section cnt!*/
 	  break;
 	case CORES_UAREA:			/* U-area, read in tdata */
-	  u = read_uarea(abfd, chead.cs_sseek);
+	  u = read_uarea (abfd, chead.cs_sseek);
 	  if (! u)
-	    return NULL;
+	    goto fail;
 
           /* This is tricky.  As the "register section", we give them
 	     the entire upage and stack.  u.u_ar0 points to where
@@ -325,12 +325,20 @@ sco5_core_file_p (abfd)
 				 (bfd_size_type) chead.cs_vsize,
 				 (bfd_vma) chead.cs_vaddr,
 				 (file_ptr) chead.cs_sseek))
-        return NULL;
+	goto fail;
 
     }
 
   return abfd->xvec;
 
+ fail:
+  if (abfd->tdata.any)
+    {
+      bfd_release (abfd, abfd->tdata.any);
+      abfd->tdata.any = NULL;
+    }
+  bfd_section_list_clear (abfd);
+  return NULL;
 }
 
 char *
Index: bfd/section.c
===================================================================
RCS file: /cvs/src/src/bfd/section.c,v
retrieving revision 1.42
diff -u -p -r1.42 section.c
--- section.c	2001/12/17 00:40:53	1.42
+++ section.c	2002/01/05 09:57:25
@@ -1,6 +1,6 @@
 /* Object file "section" support for the BFD library.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001
+   2000, 2001, 2002
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
@@ -560,6 +560,32 @@ CODE_FRAGMENT
 .#define bfd_get_section_size_after_reloc(section) \
 .     ((section)->reloc_done ? (section)->_cooked_size \
 .                            : (abort (), (bfd_size_type) 1))
+.
+.{* Macros to handle insertion and deletion of a bfd's sections.  These
+.   only handle the list pointers, ie. do not adjust section_count,
+.   target_index etc.  *}
+.#define bfd_section_list_remove(ABFD, PS) \
+.  do							\
+.    {							\
+.      asection **_ps = PS;				\
+.      asection *_s = *_ps;				\
+.      *_ps = _s->next;				\
+.      if (_s->next == NULL)				\
+.        (ABFD)->section_tail = _ps;			\
+.    }							\
+.  while (0)
+.#define bfd_section_list_insert(ABFD, PS, S) \
+.  do							\
+.    {							\
+.      asection **_ps = PS;				\
+.      asection *_s = S;				\
+.      _s->next = *_ps;				\
+.      *_ps = _s;					\
+.      if (_s->next == NULL)				\
+.        (ABFD)->section_tail = &_s->next;		\
+.    }							\
+.  while (0)
+.
 */
 
 /* We use a macro to initialize the static asymbol structures because
@@ -680,16 +706,7 @@ bfd_section_init (abfd, newsect)
 
   newsect->id = section_id;
   newsect->index = abfd->section_count;
-  newsect->flags = SEC_NO_FLAGS;
-
-  newsect->userdata = NULL;
-  newsect->contents = NULL;
-  newsect->next = (asection *) NULL;
-  newsect->relocation = (arelent *) NULL;
-  newsect->reloc_count = 0;
-  newsect->line_filepos = 0;
   newsect->owner = abfd;
-  newsect->comdat = NULL;
 
   /* Create a symbol whose only job is to point to this section.  This
      is useful for things like relocs which are relative to the base
@@ -727,6 +744,29 @@ These are the functions exported by the 
 
 /*
 FUNCTION
+	bfd_section_list_clear
+
+SYNOPSIS
+	void bfd_section_list_clear (bfd *);
+
+DESCRIPTION
+	Clears the section list, and also resets the section count and
+	hash table entries.
+*/
+
+void
+bfd_section_list_clear (abfd)
+     bfd *abfd;
+{
+  abfd->sections = NULL;
+  abfd->section_tail = &abfd->sections;
+  abfd->section_count = 0;
+  memset ((PTR) abfd->section_htab.table, 0,
+	  abfd->section_htab.size * sizeof (struct bfd_hash_entry *));
+}
+
+/*
+FUNCTION
 	bfd_get_section_by_name
 
 SYNOPSIS
@@ -1357,9 +1397,7 @@ _bfd_strip_section_from_output (info, s)
       for (spp = &os->owner->sections; *spp; spp = &(*spp)->next)
 	if (*spp == os)
 	  {
-	    *spp = os->next;
-	    if (os->next == NULL)
-	      os->owner->section_tail = spp;
+	    bfd_section_list_remove (os->owner, spp);
 	    os->owner->section_count--;
 	    break;
 	  }
Index: bfd/sunos.c
===================================================================
RCS file: /cvs/src/src/bfd/sunos.c,v
retrieving revision 1.6
diff -u -p -r1.6 sunos.c
--- sunos.c	2001/10/02 05:58:41	1.6
+++ sunos.c	2002/01/05 09:57:28
@@ -1,5 +1,6 @@
 /* BFD backend for SunOS binaries.
-   Copyright 1990, 1991, 1992, 1994, 1995, 1996, 1997, 1998, 2000, 2001
+   Copyright 1990, 1991, 1992, 1994, 1995, 1996, 1997, 1998, 2000, 2001,
+   2002
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
@@ -877,6 +878,7 @@ sunos_add_dynamic_symbols (abfd, info, s
   bfd *dynobj;
   struct sunos_dynamic_info *dinfo;
   unsigned long need;
+  asection **ps;
 
   /* Make sure we have all the required sections.  */
   if (info->hash->creator == abfd->xvec)
@@ -902,17 +904,12 @@ sunos_add_dynamic_symbols (abfd, info, s
      want, because that one still implies that the section takes up
      space in the output file.  If this is the first object we have
      seen, we must preserve the dynamic sections we just created.  */
-  if (abfd != dynobj)
-    abfd->sections = NULL;
-  else
+  for (ps = &abfd->sections; *ps != NULL; )
     {
-      asection *s;
-
-      for (s = abfd->sections;
-	   (s->flags & SEC_LINKER_CREATED) == 0;
-	   s = s->next)
-	;
-      abfd->sections = s;
+      if (abfd != dynobj || ((*ps)->flags & SEC_LINKER_CREATED) == 0)
+	bfd_section_list_remove (abfd, ps);
+      else
+	ps = &(*ps)->next;
     }
 
   /* The native linker seems to just ignore dynamic objects when -r is
Index: bfd/trad-core.c
===================================================================
RCS file: /cvs/src/src/bfd/trad-core.c,v
retrieving revision 1.10
diff -u -p -r1.10 trad-core.c
--- trad-core.c	2001/09/18 09:57:26	1.10
+++ trad-core.c	2002/01/05 09:57:28
@@ -1,6 +1,6 @@
 /* BFD back end for traditional Unix core files (U-area and raw sections)
    Copyright 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999,
-   2000, 2001
+   2000, 2001, 2002
    Free Software Foundation, Inc.
    Written by John Gilmore of Cygnus Support.
 
@@ -159,26 +159,18 @@ trad_unix_core_file_p (abfd)
 
   rawptr->u = u; /*Copy the uarea into the tdata part of the bfd */
 
-  /* Create the sections.  This is raunchy, but bfd_close wants to free
-     them separately.  */
+  /* Create the sections.  */
 
-  amt = sizeof (asection);
-  core_stacksec(abfd) = (asection *) bfd_zalloc (abfd, amt);
+  core_stacksec(abfd) = bfd_make_section_anyway (abfd, ".stack");
   if (core_stacksec (abfd) == NULL)
-    return NULL;
-  amt = sizeof (asection);
-  core_datasec (abfd) = (asection *) bfd_zalloc (abfd, amt);
+    goto fail;
+  core_datasec (abfd) = bfd_make_section_anyway (abfd, ".data");
   if (core_datasec (abfd) == NULL)
-    return NULL;
-  amt = sizeof (asection);
-  core_regsec (abfd) = (asection *) bfd_zalloc (abfd, amt);
+    goto fail;
+  core_regsec (abfd) = bfd_make_section_anyway (abfd, ".reg");
   if (core_regsec (abfd) == NULL)
-    return NULL;
+    goto fail;
 
-  core_stacksec (abfd)->name = ".stack";
-  core_datasec (abfd)->name = ".data";
-  core_regsec (abfd)->name = ".reg";
-
   core_stacksec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
   core_datasec (abfd)->flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
   core_regsec (abfd)->flags = SEC_HAS_CONTENTS;
@@ -234,12 +226,13 @@ trad_unix_core_file_p (abfd)
   core_datasec (abfd)->alignment_power = 2;
   core_regsec (abfd)->alignment_power = 2;
 
-  abfd->sections = core_stacksec (abfd);
-  core_stacksec (abfd)->next = core_datasec (abfd);
-  core_datasec (abfd)->next = core_regsec (abfd);
-  abfd->section_count = 3;
-
   return abfd->xvec;
+
+ fail:
+  bfd_release (abfd, abfd->tdata.any);
+  abfd->tdata.any = NULL;
+  bfd_section_list_clear (abfd);
+  return NULL;
 }
 
 char *
Index: bfd/xcofflink.c
===================================================================
RCS file: /cvs/src/src/bfd/xcofflink.c,v
retrieving revision 1.17
diff -u -p -r1.17 xcofflink.c
--- xcofflink.c	2002/01/03 22:06:38	1.17
+++ xcofflink.c	2002/01/05 09:57:33
@@ -1,5 +1,5 @@
 /* POWER/PowerPC XCOFF linker support.
-   Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001
+   Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
    Free Software Foundation, Inc.
    Written by Ian Lance Taylor <ian@cygnus.com>, Cygnus Support.
 
@@ -3656,15 +3656,14 @@ _bfd_xcoff_bfd_final_link (abfd, info)
 	{
 	  boolean saw_contents;
 	  int indx;
-	  asection **op, **prev;
+	  asection **op;
 	  file_ptr sofar;
 	  
 	  /* Insert .pad sections before every section which has
              contents and is loaded, if it is preceded by some other
              section which has contents and is loaded.  */
 	  saw_contents = true;
-	  for (op = &abfd->sections, prev = NULL; 
-	       *op != NULL; prev = op, op = &(*op)->next)
+	  for (op = &abfd->sections; *op != NULL; op = &(*op)->next)
 	    {
 	      if (strcmp ((*op)->name, ".pad") == 0)
 		saw_contents = false;
@@ -3675,34 +3674,22 @@ _bfd_xcoff_bfd_final_link (abfd, info)
 		    saw_contents = true;
 		  else
 		    {
-		      asection *n, *hold, **st;
+		      asection *n, **st;
 		      
 		      /* Create a pad section and place it before the section
 			 that needs padding.  This requires unlinking and 
-			 relinking the bfd's sections list. 
-			 
-			 sections = S1
-			 .          S1.next = S2
-			 .          S2.next = S3
-			 .          S3.next = NULL
-			 section_tail = &S3.next */
+			 relinking the bfd's section list.  */
 		      
-		      hold = *op;
 		      st = abfd->section_tail;
-		      
 		      n = bfd_make_section_anyway (abfd, ".pad");
 		      n->flags = SEC_HAS_CONTENTS;
 		      n->alignment_power = 0; 
-		      
-		      if (NULL == prev) 
-			abfd->sections = n;
-		      else
-			(*prev)->next = n;
-		      
-		      n->next = hold;
-		      *st = NULL;
-		      abfd->section_tail = st;
 
+		      BFD_ASSERT (*st == n);
+		      bfd_section_list_remove (abfd, st);
+		      bfd_section_list_insert (abfd, op, n);
+
+		      op = &n->next;
 		      saw_contents = false;
 		    }
 		}
Index: gas/write.c
===================================================================
RCS file: /cvs/src/src/gas/write.c,v
retrieving revision 1.51
diff -u -p -r1.51 write.c
--- write.c	2001/11/28 19:15:14	1.51
+++ write.c	2002/01/05 09:57:59
@@ -1507,22 +1507,18 @@ write_object_file ()
 #ifdef BFD_ASSEMBLER
   /* Remove the sections created by gas for its own purposes.  */
   {
-    asection **seclist, *sec;
+    asection **seclist;
     int i;
 
     seclist = &stdoutput->sections;
-    while (seclist && *seclist)
+    while (*seclist)
       {
-	sec = *seclist;
-	while (sec == reg_section || sec == expr_section)
+	if (*seclist == reg_section || *seclist == expr_section)
 	  {
-	    sec = sec->next;
-	    *seclist = sec;
+	    bfd_section_list_remove (stdoutput, seclist);
 	    stdoutput->section_count--;
-	    if (!sec)
-	      break;
 	  }
-	if (*seclist)
+	else
 	  seclist = &(*seclist)->next;
       }
     i = 0;
Index: gas/config/obj-ecoff.c
===================================================================
RCS file: /cvs/src/src/gas/config/obj-ecoff.c,v
retrieving revision 1.8
diff -u -p -r1.8 obj-ecoff.c
--- obj-ecoff.c	2001/05/03 02:07:02	1.8
+++ obj-ecoff.c	2002/01/05 09:57:59
@@ -106,7 +106,7 @@ ecoff_frob_file ()
   const struct ecoff_debug_swap * const debug_swap
     = &ecoff_backend (stdoutput)->debug_swap;
   bfd_vma addr;
-  asection *sec;
+  asection **sec;
   HDRR *hdr;
   char *buf;
   char *set;
@@ -143,53 +143,39 @@ ecoff_frob_file ()
   };
 #define n_names ((int) (sizeof (names) / sizeof (names[0])))
 
+  /* Sections that match names, order to be straightened out later.  */
+  asection *secs[n_names];
+  int i;
+
   addr = 0;
-  {
-    /* Sections that match names, order to be straightened out later.  */
-    asection *secs[n_names];
-    /* Linked list of sections with non-matching names.  Random ordering.  */
-    asection *other_sections = 0;
-    /* Pointer to next section, since we're destroying the original
-       ordering.  */
-    asection *next;
-
-    int i;
-
-    for (i = 0; i < n_names; i++)
-      secs[i] = 0;
-    for (sec = stdoutput->sections; sec != (asection *) NULL; sec = next)
-      {
-	next = sec->next;
-	for (i = 0; i < n_names; i++)
-	  if (!strcmp (sec->name, names[i]))
-	    {
-	      secs[i] = sec;
-	      break;
-	    }
-	if (i == n_names)
+  for (i = 0; i < n_names; i++)
+    secs[i] = 0;
+
+  for (sec = &stdoutput->sections; *sec != (asection *) NULL; )
+    {
+      for (i = 0; i < n_names; i++)
+	if (!strcmp ((*sec)->name, names[i]))
 	  {
-	    bfd_set_section_vma (stdoutput, sec, addr);
-	    addr += bfd_section_size (stdoutput, sec);
-	    sec->next = other_sections;
-	    other_sections = sec;
+	    secs[i] = *sec;
+	    bfd_section_list_remove (stdoutput, sec);
+	    break;
 	  }
-      }
-    for (i = 0; i < n_names; i++)
-      if (secs[i])
+      if (i == n_names)
 	{
-	  sec = secs[i];
-	  bfd_set_section_vma (stdoutput, sec, addr);
-	  addr += bfd_section_size (stdoutput, sec);
+	  bfd_set_section_vma (stdoutput, *sec, addr);
+	  addr += bfd_section_size (stdoutput, *sec);
+	  sec = &(*sec)->next;
 	}
-    for (i = n_names - 1; i >= 0; i--)
-      if (secs[i])
-	{
-	  sec = secs[i];
-	  sec->next = other_sections;
-	  other_sections = sec;
-	}
-    stdoutput->sections = other_sections;
-  }
+    }
+  for (i = 0; i < n_names; i++)
+    if (secs[i])
+      {
+	bfd_set_section_vma (stdoutput, secs[i], addr);
+	addr += bfd_section_size (stdoutput, secs[i]);
+      }
+  for (i = n_names - 1; i >= 0; i--)
+    if (secs[i])
+      bfd_section_list_insert (stdoutput, &stdoutput->sections, secs[i]);
 
   /* Build the ECOFF debugging information.  */
   assert (ecoff_data (stdoutput) != 0);
Index: gas/config/tc-mmix.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-mmix.c,v
retrieving revision 1.2
diff -u -p -r1.2 tc-mmix.c
--- tc-mmix.c	2001/11/15 21:28:57	1.2
+++ tc-mmix.c	2002/01/05 09:58:07
@@ -3629,14 +3629,12 @@ mmix_frob_file ()
       if (bfd_get_section_flags (stdoutput, real_reg_section) & SEC_HAS_CONTENTS)
 	as_fatal (_("register section has contents\n"));
 
-      /* FIXME: This does not seem like the proper way to kill a section,
-	 but it's the way it's done elsewhere, like elf64-alpha.c.  */
       /* Really remove the section.  */
       for (secpp = &stdoutput->sections;
 	   *secpp != real_reg_section;
 	   secpp = &(*secpp)->next)
 	;
-      *secpp = (*secpp)->next;
+      bfd_section_list_remove (stdoutput, secpp);
       --stdoutput->section_count;
     }
 
Index: ld/emultempl/elf32.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
retrieving revision 1.69
diff -u -p -r1.69 elf32.em
--- elf32.em	2001/12/17 00:40:53	1.69
+++ elf32.em	2002/01/05 09:58:27
@@ -1270,18 +1270,13 @@ gld${EMULATION_NAME}_place_orphan (file,
 
       if (place->section != NULL)
 	{
-	  /*  Unlink the section.  */
+	  /* Unlink the section.  */
 	  for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
 	    ;
-	  *pps = snew->next;
-	  if (snew->next == NULL)
-	    snew->owner->section_tail = pps;
+	  bfd_section_list_remove (output_bfd, pps);
 
 	  /* Now tack it on to the "place->os" section list.  */
-	  snew->next = *place->section;
-	  *place->section = snew;
-	  if (snew->next == NULL)
-	    snew->owner->section_tail = &snew->next;
+	  bfd_section_list_insert (output_bfd, place->section, snew);
 	}
 
       /* Save the end of this list.  Further ophans of this type will
Index: ld/emultempl/mmo.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/mmo.em,v
retrieving revision 1.2
diff -u -p -r1.2 mmo.em
--- mmo.em	2001/12/17 00:40:53	1.2
+++ mmo.em	2002/01/05 09:58:27
@@ -159,18 +159,13 @@ mmo_place_orphan (file, s)
 	/* Put orphans after the first section on the list.  */
 	place->section = &bfd_section->next;
 
-      /*  Unlink the section.  */
+      /* Unlink the section.  */
       for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
 	;
-      *pps = snew->next;
-      if (snew->next == NULL)
-	snew->owner->section_tail = pps;
+      bfd_section_list_remove (output_bfd, pps);
 
       /* Now tack it on to the "place->os" section list.  */
-      snew->next = *place->section;
-      *place->section = snew;
-      if (snew->next == NULL)
-	snew->owner->section_tail = &snew->next;
+      bfd_section_list_insert (output_bfd, place->section, snew);
     }
   place->section = &snew->next;	/* Save the end of this list.  */
 
Index: ld/emultempl/pe.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pe.em,v
retrieving revision 1.57
diff -u -p -r1.57 pe.em
--- pe.em	2001/12/17 00:40:53	1.57
+++ pe.em	2002/01/05 09:58:28
@@ -1685,20 +1685,15 @@ gld_${EMULATION_NAME}_place_orphan (file
 
 	  if (place->section != NULL)
 	    {
-	      /*  Unlink the section.  */
+	      /* Unlink the section.  */
 	      for (pps = &output_bfd->sections;
 		   *pps != snew;
 		   pps = &(*pps)->next)
 		;
-	      *pps = snew->next;
-	      if (snew->next == NULL)
-		snew->owner->section_tail = pps;
+	      bfd_section_list_remove (output_bfd, pps);
 
 	      /* Now tack it on to the "place->os" section list.  */
-	      snew->next = *place->section;
-	      *place->section = snew;
-	      if (snew->next == NULL)
-		snew->owner->section_tail = &snew->next;
+	      bfd_section_list_insert (output_bfd, place->section, snew);
 	    }
 
 	  /* Save the end of this list.  Further ophans of this type will


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