From: NIIBE Y. <gn...@m1...> - 2002-02-22 00:54:52
|
I've been struggling binutils... Binutils 2.11.2 (with our patch) works fine. Newer has issues, wrt got.{refcount,offset} implementation. I'm using following patch to binutils-2.11.92.0.12.3. The workaround is in bfd/elflink.h and bfd/elf.c. Sh backend should adopt new refcount base scheme (currently use offset from the beginning, and not using refcount). --- binutils-2.11.92.0.12.3/gas/configure.in 2001/12/08 03:45:55 1.85 +++ binutils-2.11.92.0.12.3/gas/configure.in 2001/12/13 10:30:48 @@ -394,8 +394,13 @@ changequote([,])dnl s390x-*-linux-gnu*) fmt=elf em=linux ;; s390-*-linux-gnu*) fmt=elf em=linux ;; - sh*eb-*-linux*) fmt=elf em=linux endian=big ;; - sh*-*-linux*) fmt=elf em=linux endian=little ;; + sh-*-linux*) fmt=elf em=linux + case ${cpu} in + sh*eb) + endian=big ;; + sh*) + endian=little ;; + esac ;; sh-*-elf*) fmt=elf ;; sh-*-coff*) fmt=coff bfd_gas=yes;; sh-*-pe*) fmt=coff em=pe bfd_gas=yes endian=little ;; --- binutils-2.11.92.0.12.3/gas/configure~ Sat Nov 17 07:05:52 2001 +++ binutils-2.11.92.0.12.3/gas/configure Tue Jan 22 11:02:20 2002 @@ -2518,8 +2518,13 @@ s390x-*-linux-gnu*) fmt=elf em=linux ;; s390-*-linux-gnu*) fmt=elf em=linux ;; - sh*eb-*-linux*) fmt=elf em=linux endian=big ;; - sh*-*-linux*) fmt=elf em=linux endian=little ;; + sh-*-linux*) fmt=elf em=linux + case ${cpu} in + sh*eb) + endian=big ;; + sh*) + endian=little ;; + esac ;; sh-*-elf*) fmt=elf ;; sh-*-coff*) fmt=coff bfd_gas=yes;; sh-*-pe*) fmt=coff em=pe bfd_gas=yes endian=little ;; --- binutils-2.11.92.0.12.3/bfd/elflink.h~ Thu Nov 29 15:55:47 2001 +++ binutils-2.11.92.0.12.3/bfd/elflink.h Wed Feb 20 17:37:09 2002 @@ -7914,7 +7914,7 @@ { bfd_vma *off = (bfd_vma *) offarg; - if (h->got.refcount > 0) + if (h->got.refcount >= 0) { h->got.offset = off[0]; off[0] += ARCH_SIZE / 8; --- binutils-2.11.92.0.12.3/bfd/elf.c~ Sat Nov 17 07:05:51 2001 +++ binutils-2.11.92.0.12.3/bfd/elf.c Wed Feb 20 17:36:39 2002 @@ -1213,7 +1213,7 @@ /* Copy over the global and procedure linkage table refcount entries. These may have been already set up by a check_relocs routine. */ tmp = dir->got.refcount; - if (tmp <= 0) + if (tmp < 0) { dir->got.refcount = ind->got.refcount; ind->got.refcount = tmp; @@ -1222,7 +1222,7 @@ BFD_ASSERT (ind->got.refcount <= 0); tmp = dir->plt.refcount; - if (tmp <= 0) + if (tmp < 0) { dir->plt.refcount = ind->plt.refcount; ind->plt.refcount = tmp; --- binutils-2.11.92.0.12.3/bfd/elf32-sh.c.orig Wed Feb 20 17:34:17 2002 +++ binutils-2.11.92.0.12.3/bfd/elf32-sh.c Wed Feb 20 17:35:40 2002 @@ -2624,14 +2624,18 @@ { 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) + && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0 + /* XXX: Should be reverted after linker behaviour will be fixed */ + && h->root.type != bfd_link_hash_undefweak + && h->root.type != bfd_link_hash_undefined) { /* This case can occur if we saw a PLT reloc in an input 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 REL32 - reloc instead. */ - BFD_ASSERT ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0); + object, or if all references were garbage collected. In + such a case, we don't actually need to build a procedure + linkage table, and we can just do a REL32 reloc instead. */ + h->plt.offset = (bfd_vma) -1; + h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT; return true; } @@ -2986,6 +2990,11 @@ sgot = NULL; splt = NULL; sreloc = NULL; + if (dynobj != NULL) + { + splt = bfd_get_section_by_name (dynobj, ".plt"); + sgot = bfd_get_section_by_name (dynobj, ".got"); + } rel = relocs; relend = relocs + input_section->reloc_count; @@ -3101,6 +3110,7 @@ sec->output_section will be NULL. */ if (r_type == R_SH_GOTPC || (r_type == R_SH_PLT32 + && splt != NULL && h->plt.offset != (bfd_vma) -1) || (r_type == R_SH_GOT32 && elf_hash_table (info)->dynamic_sections_created @@ -3126,7 +3136,9 @@ sections against symbols defined externally in shared libraries. We can't do anything with them here. */ - || (input_section->flags & SEC_DEBUGGING) != 0))) + || ((input_section->flags & SEC_DEBUGGING) != 0 + && (h->elf_link_hash_flags + & ELF_LINK_HASH_DEF_DYNAMIC) != 0)))) relocation = 0; else if (sec->output_section == NULL) { @@ -3144,14 +3156,17 @@ else if (h->root.type == bfd_link_hash_undefweak) relocation = 0; else if (info->shared - && (!info->symbolic || info->allow_shlib_undefined) - && !info->no_undefined) + && (!info->symbolic || info->allow_shlib_undefined) + && !info->no_undefined + && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) relocation = 0; else { if (! ((*info->callbacks->undefined_symbol) (info, h->root.root.string, input_bfd, - input_section, rel->r_offset, true))) + input_section, rel->r_offset, + (!info->shared || info->no_undefined + || ELF_ST_VISIBILITY (h->other))))) return false; relocation = 0; } @@ -3465,7 +3480,8 @@ || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN) goto final_link_relocate; - if (h->plt.offset == (bfd_vma) -1) + if (h->plt.offset == (bfd_vma) -1 + || splt == NULL) { /* We didn't make a PLT entry for this symbol. This happens when statically linking PIC code, or when @@ -3473,12 +3489,6 @@ goto final_link_relocate; } - if (splt == NULL) - { - splt = bfd_get_section_by_name (dynobj, ".plt"); - BFD_ASSERT (splt != NULL); - } - relocation = (splt->output_section->vma + splt->output_offset + h->plt.offset); @@ -3920,7 +3930,6 @@ break; h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; - break; case R_SH_DIR32: @@ -3945,6 +3954,7 @@ && (ELF32_R_TYPE (rel->r_info) != R_SH_REL32 || (h != NULL && (! info->symbolic + || h->root.type == bfd_link_hash_defweak || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)))) { -- |