[PATCH] objdump relocation fixes for ARM disassembly

Stig Petter Olsrød stigpo@users.sourceforge.net
Tue Feb 22 22:54:00 GMT 2005


Hello,

objdump disassembly did not relocate correctly for the ARM processor. It seems 
that the test for triggering the INSN_HAS_RELOC flag was void (one test killed the other,
since octets would always be zero) and all relocations would thus fail. I changed the test 
so the flag is set when we are about to disassemble an insn that the current relocation 
entry points to. I also changed objdump_print_addr to use the current relocation entry if 
the insn has such an entry. This causes the symbol printed to be correct for both external 
symbols (from the undefined section) and local symbols. 

This has only been tested for the ARM processor, but I don't think it should break other
DISASSEMBLER_NEEDS_RELOCS processors either. 


binutils/

2005-02-22  Stig Petter Olsroed  <stigpo@users.sourceforge.net>

	* objdump.c (disassemble_bytes): Fixed relocation check for
	DISASSEMBLER_NEEDS_RELOCS platforms to properly trigger the
	INSN_HAS_RELOC flag.  Set the current relocation entry in
	objdump_disasm_info to allow printing the proper symbol.
	(objdump_print_addr): Use the relocation entry in
	objdump_disasm_info to lookup the correct symbol for
	DISASSEMBLER_NEEDS_RELOCS platforms.

--- binutils/objdump.c	2005-02-22 01:50:06.000000000 +0100
+++ binutils/objdump.c   2005-02-22 14:27:33.066960900 +0100
@@ -128,6 +128,7 @@
   arelent **         dynrelbuf;
   long               dynrelcount;
   disassembler_ftype disassemble_fn;
+  arelent *          reloc;
 };
 
 /* Architecture to disassemble for, or default if NULL.  */
@@ -852,6 +853,8 @@
 {
   struct objdump_disasm_info *aux;
   asymbol *sym;
+  arelent *q;
+  int skip_find = 0;
 
   if (sorted_symcount < 1)
     {
@@ -861,6 +864,22 @@
     }
 
   aux = (struct objdump_disasm_info *) info->application_data;
+
+  q = aux->reloc;
+  if (q != NULL)
+    {
+      if (q->sym_ptr_ptr != NULL && *q->sym_ptr_ptr != NULL)
+        {
+          /* Adjust the vma to the reloc */
+          vma += bfd_asymbol_value (*q->sym_ptr_ptr);
+          if (bfd_is_und_section (bfd_get_section (*q->sym_ptr_ptr)))
+            {
+              skip_find = 1;
+              sym = *q->sym_ptr_ptr;
+            }
+        }
+    }
+  if (!skip_find)
   sym = find_symbol_for_address (vma, info, NULL);
   objdump_print_addr_with_sym (aux->abfd, aux->sec, sym, vma, info,
 			       skip_zeroes);
@@ -1350,16 +1369,22 @@
 	      info->bytes_per_chunk = 0;
 
 #ifdef DISASSEMBLER_NEEDS_RELOCS
-	      /* FIXME: This is wrong.  It tests the number of octets
-		 in the last instruction, not the current one.  */
-	      if (*relppp < relppend
-		  && (**relppp)->address >= rel_offset + addr_offset
-		  && ((**relppp)->address
-		      < rel_offset + addr_offset + octets / opb))
+	      /* Check if the current relocation entry applies to the 
+		 instruction we are about to disassemble.
+		 This works for ARM at least.
+	      */
+	      if ((*relppp) < relppend
+		  && ((**relppp)->address == rel_offset + addr_offset))
+		{
 		info->flags = INSN_HAS_RELOC;
+		  aux->reloc = **relppp;
+		}
 	      else
 #endif
+		{
 		info->flags = 0;
+		  aux->reloc = NULL;
+		}
 
 	      octets = (*disassemble_fn) (section->vma + addr_offset, info);
 	      info->fprintf_func = (fprintf_ftype) fprintf;





More information about the Binutils mailing list