This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix objdump -d on ppc64 without dot syms (take 2)


On Tue, Aug 17, 2004 at 01:27:10PM +0930, Alan Modra wrote:
> I suppose I could do something in the linker for old ABI objects that
> have a mismatch between code entry and function descriptor symbols..

This also fixes a segfault when using the srec linker.

bfd/
	* elf64-ppc.c (add_symbol_adjust): Correct mismatched function
	symbol visibility.
	(ppc64_elf_check_directives): Check that we have the right hash
	table before proceeding.
ld/testsuite/
	* ld-elfvsb/elfvsb.exp: Cope with ppc64 dot symbols.

Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.160
diff -u -p -r1.160 elf64-ppc.c
--- bfd/elf64-ppc.c	17 Aug 2004 01:25:21 -0000	1.160
+++ bfd/elf64-ppc.c	17 Aug 2004 05:10:55 -0000
@@ -3569,7 +3569,10 @@ ppc64_elf_archive_symbol_lookup (bfd *ab
    new ABI object defines "bar".  Well, at least, undefined dot symbols
    are made weak.  This stops later archive searches from including an
    object if we already have a function descriptor definition.  It also
-   prevents the linker complaining about undefined symbols.  */
+   prevents the linker complaining about undefined symbols.
+   We also check and correct mismatched symbol visibility here.  The
+   most restrictive visibility of the function descriptor and the
+   function entry symbol is used.  */
 
 static bfd_boolean
 add_symbol_adjust (struct elf_link_hash_entry *h, void *inf)
@@ -3585,8 +3588,7 @@ add_symbol_adjust (struct elf_link_hash_
   if (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_undefined
-      || h->root.root.string[0] != '.')
+  if (h->root.root.string[0] != '.')
     return TRUE;
 
   info = inf;
@@ -3595,9 +3597,19 @@ add_symbol_adjust (struct elf_link_hash_
   fdh = get_fdh (eh, htab);
   if (fdh != NULL)
     {
-      eh->elf.root.type = bfd_link_hash_undefweak;
-      eh->was_undefined = 1;
-      htab->twiddled_syms = 1;
+      unsigned entry_vis = ELF_ST_VISIBILITY (eh->elf.other) - 1;
+      unsigned descr_vis = ELF_ST_VISIBILITY (fdh->elf.other) - 1;
+      if (entry_vis < descr_vis)
+	fdh->elf.other += entry_vis - descr_vis;
+      else if (entry_vis > descr_vis)
+	eh->elf.other += descr_vis - entry_vis;
+
+      if (eh->elf.root.type == bfd_link_hash_undefined)
+	{
+	  eh->elf.root.type = bfd_link_hash_undefweak;
+	  eh->was_undefined = 1;
+	  htab->twiddled_syms = 1;
+	}
     }
 
   return TRUE;
@@ -3608,8 +3620,14 @@ ppc64_elf_check_directives (bfd *abfd AT
 			    struct bfd_link_info *info)
 {
   struct ppc_link_hash_table *htab;
+  extern const bfd_target bfd_elf64_powerpc_vec;
+  extern const bfd_target bfd_elf64_powerpcle_vec;
 
   htab = ppc_hash_table (info);
+  if (htab->elf.root.creator != &bfd_elf64_powerpc_vec
+      && htab->elf.root.creator != &bfd_elf64_powerpcle_vec)
+    return TRUE;
+
   elf_link_hash_traverse (&htab->elf, add_symbol_adjust, info);
 
   /* We need to fix the undefs list for any syms we have twiddled to
Index: ld/testsuite/ld-elfvsb/elfvsb.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-elfvsb/elfvsb.exp,v
retrieving revision 1.25
diff -u -p -r1.25 elfvsb.exp
--- ld/testsuite/ld-elfvsb/elfvsb.exp	11 May 2004 17:08:37 -0000	1.25
+++ ld/testsuite/ld-elfvsb/elfvsb.exp	17 Aug 2004 05:10:55 -0000
@@ -117,11 +117,11 @@ proc visibility_test { visibility progna
     }
     if {![ld_simple_link $CC $tmpdir/$progname.so "$shared $shldflags $tmpdir/$sh1 $tmpdir/$sh2"]} {
 	if { [ string match $visibility "hidden_undef" ]
-	     && [regexp ".*/sh1.c.*: undefined reference to \`visibility\'" $link_output]
+	     && [regexp ".*/sh1.c.*: undefined reference to \`\.?visibility\'" $link_output]
 	     && [regexp ".*/sh1.c.*: undefined reference to \`visibility_var\'" $link_output] } {
     	    pass "$testname"
 	} else { if { [ string match $visibility "protected_undef" ]
-	     && [regexp ".*/sh1.c.*: undefined reference to \`visibility\'" $link_output]
+	     && [regexp ".*/sh1.c.*: undefined reference to \`\.?visibility\'" $link_output]
 	     && [regexp ".*/sh1.c.*: undefined reference to \`visibility_var\'" $link_output] } {
     	    pass "$testname"
 	} else {
@@ -140,13 +140,13 @@ proc visibility_test { visibility progna
     }
     if ![ld_simple_link $CC $tmpdir/$progname "-Wl,-rpath,$rpath $tmpdir/$main $tmpdir/$progname.so"] {
 	if { [ string match $visibility "hidden" ]
-	     && [regexp ".*/main.c.*: undefined reference to \`visibility\'" $link_output]
+	     && [regexp ".*/main.c.*: undefined reference to \`\.?visibility\'" $link_output]
 	     && [regexp ".*/main.c.*: undefined reference to \`visibility_var\'" $link_output] } {
     	    pass "$testname"
 	} else { if { [ string match $visibility "hidden_undef_def" ]
-	     && [regexp ".*/main.c.*: undefined reference to \`visibility\'" $link_output]
+	     && [regexp ".*/main.c.*: undefined reference to \`\.?visibility\'" $link_output]
 	     && [regexp ".*/main.c.*: undefined reference to \`visibility_def\'" $link_output]
-	     && [regexp ".*/main.c.*: undefined reference to \`visibility_func\'" $link_output]
+	     && [regexp ".*/main.c.*: undefined reference to \`\.?visibility_func\'" $link_output]
 	     && [regexp ".*/main.c.*: undefined reference to \`visibility_var\'" $link_output] } {
     	    pass "$testname"
 	} else {

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]