diff options
-rw-r--r-- | bfd/ChangeLog | 13 | ||||
-rw-r--r-- | bfd/elf32-i386.c | 34 | ||||
-rw-r--r-- | bfd/elf32-sparc.c | 50 |
3 files changed, 81 insertions, 16 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 5ffa201..e4ed1f3 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,16 @@ +Tue Dec 20 13:58:01 1994 Ian Lance Taylor <ian@sanguine.cygnus.com> + + * elf32-i386.c (elf_i386_relocate_section): Correct and expand the + list of cases for which relocation need not be computed. + * elf32-sparc.c (elf32_sparc_relocate_section): Likewise. + +start-sanitize-arc +Tue Dec 20 09:01:01 1994 Doug Evans <dje@canuck.cygnus.com> + + * elf32-arc.c (elf_arc_howto_table, R_ARC_B22_PCREL): Value is + right-shifted 2 bits. Fix dst_mask. +end-sanitize-arc + Mon Dec 19 23:09:16 1994 Jeff Law (law@snake.cs.utah.edu) * elf32-hppa.c (elf32_hppa_read_symext_info): Delete do_locals and diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 60c0f45..a80cf70 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -647,11 +647,13 @@ elf_i386_adjust_dynamic_symbol (info, h) if (s->_raw_size == 0) s->_raw_size += PLT_ENTRY_SIZE; - /* If we are not generating a shared library, or if the symbol - is not defined, set the symbol to this location in the .plt. - This is required to make function pointers compare as equal - between the normal executable and the shared library. */ - if (! info->shared || h->root.type != bfd_link_hash_defined) + /* If this symbol is not defined in a regular file, and we are + not generating a shared library, then set the symbol to this + location in the .plt. This is required to make function + pointers compare as equal between the normal executable and + the shared library. */ + if (! info->shared + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) { h->root.u.def.section = s; h->root.u.def.value = s->_raw_size; @@ -1030,9 +1032,25 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section, if (h->root.type == bfd_link_hash_defined) { sec = h->root.u.def.section; - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); + if (r_type == R_386_GOTPC + || (r_type == R_386_PLT32 + && h->plt_offset != (bfd_vma) -1) + || (r_type == R_386_GOT32 + && elf_hash_table (info)->dynamic_sections_created) + || (info->shared + && (r_type == R_386_32 + || r_type == R_386_PC32) + && (input_section->flags & SEC_ALLOC) != 0)) + { + /* In these cases, we don't need the relocation + value. We check specially because in some + obscure cases sec->output_section will be NULL. */ + relocation = 0; + } + else + relocation = (h->root.u.def.value + + sec->output_section->vma + + sec->output_offset); } else if (h->root.type == bfd_link_hash_weak) relocation = 0; diff --git a/bfd/elf32-sparc.c b/bfd/elf32-sparc.c index 713e855..006db67 100644 --- a/bfd/elf32-sparc.c +++ b/bfd/elf32-sparc.c @@ -619,11 +619,13 @@ elf32_sparc_adjust_dynamic_symbol (info, h) return false; } - /* If we are not generating a shared library, or if the symbol - is not defined, set the symbol to this location in the .plt. - This is required to make function pointers compare as equal - between the normal executable and the shared library. */ - if (! info->shared || h->root.type != bfd_link_hash_defined) + /* If this symbol is not defined in a regular file, and we are + not generating a shared library, then set the symbol to this + location in the .plt. This is required to make function + pointers compare as equal between the normal executable and + the shared library. */ + if (! info->shared + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) { h->root.u.def.section = s; h->root.u.def.value = s->_raw_size; @@ -1005,9 +1007,41 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section, if (h->root.type == bfd_link_hash_defined) { sec = h->root.u.def.section; - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); + if ((r_type == R_SPARC_WPLT30 + && h->plt_offset != (bfd_vma) -1) + || ((r_type == R_SPARC_GOT10 + || r_type == R_SPARC_GOT13 + || r_type == R_SPARC_GOT22) + && elf_hash_table (info)->dynamic_sections_created) + || (info->shared + && (input_section->flags & SEC_ALLOC) != 0 + && (r_type == R_SPARC_8 + || r_type == R_SPARC_16 + || r_type == R_SPARC_32 + || r_type == R_SPARC_DISP8 + || r_type == R_SPARC_DISP16 + || r_type == R_SPARC_DISP32 + || r_type == R_SPARC_WDISP30 + || r_type == R_SPARC_WDISP22 + || r_type == R_SPARC_HI22 + || r_type == R_SPARC_22 + || r_type == R_SPARC_13 + || r_type == R_SPARC_LO10 + || r_type == R_SPARC_UA32 + || ((r_type == R_SPARC_PC10 + || r_type == R_SPARC_PC22) + && strcmp (h->root.root.string, + "_GLOBAL_OFFSET_TABLE_") != 0)))) + { + /* In these cases, we don't need the relocation + value. We check specially because in some + obscure cases sec->output_section will be NULL. */ + relocation = 0; + } + else + relocation = (h->root.u.def.value + + sec->output_section->vma + + sec->output_offset); } else if (h->root.type == bfd_link_hash_weak) relocation = 0; |