diff options
author | Niklas Hallqvist <niklas@cvs.openbsd.org> | 1996-06-10 10:55:58 +0000 |
---|---|---|
committer | Niklas Hallqvist <niklas@cvs.openbsd.org> | 1996-06-10 10:55:58 +0000 |
commit | a7e831079363e3bb45f3172f6e59ba48e335682b (patch) | |
tree | ee4324eac9a9d66f189fab60498ec42b8226b7fc /gnu/usr.bin/binutils/bfd/elf32-i386.c | |
parent | 467cb0a471d13c5186a6ee166e60b47c30da64e9 (diff) |
Bring Cygnus versions into the trunk, keeping our local patches
Diffstat (limited to 'gnu/usr.bin/binutils/bfd/elf32-i386.c')
-rw-r--r-- | gnu/usr.bin/binutils/bfd/elf32-i386.c | 97 |
1 files changed, 59 insertions, 38 deletions
diff --git a/gnu/usr.bin/binutils/bfd/elf32-i386.c b/gnu/usr.bin/binutils/bfd/elf32-i386.c index ffa95d8b7a4..3b39aac9191 100644 --- a/gnu/usr.bin/binutils/bfd/elf32-i386.c +++ b/gnu/usr.bin/binutils/bfd/elf32-i386.c @@ -1,5 +1,5 @@ /* Intel 80386/80486-specific support for 32-bit ELF - Copyright 1993, 1994, 1995 Free Software Foundation, Inc. + Copyright 1993, 1994, 1995, 1996 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -363,10 +363,7 @@ elf_i386_check_relocs (abfd, info, sec, relocs) size = symtab_hdr->sh_info * sizeof (bfd_vma); local_got_offsets = (bfd_vma *) bfd_alloc (abfd, size); if (local_got_offsets == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } + return false; elf_local_got_offsets (abfd) = local_got_offsets; for (i = 0; i < symtab_hdr->sh_info; i++) local_got_offsets[i] = (bfd_vma) -1; @@ -394,22 +391,16 @@ elf_i386_check_relocs (abfd, info, sec, relocs) case R_386_PLT32: /* This symbol requires a procedure linkage table entry. We actually build the entry in adjust_dynamic_symbol, - because this might be a case of linking PIC code without - linking in any dynamic objects, in which case we don't - need to generate a procedure linkage table after all. */ - + because this might be a case of linking PIC code which is + never referenced by a dynamic object, in which case we + don't need to generate a procedure linkage table entry + after all. */ + /* If this is a local symbol, we resolve it directly without creating a procedure linkage table entry. */ if (h == NULL) continue; - /* Make sure this symbol is output as a dynamic symbol. */ - if (h->dynindx == -1) - { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) - return false; - } - h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; break; @@ -501,17 +492,26 @@ elf_i386_adjust_dynamic_symbol (info, h) if (h->type == STT_FUNC || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0) { - if (! elf_hash_table (info)->dynamic_sections_created) + if (! info->shared + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0 + && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0) { /* This case can occur if we saw a PLT32 reloc in an input - file, but none of the input files were dynamic objects. - In such a case, we don't actually need to build a - procedure linkage table, and we can just do a PC32 reloc - instead. */ + file, but the symbol was never referred to by a dynamic + object. In such a case, we don't actually need to build + a procedure linkage table, and we can just do a PC32 + reloc instead. */ BFD_ASSERT ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0); return true; } + /* Make sure this symbol is output as a dynamic symbol. */ + if (h->dynindx == -1) + { + if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + return false; + } + s = bfd_get_section_by_name (dynobj, ".plt"); BFD_ASSERT (s != NULL); @@ -725,14 +725,19 @@ elf_i386_size_dynamic_sections (output_bfd, info) /* Remember whether there are any reloc sections other than .rel.plt. */ if (strcmp (name, ".rel.plt") != 0) - relocs = true; - - /* If this relocation section applies to a read only - section, then we probably need a DT_TEXTREL entry. */ - target = bfd_get_section_by_name (output_bfd, name + 4); - if (target != NULL - && (target->flags & SEC_READONLY) != 0) - reltext = true; + { + relocs = true; + + /* If this relocation section applies to a read only + section, then we probably need a DT_TEXTREL + entry. The entries in the .rel.plt section + really apply to the .got section, which we + created ourselves and so know is not readonly. */ + target = bfd_get_section_by_name (output_bfd, name + 4); + if (target != NULL + && (target->flags & SEC_READONLY) != 0) + reltext = true; + } /* We use the reloc_count field as a counter if we need to copy relocs into the output file. */ @@ -762,10 +767,7 @@ elf_i386_size_dynamic_sections (output_bfd, info) /* Allocate memory for the section contents. */ s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size); if (s->contents == NULL && s->_raw_size != 0) - { - bfd_set_error (bfd_error_no_memory); - return false; - } + return false; } if (elf_hash_table (info)->dynamic_sections_created) @@ -903,6 +905,9 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section, else { h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + while (h->root.type == bfd_link_hash_indirect + || h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; if (h->root.type == bfd_link_hash_defined || h->root.type == bfd_link_hash_defweak) { @@ -917,6 +922,9 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section, || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)) || (info->shared + && (! info->symbolic + || (h->elf_link_hash_flags + & ELF_LINK_HASH_DEF_REGULAR) == 0) && (r_type == R_386_32 || r_type == R_386_PC32) && (input_section->flags & SEC_ALLOC) != 0)) @@ -1101,9 +1109,14 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section, case R_386_PC32: if (info->shared && (input_section->flags & SEC_ALLOC) != 0 - && (r_type != R_386_PC32 || h != NULL)) + && (r_type != R_386_PC32 + || (h != NULL + && (! info->symbolic + || (h->elf_link_hash_flags + & ELF_LINK_HASH_DEF_REGULAR) == 0)))) { Elf_Internal_Rel outrel; + boolean relocate; /* When generating a shared object, these relocations are copied into the output file to be resolved at run @@ -1135,15 +1148,23 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section, if (r_type == R_386_PC32) { BFD_ASSERT (h != NULL && h->dynindx != -1); + relocate = false; outrel.r_info = ELF32_R_INFO (h->dynindx, R_386_PC32); } else { - if (h == NULL) - outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE); + if (h == NULL + || (info->symbolic + && (h->elf_link_hash_flags + & ELF_LINK_HASH_DEF_REGULAR) != 0)) + { + relocate = true; + outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE); + } else { BFD_ASSERT (h->dynindx != -1); + relocate = false; outrel.r_info = ELF32_R_INFO (h->dynindx, R_386_32); } } @@ -1158,7 +1179,7 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section, not want to fiddle with the addend. Otherwise, we need to include the symbol value so that it becomes an addend for the dynamic reloc. */ - if (h != NULL) + if (! relocate) continue; } @@ -1519,7 +1540,7 @@ elf_i386_finish_dynamic_sections (output_bfd, info) #define elf_backend_finish_dynamic_sections \ elf_i386_finish_dynamic_sections #define elf_backend_want_got_plt 1 -#define elf_backend_plt_readonly 0 +#define elf_backend_plt_readonly 1 #define elf_backend_want_plt_sym 0 #include "elf32-target.h" |