+2000-02-13  Ian Lance Taylor  <ian@zembu.com>
+
+       * section.c (_bfd_strip_section_from_output): Add info parameter.
+       If it passed as non-NULL, use it to check whether any input BFD
+       has an input section which uses this output section.  Change all
+       callers.
+       * bfd-in2.h: Rebuild.
+
+       * bfd-in.h: Move declarations of bfd_get_elf_phdr_upper_bound and
+       bfd_get_elf_phdrs in from bfd-in2.h, correcting patch of
+       1999-11-29.
+       * bfd-in2.h: Rebuild.
+
 2000-02-10  Timothy Wall  <twall@cygnus.com>
 
        * coffswap.h (coff_swap_sym_in): Add hook SWAP_SYM_IN_POST to
 
 extern void bfd_elf_set_dt_needed_name PARAMS ((bfd *, const char *));
 extern const char *bfd_elf_get_dt_soname PARAMS ((bfd *));
 
+/* Return an upper bound on the number of bytes required to store a
+   copy of ABFD's program header table entries.  Return -1 if an error
+   occurs; bfd_get_error will return an appropriate code.  */
+extern long bfd_get_elf_phdr_upper_bound PARAMS ((bfd *abfd));
+
+/* Copy ABFD's program header table entries to *PHDRS.  The entries
+   will be stored as an array of Elf_Internal_Phdr structures, as
+   defined in include/elf/internal.h.  To find out how large the
+   buffer needs to be, call bfd_get_elf_phdr_upper_bound.
+
+   Return the number of program header table entries read, or -1 if an
+   error occurs; bfd_get_error will return an appropriate code.  */
+extern int bfd_get_elf_phdrs PARAMS ((bfd *abfd, void *phdrs));
+
 /* SunOS shared library support routines for the linker.  */
 
 extern struct bfd_link_needed_list *bfd_sunos_get_needed_list
 
 extern void bfd_elf_set_dt_needed_name PARAMS ((bfd *, const char *));
 extern const char *bfd_elf_get_dt_soname PARAMS ((bfd *));
 
+/* Return an upper bound on the number of bytes required to store a
+   copy of ABFD's program header table entries.  Return -1 if an error
+   occurs; bfd_get_error will return an appropriate code.  */
+extern long bfd_get_elf_phdr_upper_bound PARAMS ((bfd *abfd));
+
+/* Copy ABFD's program header table entries to *PHDRS.  The entries
+   will be stored as an array of Elf_Internal_Phdr structures, as
+   defined in include/elf/internal.h.  To find out how large the
+   buffer needs to be, call bfd_get_elf_phdr_upper_bound.
+
+   Return the number of program header table entries read, or -1 if an
+   error occurs; bfd_get_error will return an appropriate code.  */
+extern int bfd_get_elf_phdrs PARAMS ((bfd *abfd, void *phdrs));
+
 /* SunOS shared library support routines for the linker.  */
 
 extern struct bfd_link_needed_list *bfd_sunos_get_needed_list
            target).  In most cases, if this was going to start at the
            100th octet (8-bit quantity) in the output section, this value
            would be 100.  However, if the target byte size is 16 bits
-           (bfd_octets_per_byte is "2"), this value would be 50. */ 
+           (bfd_octets_per_byte is "2"), this value would be 50. */
 
    bfd_vma output_offset;
 
                (ibfd, isection, obfd, osection))
 void 
 _bfd_strip_section_from_output
