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 09:21:57AM +0930, Alan Modra wrote:
> On Sat, Aug 14, 2004 at 05:47:43PM +0200, Jakub Jelinek wrote:
> > FAIL: S-records
> 
> This one is also a linker problem, but I'm inclined to ignore it for the
> time being.  The generic linker doesn't understand how to resolve
> "bl foo" to the function code entry point.

Well, it wasn't too hard to fix.

	* elf64-ppc.c (ppc64_elf_branch_reloc): New function.
	(ppc64_elf_howto_raw): Use ppc64_elf_branch_reloc.
	(ppc64_elf_brtaken_reloc): Here too.

Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.161
diff -u -p -r1.161 elf64-ppc.c
--- bfd/elf64-ppc.c	17 Aug 2004 05:38:28 -0000	1.161
+++ bfd/elf64-ppc.c	17 Aug 2004 07:01:13 -0000
@@ -35,6 +35,8 @@
 
 static bfd_reloc_status_type ppc64_elf_ha_reloc
   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type ppc64_elf_branch_reloc
+  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
 static bfd_reloc_status_type ppc64_elf_brtaken_reloc
   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
 static bfd_reloc_status_type ppc64_elf_sectoff_reloc
@@ -49,7 +51,8 @@ static bfd_reloc_status_type ppc64_elf_t
   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
 static bfd_reloc_status_type ppc64_elf_unhandled_reloc
   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
-
+static bfd_vma opd_entry_value
+  (asection *, bfd_vma, asection **, bfd_vma *);
 
 #define TARGET_LITTLE_SYM	bfd_elf64_powerpcle_vec
 #define TARGET_LITTLE_NAME	"elf64-powerpcle"
@@ -305,7 +308,7 @@ static reloc_howto_type ppc64_elf_howto_
 	 FALSE,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_bitfield, /* complain_on_overflow */
-	 bfd_elf_generic_reloc,	/* special_function */
+	 ppc64_elf_branch_reloc, /* special_function */
 	 "R_PPC64_ADDR14",	/* name */
 	 FALSE,			/* partial_inplace */
 	 0,			/* src_mask */
@@ -354,7 +357,7 @@ static reloc_howto_type ppc64_elf_howto_
 	 TRUE,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_signed, /* complain_on_overflow */
-	 bfd_elf_generic_reloc,	/* special_function */
+	 ppc64_elf_branch_reloc, /* special_function */
 	 "R_PPC64_REL24",	/* name */
 	 FALSE,			/* partial_inplace */
 	 0,			/* src_mask */
@@ -369,7 +372,7 @@ static reloc_howto_type ppc64_elf_howto_
 	 TRUE,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_signed, /* complain_on_overflow */
-	 bfd_elf_generic_reloc,	/* special_function */
+	 ppc64_elf_branch_reloc, /* special_function */
 	 "R_PPC64_REL14",	/* name */
 	 FALSE,			/* partial_inplace */
 	 0,			/* src_mask */
@@ -2133,6 +2136,28 @@ ppc64_elf_ha_reloc (bfd *abfd, arelent *
 }
 
 static bfd_reloc_status_type
+ppc64_elf_branch_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
+			void *data, asection *input_section,
+			bfd *output_bfd, char **error_message)
+{
+  if (output_bfd != NULL)
+    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+				  input_section, output_bfd, error_message);
+
+  if (strcmp (symbol->section->name, ".opd") == 0)
+    {
+      bfd_vma dest = opd_entry_value (symbol->section,
+				      symbol->value + reloc_entry->addend,
+				      NULL, NULL);
+      if (dest != (bfd_vma) -1)
+	reloc_entry->addend = dest - (symbol->value
+				      + symbol->section->output_section->vma
+				      + symbol->section->output_offset);
+    }
+  return bfd_reloc_continue;
+}
+
+static bfd_reloc_status_type
 ppc64_elf_brtaken_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
 			 void *data, asection *input_section,
 			 bfd *output_bfd, char **error_message)
@@ -2168,7 +2193,7 @@ ppc64_elf_brtaken_reloc (bfd *abfd, arel
       else if ((insn & (0x14 << 21)) == (0x10 << 21))
 	insn |= 0x08 << 21;
       else
-	return bfd_reloc_continue;
+	goto out;
     }
   else
     {
@@ -2190,7 +2215,9 @@ ppc64_elf_brtaken_reloc (bfd *abfd, arel
 	insn ^= 0x01 << 21;
     }
   bfd_put_32 (abfd, insn, (bfd_byte *) data + octets);
-  return bfd_reloc_continue;
+ out:
+  return ppc64_elf_branch_reloc (abfd, reloc_entry, symbol, data,
+				 input_section, output_bfd, error_message);
 }
 
 static bfd_reloc_status_type


-- 
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]