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]

Patch for readelf --relocs & little-endian mips elf64


As I said in my earlier message, the proposed elf-rel11 test doesn't
work for mips64el-linux-gnu.  The problem is in the interpretation of
a relocation's r_info field.  For MIPS elf64, this seems to be a
fixed-order structure: a 32-bit symbol index followed by 4 individual
byte fields.  Target endiannes applies to the 32-bit field, but not
to the r_info field as a whole.

[I wondered at first whether the fixed order was a bug, but the
GNU & SGI assemblers do seem to agree here.]

As far as I can tell, elf64-mips.c is consistent about the ordering,
but readelf isn't.  The (somewhat unpleasant) patch below fixes that.

I thought about keeping the original order for the INFO column
and just using the corrected order when extracting the fields.
But the convention seems to be that "endianness doesn't matter":
the same information should be displayed the same way regardless.

Tested on the same targets as the earlier patch, fixes the elf-rel11
failure for mips64el-linux-gnu.  OK to install?

Richard


	* readelf.c (dump_relocations): Reorder the r_info field for
	little-endian mips elf64.  Move #ifdef BFD64 to cover the new code.

Index: readelf.c
===================================================================
RCS file: /cvs/src/src/binutils/readelf.c,v
retrieving revision 1.192
diff -c -d -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.192 readelf.c
*** readelf.c	21 Jan 2003 15:41:10 -0000	1.192
--- readelf.c	26 Jan 2003 15:27:28 -0000
*************** dump_relocations (file, rel_offset, rel_
*** 1025,1032 ****
--- 1025,1046 ----
  	}
        else
  	{
+ 	  /* The #ifdef BFD64 below is to prevent a compile time warning.
+ 	     We know that if we do not have a 64 bit data type that we
+ 	     will never execute this code anyway.  */
+ #ifdef BFD64
  	  if (elf_header.e_machine == EM_MIPS)
  	    {
+ 	      /* In little-endian objects, r_info isn't really a 64-bit
+ 		 little-endian value: it has a 32-bit little-endian
+ 		 symbol index followed by four individual byte fields.
+ 		 Reorder INFO accordingly.  */
+ 	      if (elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
+ 		info = (((info & 0xffffffff) << 32)
+ 			| ((info >> 56) & 0xff)
+ 			| ((info >> 40) & 0xff00)
+ 			| ((info >> 24) & 0xff0000)
+ 			| ((info >> 8) & 0xff000000));
  	      type  = ELF64_MIPS_R_TYPE (info);
  	      type2 = ELF64_MIPS_R_TYPE2 (info);
  	      type3 = ELF64_MIPS_R_TYPE3 (info);
*************** dump_relocations (file, rel_offset, rel_
*** 1035,1044 ****
  	    type = ELF64_R_TYPE_ID (info);
  	  else
  	    type = ELF64_R_TYPE (info);
! 	  /* The #ifdef BFD64 below is to prevent a compile time warning.
! 	     We know that if we do not have a 64 bit data type that we
! 	     will never execute this code anyway.  */
! #ifdef BFD64
  	  symtab_index = ELF64_R_SYM  (info);
  #endif
  	}
--- 1049,1055 ----
  	    type = ELF64_R_TYPE_ID (info);
  	  else
  	    type = ELF64_R_TYPE (info);
! 
  	  symtab_index = ELF64_R_SYM  (info);
  #endif
  	}


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