diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 4e6d1617af..7c6e3cb9d4 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -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 . + * 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. diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 6e942a5b83..5643c7a05c 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -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"); diff --git a/bfd/elf32-sparc.c b/bfd/elf32-sparc.c index 4256878a7d..2733a1e261 100644 --- a/bfd/elf32-sparc.c +++ b/bfd/elf32-sparc.c @@ -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) diff --git a/bfd/elfcode.h b/bfd/elfcode.h index 85d5fd93f1..8286d4e8fb 100644 --- a/bfd/elfcode.h +++ b/bfd/elfcode.h @@ -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))