Preliminary support for generating shared libraries, from Eric
authorIan Lance Taylor <ian@airs.com>
Thu, 23 Jun 1994 21:36:03 +0000 (21:36 +0000)
committerIan Lance Taylor <ian@airs.com>
Thu, 23 Jun 1994 21:36:03 +0000 (21:36 +0000)
Youngdale <ericy@cais.cais.com>.
* elfcode.h (prep_headers): If DYNAMIC, set e_type to ET_DYN.
(elf_link_add_object_symbols): If generating a shared library,
create dynamic sections for first input BFD with the right format.
(elf_link_create_dynamic_sections): Don't create .interp section
if creating a shared library.
(elf_link_input_bfd): Skip dynamic sections in input file.
(elf_bfd_final_link): If creating a shared library, it's OK for
dynobj to have sections which are not SEC_IN_MEMORY.
* elf32-i386.c (elf_i386_size_dynamic_sections): Only set .interp
section if not creating a shared library.
* elf32-sparc.c (elf_sparc_size_dynamic_sections): Likewise.

bfd/ChangeLog
bfd/elf32-i386.c
bfd/elf32-sparc.c
bfd/elfcode.h

index 4e6d161..7c6e3cb 100644 (file)
@@ -1,5 +1,19 @@
 Thu Jun 23 15:31:28 1994  Ian Lance Taylor  (ian@sanguine.cygnus.com)
 
+       Preliminary support for generating shared libraries, from Eric
+       Youngdale <ericy@cais.cais.com>.
+       * elfcode.h (prep_headers): If DYNAMIC, set e_type to ET_DYN.
+       (elf_link_add_object_symbols): If generating a shared library,
+       create dynamic sections for first input BFD with the right format.
+       (elf_link_create_dynamic_sections): Don't create .interp section
+       if creating a shared library.
+       (elf_link_input_bfd): Skip dynamic sections in input file.
+       (elf_bfd_final_link): If creating a shared library, it's OK for
+       dynobj to have sections which are not SEC_IN_MEMORY.
+       * elf32-i386.c (elf_i386_size_dynamic_sections): Only set .interp
+       section if not creating a shared library.
+       * elf32-sparc.c (elf_sparc_size_dynamic_sections): Likewise.
+
        * elfcode.h (elf_object_p): Don't set DYNAMIC just because there
        is an SHT_DYNAMIC section.
 
index 6e942a5..5643c7a 100644 (file)
@@ -488,10 +488,13 @@ elf_i386_size_dynamic_sections (output_bfd, info)
   BFD_ASSERT (dynobj != NULL);
 
   /* Set the contents of the .interp section to the interpreter.  */
-  s = bfd_get_section_by_name (dynobj, ".interp");
-  BFD_ASSERT (s != NULL);
-  s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
-  s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+  if (! info->shared)
+    {
+      s = bfd_get_section_by_name (dynobj, ".interp");
+      BFD_ASSERT (s != NULL);
+      s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
+      s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+    }
 
   /* The adjust_dynamic_symbol entry point has determined the sizes of
      the various dynamic sections.  Allocate some memory for them to
@@ -505,8 +508,10 @@ elf_i386_size_dynamic_sections (output_bfd, info)
   /* Add some entries to the .dynamic section.  We fill in the values
      later, in elf_i386_finish_dynamic_sections, but we must add the
      entries now so that we get the correct size for the .dynamic
-     section.  */
-  if (! bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0))
+     section.  The DT_DEBUG entry is filled in by the dynamic linker
+     and used by the debugger.  */
+  if (! bfd_elf32_add_dynamic_entry (info, DT_DEBUG, 0)
+      || ! bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0))
     return false;
 
   s = bfd_get_section_by_name (dynobj, ".plt");
index 4256878..2733a1e 100644 (file)
@@ -472,10 +472,13 @@ elf32_sparc_size_dynamic_sections (output_bfd, info)
   BFD_ASSERT (dynobj != NULL);
 
   /* Set the contents of the .interp section to the interpreter.  */
-  s = bfd_get_section_by_name (dynobj, ".interp");
-  BFD_ASSERT (s != NULL);
-  s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
-  s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+  if (! info->shared)
+    {
+      s = bfd_get_section_by_name (dynobj, ".interp");
+      BFD_ASSERT (s != NULL);
+      s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
+      s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+    }
 
   /* Make space for the trailing nop in .plt.  */
   s = bfd_get_section_by_name (dynobj, ".plt");
