diff options
author | Niklas Hallqvist <niklas@cvs.openbsd.org> | 1996-09-04 19:11:21 +0000 |
---|---|---|
committer | Niklas Hallqvist <niklas@cvs.openbsd.org> | 1996-09-04 19:11:21 +0000 |
commit | c3c8d76890b592bf5acc1a9b7faeabd9b829dd71 (patch) | |
tree | 6358a23d0df9de73b6d5d6d3a75545ff35f05b47 /gnu/usr.bin/binutils/bfd/elflink.h | |
parent | 4ba440a6e788da3a64fa29b782c37150a3f5cc18 (diff) |
Merge the Cygnus 960904 sources
Diffstat (limited to 'gnu/usr.bin/binutils/bfd/elflink.h')
-rw-r--r-- | gnu/usr.bin/binutils/bfd/elflink.h | 105 |
1 files changed, 73 insertions, 32 deletions
diff --git a/gnu/usr.bin/binutils/bfd/elflink.h b/gnu/usr.bin/binutils/bfd/elflink.h index 7fb51a7bb4e..6326121dcd7 100644 --- a/gnu/usr.bin/binutils/bfd/elflink.h +++ b/gnu/usr.bin/binutils/bfd/elflink.h @@ -23,8 +23,6 @@ static boolean elf_link_add_object_symbols PARAMS ((bfd *, struct bfd_link_info *)); static boolean elf_link_add_archive_symbols PARAMS ((bfd *, struct bfd_link_info *)); -static Elf_Internal_Rela *elf_link_read_relocs - PARAMS ((bfd *, asection *, PTR, Elf_Internal_Rela *, boolean)); static boolean elf_export_symbol PARAMS ((struct elf_link_hash_entry *, PTR)); static boolean elf_adjust_dynamic_symbol @@ -679,17 +677,25 @@ elf_link_add_object_symbols (abfd, info) by some other object. If it has, we want to use the existing definition, and we do not want to report a multiple symbol definition error; we do this by - clobbering sec to be bfd_und_section_ptr. */ + clobbering sec to be bfd_und_section_ptr. We treat a + common symbol as a definition if the symbol in the shared + library is a function, since common symbols always + represent variables; this can cause confusion in + principle, but any such confusion would seem to indicate + an erroneous program or shared library. */ if (dynamic && definition) { if (h->root.type == bfd_link_hash_defined || h->root.type == bfd_link_hash_defweak || (h->root.type == bfd_link_hash_common - && bind == STB_WEAK)) + && (bind == STB_WEAK + || ELF_ST_TYPE (sym.st_info) == STT_FUNC))) { sec = bfd_und_section_ptr; definition = false; size_change_ok = true; + if (h->root.type == bfd_link_hash_common) + type_change_ok = true; } } @@ -700,7 +706,10 @@ elf_link_add_object_symbols (abfd, info) objects, even if they are defined after the dynamic object in the link. */ if (! dynamic - && definition + && (definition + || (bfd_is_com_section (sec) + && (h->root.type == bfd_link_hash_defweak + || h->type == STT_FUNC))) && (h->root.type == bfd_link_hash_defined || h->root.type == bfd_link_hash_defweak) && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0 @@ -715,6 +724,8 @@ elf_link_add_object_symbols (abfd, info) h->root.type = bfd_link_hash_undefined; h->root.u.undef.abfd = h->root.u.def.section->owner; size_change_ok = true; + if (bfd_is_com_section (sec)) + type_change_ok = true; } } @@ -948,9 +959,10 @@ elf_link_add_object_symbols (abfd, info) if ((o->flags & SEC_ALLOC) == 0) continue; - internal_relocs = elf_link_read_relocs (abfd, o, (PTR) NULL, - (Elf_Internal_Rela *) NULL, - info->keep_memory); + internal_relocs = (NAME(_bfd_elf,link_read_relocs) + (abfd, o, (PTR) NULL, + (Elf_Internal_Rela *) NULL, + info->keep_memory)); if (internal_relocs == NULL) goto error_return; @@ -1150,8 +1162,9 @@ elf_add_dynamic_entry (info, tag, val) value is allocated using either malloc or bfd_alloc, according to the KEEP_MEMORY argument. */ -static Elf_Internal_Rela * -elf_link_read_relocs (abfd, o, external_relocs, internal_relocs, keep_memory) +Elf_Internal_Rela * +NAME(_bfd_elf,link_read_relocs) (abfd, o, external_relocs, internal_relocs, + keep_memory) bfd *abfd; asection *o; PTR external_relocs; @@ -1896,7 +1909,8 @@ elf_bfd_final_link (abfd, info) zero. This is done in elf_fake_sections as well, but forcing the VMA to 0 here will ensure that relocs against these sections are handled correctly. */ - if ((o->flags & SEC_ALLOC) == 0) + if ((o->flags & SEC_ALLOC) == 0 + && ! o->user_set_vma) o->vma = 0; } @@ -2714,6 +2728,7 @@ elf_link_input_bfd (finfo, input_bfd) Elf_Internal_Shdr *symtab_hdr; size_t locsymcount; size_t extsymoff; + Elf_External_Sym *external_syms; Elf_External_Sym *esym; Elf_External_Sym *esymend; Elf_Internal_Sym *isym; @@ -2744,16 +2759,23 @@ elf_link_input_bfd (finfo, input_bfd) } /* Read the local symbols. */ - if (locsymcount > 0 - && (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0 - || (bfd_read (finfo->external_syms, sizeof (Elf_External_Sym), + if (symtab_hdr->contents != NULL) + external_syms = (Elf_External_Sym *) symtab_hdr->contents; + else if (locsymcount == 0) + external_syms = NULL; + else + { + external_syms = finfo->external_syms; + if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0 + || (bfd_read (external_syms, sizeof (Elf_External_Sym), locsymcount, input_bfd) - != locsymcount * sizeof (Elf_External_Sym)))) - return false; + != locsymcount * sizeof (Elf_External_Sym))) + return false; + } /* Swap in the local symbols and write out the ones which we know are going into the output file. */ - esym = finfo->external_syms; + esym = external_syms; esymend = esym + locsymcount; isym = finfo->internal_syms; pindex = finfo->indices; @@ -2793,7 +2815,7 @@ elf_link_input_bfd (finfo, input_bfd) *ppsection = isec; /* Don't output the first, undefined, symbol. */ - if (esym == finfo->external_syms) + if (esym == external_syms) continue; /* If we are stripping all symbols, we don't want to output this @@ -2859,6 +2881,8 @@ elf_link_input_bfd (finfo, input_bfd) /* Relocate the contents of each section. */ for (o = input_bfd->sections; o != NULL; o = o->next) { + bfd_byte *contents; + if (! o->linker_mark) { /* This section was omitted from the link. */ @@ -2877,20 +2901,28 @@ elf_link_input_bfd (finfo, input_bfd) continue; } - /* Read the contents of the section. */ - if (! bfd_get_section_contents (input_bfd, o, finfo->contents, - (file_ptr) 0, o->_raw_size)) - return false; + /* Get the contents of the section. They have been cached by a + relaxation routine. Note that o is a section in an input + file, so the contents field will not have been set by any of + the routines which work on output files. */ + if (elf_section_data (o)->this_hdr.contents != NULL) + contents = elf_section_data (o)->this_hdr.contents; + else + { + contents = finfo->contents; + if (! bfd_get_section_contents (input_bfd, o, contents, + (file_ptr) 0, o->_raw_size)) + return false; + } if ((o->flags & SEC_RELOC) != 0) { Elf_Internal_Rela *internal_relocs; /* Get the swapped relocs. */ - internal_relocs = elf_link_read_relocs (input_bfd, o, - finfo->external_relocs, - finfo->internal_relocs, - false); + internal_relocs = (NAME(_bfd_elf,link_read_relocs) + (input_bfd, o, finfo->external_relocs, + finfo->internal_relocs, false)); if (internal_relocs == NULL && o->reloc_count > 0) return false; @@ -2916,8 +2948,7 @@ elf_link_input_bfd (finfo, input_bfd) the addend to be adjusted. */ if (! (*relocate_section) (output_bfd, finfo->info, - input_bfd, o, - finfo->contents, + input_bfd, o, contents, internal_relocs, finfo->internal_syms, finfo->sections)) @@ -3090,7 +3121,7 @@ elf_link_input_bfd (finfo, input_bfd) if (elf_section_data (o)->stab_info == NULL) { if (! bfd_set_section_contents (output_bfd, o->output_section, - finfo->contents, o->output_offset, + contents, o->output_offset, (o->_cooked_size != 0 ? o->_cooked_size : o->_raw_size))) @@ -3100,7 +3131,7 @@ elf_link_input_bfd (finfo, input_bfd) { if (! _bfd_write_section_stabs (output_bfd, o, &elf_section_data (o)->stab_info, - finfo->contents)) + contents)) return false; } } @@ -3360,15 +3391,25 @@ elf_create_pointer_linker_section (abfd, info, lsect, h, rel) linker_section_ptr->written_address_p = false; *ptr_linker_section_ptr = linker_section_ptr; +#if 0 if (lsect->hole_size && lsect->hole_offset < lsect->max_hole_offset) { - linker_section_ptr->offset = lsect->section->_raw_size - lsect->hole_size; + linker_section_ptr->offset = lsect->section->_raw_size - lsect->hole_size + (ARCH_SIZE / 8); lsect->hole_offset += ARCH_SIZE / 8; lsect->sym_offset += ARCH_SIZE / 8; if (lsect->sym_hash) /* Bump up symbol value if needed */ - lsect->sym_hash->root.u.def.value += ARCH_SIZE / 8; + { + lsect->sym_hash->root.u.def.value += ARCH_SIZE / 8; +#ifdef DEBUG + fprintf (stderr, "Bump up %s by %ld, current value = %ld\n", + lsect->sym_hash->root.root.string, + (long)ARCH_SIZE / 8, + (long)lsect->sym_hash->root.u.def.value); +#endif + } } else +#endif linker_section_ptr->offset = lsect->section->_raw_size; lsect->section->_raw_size += ARCH_SIZE / 8; |