This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Patch for readelf --relocs & little-endian mips elf64
- From: Richard Sandiford <rsandifo at redhat dot com>
- To: binutils at sources dot redhat dot com
- Cc: echristo at redhat dot com
- Date: 26 Jan 2003 15:35:10 +0000
- Subject: 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
}