@@ -492,10 +495,12 @@ elf32_sparc_size_dynamic_sections (output_bfd, info)
     return false;
 
   /* Add some entries to the .dynamic section.  We fill in the values
-     later, in elf32_sparc_finish_dynamic_sections, but we must add the
-     entries now so that we get the correct size for the .dynamic
-     section.  */
-  if (! bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0)
+     later, in elf32_sparc_finish_dynamic_sections, but we must add
+     the entries now so that we get the correct size for the .dynamic
+     section.  The DT_DEBUG entry is filled in by the dynamic linker
+     and used by the debugger.  */
+  if (! bfd_elf32_add_dynamic_entry (info, DT_DEBUG, 0)
+      || ! bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0)
       || ! bfd_elf32_add_dynamic_entry (info, DT_PLTRELSZ, 0)
       || ! bfd_elf32_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
       || ! bfd_elf32_add_dynamic_entry (info, DT_JMPREL, 0)
index 85d5fd9..8286d4e 100644 (file)
@@ -2125,7 +2125,13 @@ prep_headers (abfd)
   for (count = EI_PAD; count < EI_NIDENT; count++)
     i_ehdrp->e_ident[count] = 0;
 
-  i_ehdrp->e_type = (abfd->flags & EXEC_P) ? ET_EXEC : ET_REL;
+  if ((abfd->flags & DYNAMIC) != 0)
+    i_ehdrp->e_type = ET_DYN;
+  else if ((abfd->flags & EXEC_P) != 0)
+    i_ehdrp->e_type = ET_EXEC;
+  else
+    i_ehdrp->e_type = ET_REL;
+
   switch (bfd_get_arch (abfd))
     {
     case bfd_arch_unknown:
@@ -4131,7 +4137,23 @@ elf_link_add_object_symbols (abfd, info)
   elf_sym_hashes (abfd) = sym_hash;
 
   if (elf_elfheader (abfd)->e_type != ET_DYN)
-    dynamic = false;
+    {
+      dynamic = false;
+
+      /* If we are creating a shared library, create all the dynamic
+         sections immediately.  We need to attach them to something,
+         so we attach them to this BFD, provided it is the right
+         format.  FIXME: If there are no input BFD's of the same
+         format as the output, we can't make a shared library.  */
+      if (info->shared
+         && elf_hash_table (info)->dynobj == NULL
+         && abfd->xvec == info->hash->creator)
+       {
+         if (! elf_link_create_dynamic_sections (abfd, info))
+           goto error_return;
+         elf_hash_table (info)->dynobj = abfd;
+       }
+    }
   else
     {
       asection *s;
@@ -4571,10 +4593,15 @@ elf_link_create_dynamic_sections (abfd, info)
      sections.  */
   flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY;
 
-  s = bfd_make_section (abfd, ".interp");
-  if (s == NULL
-      || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY))
-    return false;
+  /* A dynamically linked executable has a .interp section, but a
+     shared library does not.  */
+  if (! info->shared)
+    {
+      s = bfd_make_section (abfd, ".interp");
+      if (s == NULL
+         || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY))
+       return false;
+    }
 
   s = bfd_make_section (abfd, ".dynamic");
   if (s == NULL
@@ -4755,7 +4782,7 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, info, sinterpptr)
     return true;
 
   *sinterpptr = bfd_get_section_by_name (dynobj, ".interp");
-  BFD_ASSERT (*sinterpptr != NULL);
+  BFD_ASSERT (*sinterpptr != NULL || info->shared);
 
   /* Set the size of the .dynsym and .hash sections.  We counted the
      number of dynamic symbols in elf_link_add_object_symbols.  We
@@ -5515,7 +5542,11 @@ elf_bfd_final_link (abfd, info)
        {
          if ((o->flags & SEC_HAS_CONTENTS) == 0)
            continue;
-         BFD_ASSERT ((o->flags & SEC_IN_MEMORY) != 0);
+         if ((o->flags & SEC_IN_MEMORY) == 0)
+           {
+             BFD_ASSERT (info->shared);
+             continue;
+           }
          if (! bfd_set_section_contents (abfd, o->output_section,
                                          o->contents, o->output_offset,
                                          o->_raw_size))
@@ -5965,6 +5996,14 @@ elf_link_input_bfd (finfo, input_bfd)
       if ((o->flags & SEC_HAS_CONTENTS) == 0)
        continue;
 
+      if ((o->flags & SEC_IN_MEMORY) != 0
+         && input_bfd == elf_hash_table (finfo->info)->dynobj)
+       {
+         /* Section was created by elf_link_create_dynamic_sections.
+             FIXME: This test is fragile.  */
+         continue;
+       }
+
       /* Read the contents of the section.  */
       if (! bfd_get_section_contents (input_bfd, o, finfo->contents,
                                      (file_ptr) 0, o->_raw_size))