- PARAMS ((asection *section));
+ PARAMS ((struct bfd_link_info *info, asection *section));
 
 enum bfd_architecture 
 {
   bfd_arch_mn10200,    /* Matsushita MN10200 */
   bfd_arch_mn10300,    /* Matsushita MN10300 */
 #define bfd_mach_mn10300               300
-#define bfd_mach_am33               330
+#define bfd_mach_am33          330
   bfd_arch_fr30,
 #define bfd_mach_fr30          0x46523330
   bfd_arch_mcore,
 
 int 
 bfd_arch_mach_octets_per_byte PARAMS ((enum bfd_architecture arch,
-                                       unsigned long machine));
+    unsigned long machine));
 
 typedef enum bfd_reloc_status
 {
 int 
 bfd_decode_symclass PARAMS ((asymbol *symbol));
 
-boolean
-bfd_is_undefined_symclass PARAMS ((int symclass));
+boolean 
+bfd_is_undefined_symclass  PARAMS ((int symclass));
 
 void 
 bfd_symbol_info PARAMS ((asymbol *symbol, symbol_info *ret));
 CONST char *
 bfd_format_string PARAMS ((bfd_format format));
 
-
-/* Return an upper bound on the number of bytes required to store a
-   copy of ABFD's program header table entries.  Return -1 if an error
-   occurs; bfd_get_error will return an appropriate code.  */
-extern long bfd_get_elf_phdr_upper_bound PARAMS ((bfd *abfd));
-
-/* Copy ABFD's program header table entries to *PHDRS.  The entries
-   will be stored as an array of Elf_Internal_Phdr structures, as
-   defined in include/elf/internal.h.  To find out how large the
-   buffer needs to be, call bfd_get_elf_phdr_upper_bound.
-
-   Return the number of program header table entries read, or -1 if an
-   error occurs; bfd_get_error will return an appropriate code.  */
-extern int bfd_get_elf_phdrs PARAMS ((bfd *abfd, void *phdrs));
-
-
 #ifdef __cplusplus
 }
 #endif
 
 
       if (strip)
        {
-         _bfd_strip_section_from_output (s);
+         _bfd_strip_section_from_output (info, s);
          continue;
        }
 
 
 
       if (strip)
        {
-         _bfd_strip_section_from_output (s);
+         _bfd_strip_section_from_output (info, s);
          continue;
        }
 
 
 
       if (strip)
        {
-         _bfd_strip_section_from_output (s);
+         _bfd_strip_section_from_output (info, s);
          continue;
        }
 
 
 
       if (strip)
        {
-         _bfd_strip_section_from_output (s);
+         _bfd_strip_section_from_output (info, s);
          continue;
        }
 
 
 
       if (strip)
        {
-         _bfd_strip_section_from_output (s);
+         _bfd_strip_section_from_output (info, s);
          continue;
        }
 
 
        }
 
       if (strip)
-       _bfd_strip_section_from_output (s);
+       _bfd_strip_section_from_output (info, s);
       else
        {
          /* Allocate memory for the section contents.  */
 
 
       if (strip)
        {
-         _bfd_strip_section_from_output (s);
+         _bfd_strip_section_from_output (info, s);
          continue;
        }
 
 
       verdefs = asvinfo.verdefs;
 
       if (verdefs == NULL)
-       _bfd_strip_section_from_output (s);
+       _bfd_strip_section_from_output (info, s);
       else
        {
          unsigned int cdefs;
                                (PTR) &sinfo);
 
        if (elf_tdata (output_bfd)->verref == NULL)
-         _bfd_strip_section_from_output (s);
+         _bfd_strip_section_from_output (info, s);
        else
          {
            Elf_Internal_Verneed *t;
       if (dynsymcount == 0
          || (verdefs == NULL && elf_tdata (output_bfd)->verref == NULL))
        {
-         _bfd_strip_section_from_output (s);
+         _bfd_strip_section_from_output (info, s);
          /* The DYNSYMCOUNT might have changed if we were going to
             output a dynamic symbol table entry for S.  */
          dynsymcount = _bfd_elf_link_renumber_dynsyms (output_bfd, info);
 
 
 SYNOPSIS
        void _bfd_strip_section_from_output
-       (asection *section);
+       (struct bfd_link_info *info, asection *section);
 
 DESCRIPTION
-       Remove @var{section} from the output.  If the output section becomes
-       empty, remove it from the output bfd.
+       Remove @var{section} from the output.  If the output section
+       becomes empty, remove it from the output bfd.  @var{info} may
+       be NULL; if it is not, it is used to decide whether the output
+       section is empty.
 */
 void
-_bfd_strip_section_from_output (s)
+_bfd_strip_section_from_output (info, s)
+     struct bfd_link_info *info;
      asection *s;
 {
   asection **spp, *os;
   struct bfd_link_order *p, *pp;
+  boolean keep_os;
 
-  /* Excise the input section from the link order.  */
+  /* Excise the input section from the link order.
+
+     FIXME: For all calls that I can see to this function, the link
+     orders have not yet been set up.  So why are we checking them? --
+     Ian */
   os = s->output_section;
   for (p = os->link_order_head, pp = NULL; p != NULL; pp = p, p = p->next)
     if (p->type == bfd_indirect_link_order
        break;
       }
 
+  keep_os = os->link_order_head != NULL;
+
+  if (! keep_os && info != NULL)
+    {
+      bfd *abfd;
+      for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
+       {
+         asection *is;
+         for (is = abfd->sections; is != NULL; is = is->next)
+           {
+             if (is != s && is->output_section == os)
+               break;
+           }
+         if (is != NULL)
+           break;
+       }
+      if (abfd != NULL)
+       keep_os = true;
+    }
+
   /* If the output section is empty, remove it too.  Careful about sections
      that have been discarded in the link script -- they are mapped to 
      bfd_abs_section, which has no owner.  */
-  if (!os->link_order_head && os->owner)
+  if (!keep_os && os->owner != NULL)
     {
       for (spp = &os->owner->sections; *spp; spp = &(*spp)->next)
        if (*spp == os)