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.
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.
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
/* 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");
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");
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)
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:
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;
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
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
{
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))
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))