This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Committed, CRIS: Fixes for ELF visibility, objects with no global symbols
- From: Hans-Peter Nilsson <hans-peter dot nilsson at axis dot com>
- To: binutils at sources dot redhat dot com
- Date: Tue, 9 Jul 2002 05:52:41 +0200
- Subject: Committed, CRIS: Fixes for ELF visibility, objects with no global symbols
There are two fixes here, both necessary for current CVS GCC,
creating libgcc_s.so.1. One: fix bugs with ELF visibility.
Two: be able to link objects with no global symbols. Strange
that the latter hasn't been spotted before. I'm sorry that I
don't have a test-case to trig the sanity-check I moved, other
than the below, for the first location being incorrect. It's
been there since FSF elf32-cris.c 1.1, FWIW.
ld/testsuite:
* ld-cris/libdso-3.d, ld-cris/dso-3.s, ld-cris/noglob1.s,
ld-cris/noglob1.d: New tests.
bfd:
* elf32-cris.c (cris_elf_relocate_section): Move sanity-check for
NULL sym_hashes to just before use.
<case R_CRIS_32_GOTREL>: In test for local symbol, accept also
symbol with non-default visibility.
<case R_CRIS_32_GOTREL, case R_CRIS_32_PLT_GOTREL>: Ditto.
<case R_CRIS_8_PCREL, case R_CRIS_16_PCREL, case R_CRIS_32_PCREL>:
Ditto.
(cris_elf_gc_sweep_hook): Only decrease h->plt.refcount for
symbol with non-default visibility.
(cris_elf_check_relocs): At tests for local symbol before
increasing h->plt.refcount, also check for non-default
visibility. Ditto when checking for local symbol to eliminate
pc-relative runtime relocs.
Index: ld-cris/dso-3.s
===================================================================
RCS file: ld-cris/dso-3.s
diff -N ld-cris/dso-3.s
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- ld-cris/dso-3.s 9 Jul 2002 03:34:09 -0000
***************
*** 0 ****
--- 1,20 ----
+ ; The visibility definitions here override the default
+ ; definitions in the object where the symbols are defined. We
+ ; check STV_HIDDEN and STV_PROTECTED with function and object
+ ; definition respectively. This is by no means a full coverage,
+ ; just enough to be a test-case for the bug described in
+ ; libdso-3.d. Use ld-elfvsb for general visibility tests.
+
+ .hidden expobj
+ .protected expfn
+
+ .text
+ .global globsym
+ .type globsym,@function
+ globsym:
+ move.d expfn:GOTOFF,$r3
+ move.d expfn:PLTG,$r3
+ move.d expfn:PLT,$r3
+ move.d expobj:GOTOFF,$r3
+ .Lfe1:
+ .size globsym,.Lfe1-globsym
Index: ld-cris/libdso-3.d
===================================================================
RCS file: ld-cris/libdso-3.d
diff -N ld-cris/libdso-3.d
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- ld-cris/libdso-3.d 9 Jul 2002 03:34:09 -0000
***************
*** 0 ****
--- 1,14 ----
+ #source: expdyn1.s
+ #source: dso-3.s
+ #as: --pic --no-underscore
+ #ld: --shared -m crislinux
+ #objdump: -R
+
+ # GOTOFF relocs against global symbols with non-default
+ # visibility got a linker error. (A non-default visibility is
+ # to be treated as a local definition for the reloc.) We also
+ # make sure we don't get unnecessary dynamic relocations.
+
+ .*: file format elf32-cris
+
+ DYNAMIC RELOCATION RECORDS \(none\)
Index: ld-cris/noglob1.d
===================================================================
RCS file: ld-cris/noglob1.d
diff -N ld-cris/noglob1.d
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- ld-cris/noglob1.d 9 Jul 2002 03:34:09 -0000
***************
*** 0 ****
--- 1,8 ----
+ #ld:
+ #objdump: -p
+
+ # Check that we can link an object that doesn't have any global symbols;
+ # where elf_sym_hashes(bfd) is NULL.
+
+ .*: file format elf32.*-cris
+ #pass
Index: ld-cris/noglob1.s
===================================================================
RCS file: ld-cris/noglob1.s
diff -N ld-cris/noglob1.s
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- ld-cris/noglob1.s 9 Jul 2002 03:34:09 -0000
***************
*** 0 ****
--- 1,4 ----
+ ; See noglob1.d
+ .text
+ x:
+ move.d .,$r0
Index: elf32-cris.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-cris.c,v
retrieving revision 1.32
diff -p -c -r1.32 elf32-cris.c
*** elf32-cris.c 1 Jul 2002 08:06:42 -0000 1.32
--- elf32-cris.c 9 Jul 2002 03:17:52 -0000
*************** cris_elf_relocate_section (output_bfd, i
*** 805,815 ****
sym_hashes = elf_sym_hashes (input_bfd);
relend = relocs + input_section->reloc_count;
- /* It seems this can happen with erroneous or unsupported input (mixing
- a.out and elf in an archive, for example.) */
- if (sym_hashes == NULL)
- return false;
-
sgot = NULL;
splt = NULL;
sreloc = NULL;
--- 805,810 ----
*************** cris_elf_relocate_section (output_bfd, i
*** 879,884 ****
--- 874,884 ----
}
else
{
+ /* It seems this can happen with erroneous or unsupported input
+ (mixing a.out and elf in an archive, for example.) */
+ if (sym_hashes == NULL)
+ return false;
+
h = sym_hashes [r_symndx - symtab_hdr->sh_info];
while (h->root.type == bfd_link_hash_indirect
*************** cris_elf_relocate_section (output_bfd, i
*** 1150,1156 ****
case R_CRIS_32_GOTREL:
/* This relocation must only be performed against local symbols. */
! if (h != NULL)
{
(*_bfd_error_handler)
(_("%s: relocation %s is not allowed for global symbol: `%s' from %s section"),
--- 1150,1156 ----
case R_CRIS_32_GOTREL:
/* This relocation must only be performed against local symbols. */
! if (h != NULL && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
{
(*_bfd_error_handler)
(_("%s: relocation %s is not allowed for global symbol: `%s' from %s section"),
*************** cris_elf_relocate_section (output_bfd, i
*** 1190,1196 ****
/* Resolve a PLT_PCREL reloc against a local symbol directly,
without using the procedure linkage table. */
! if (h == NULL)
break;
if (h->plt.offset == (bfd_vma) -1
--- 1190,1196 ----
/* Resolve a PLT_PCREL reloc against a local symbol directly,
without using the procedure linkage table. */
! if (h == NULL || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
break;
if (h->plt.offset == (bfd_vma) -1
*************** cris_elf_relocate_section (output_bfd, i
*** 1215,1221 ****
/* Resolve a PLT_GOTREL reloc against a local symbol directly,
without using the procedure linkage table. */
! if (h == NULL)
break;
if (h->plt.offset == (bfd_vma) -1
--- 1215,1221 ----
/* Resolve a PLT_GOTREL reloc against a local symbol directly,
without using the procedure linkage table. */
! if (h == NULL || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
break;
if (h->plt.offset == (bfd_vma) -1
*************** cris_elf_relocate_section (output_bfd, i
*** 1237,1243 ****
case R_CRIS_16_PCREL:
case R_CRIS_32_PCREL:
/* If the symbol was local, we need no shlib-specific handling. */
! if (h == NULL)
break;
/* Fall through. */
--- 1237,1243 ----
case R_CRIS_16_PCREL:
case R_CRIS_32_PCREL:
/* If the symbol was local, we need no shlib-specific handling. */
! if (h == NULL || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
break;
/* Fall through. */
*************** cris_elf_gc_sweep_hook (abfd, info, sec,
*** 1898,1904 ****
if (r_symndx >= symtab_hdr->sh_info)
{
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
! if (h->plt.refcount > 0)
--h->plt.refcount;
}
break;
--- 1898,1905 ----
if (r_symndx >= symtab_hdr->sh_info)
{
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
! if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
! && h->plt.refcount > 0)
--h->plt.refcount;
}
break;
*************** cris_elf_check_relocs (abfd, info, sec,
*** 2486,2492 ****
/* If this is a local symbol, we resolve it directly without
creating a procedure linkage table entry. */
! if (h == NULL)
continue;
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
--- 2487,2493 ----
/* If this is a local symbol, we resolve it directly without
creating a procedure linkage table entry. */
! if (h == NULL || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
continue;
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
*************** cris_elf_check_relocs (abfd, info, sec,
*** 2525,2531 ****
/* Make sure a plt entry is created for this symbol if it
turns out to be a function defined by a dynamic object. */
! h->plt.refcount++;
}
/* If we are creating a shared library and this is not a local
--- 2526,2533 ----
/* Make sure a plt entry is created for this symbol if it
turns out to be a function defined by a dynamic object. */
! if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
! h->plt.refcount++;
}
/* If we are creating a shared library and this is not a local
*************** cris_elf_check_relocs (abfd, info, sec,
*** 2558,2564 ****
|| r_type == R_CRIS_32_PCREL)
{
/* If the symbol is local, then we can eliminate the reloc. */
! if (h == NULL)
break;
/* If this is with -Bsymbolic and the symbol isn't weak, and
--- 2560,2566 ----
|| r_type == R_CRIS_32_PCREL)
{
/* If the symbol is local, then we can eliminate the reloc. */
! if (h == NULL || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
break;
/* If this is with -Bsymbolic and the symbol isn't weak, and
brgds, H-P