This is the mail archive of the binutils@sourceware.cygnus.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]

Re: readelf breakage.


Hi Guys,

  Here is a patch that should fix this problem.  I will apply it to
  the sources shortly.

Cheers
	Nick


1999-07-09  Nick Clifton  <nickc@cygnus.com>

	* readelf.c: Only support decoding 64bit ELF files if the compiler
	supports a 64 bit data type.


Index: readelf.c
===================================================================
RCS file: /cvs/cvsfiles/devo/binutils/readelf.c,v
retrieving revision 1.75
diff -p -r1.75 readelf.c
*** readelf.c	1999/06/21 22:51:05	1.75
--- readelf.c	1999/07/09 10:03:50
***************
*** 27,35 ****
  #include <stdio.h>
  #include <time.h>
  
  /* Define BFD64 here, even if our default architecture is 32 bit ELF
!    as this will allow us to read in and parse 64bit and 32bit ELF files.  */
  #define BFD64
  #include "bfd.h"
  
  #include "elf/common.h"
--- 27,40 ----
  #include <stdio.h>
  #include <time.h>
  
+ #if __GNUC__ >= 2
  /* Define BFD64 here, even if our default architecture is 32 bit ELF
!    as this will allow us to read in and parse 64bit and 32bit ELF files.
!    Only do this if we belive that the compiler can support a 64 bit
!    data type.  For now we only rely on GCC being able to do this.  */
  #define BFD64
+ #endif
+ 
  #include "bfd.h"
  
  #include "elf/common.h"
*************** typedef int Elf32_Word;
*** 203,209 ****
--- 209,228 ----
  #define DT_VERSIONTAGIDX(tag)	(DT_VERNEEDNUM - (tag))	/* Reverse order! */
  
  #define BYTE_GET(field) 	byte_get (field, sizeof (field))
+ 
+ /* If we can support a 64 bit data type then BFD64 should be defined
+    and sizeof (bfd_vma) == 8.  In this case when translating from an
+    external 8 byte field to an internal field, we can assume that the
+    internal field is also 8 bytes wide and so we can extact all the data.
+    If, however, BFD64 is not defined, then we must assume that the
+    internal data structure only has 4 byte wide fields that are the
+    equivalent of the 8 byte wide external counterparts, and so we must
+    truncate the data.  */
+ #ifdef  BFD64
  #define BYTE_GET8(field) 	byte_get (field, -8)
+ #else
+ #define BYTE_GET8(field) 	byte_get (field, 8)
+ #endif
  
  #define NUM_ELEM(array) 	(sizeof (array) / sizeof ((array)[0]))
  
*************** byte_get_little_endian (field, size)
*** 329,334 ****
--- 348,354 ----
  	|    (((unsigned long) (field [2])) << 16)
  	|    (((unsigned long) (field [3])) << 24);
  
+ #ifdef BFD64
      case -8:
        /* This is a special case, generated by the BYTE_GET8 macro.
  	 It means that we are loading an 8 byte value from a field
*************** byte_get_little_endian (field, size)
*** 342,348 ****
  	|    (((bfd_vma) (field [5])) << 40)
  	|    (((bfd_vma) (field [6])) << 48)
  	|    (((bfd_vma) (field [7])) << 56);
! 
      default:
        error (_("Unhandled data length: %d\n"), size);
        abort ();
--- 362,368 ----
  	|    (((bfd_vma) (field [5])) << 40)
  	|    (((bfd_vma) (field [6])) << 48)
  	|    (((bfd_vma) (field [7])) << 56);
! #endif
      default:
        error (_("Unhandled data length: %d\n"), size);
        abort ();
*************** byte_get_big_endian (field, size)
*** 376,381 ****
--- 396,402 ----
  	|   (((unsigned long) (field [5])) << 16)
  	|   (((unsigned long) (field [4])) << 24);
  
+ #ifdef BFD64
      case -8:
        /* This is a special case, generated by the BYTE_GET8 macro.
  	 It means that we are loading an 8 byte value from a field
*************** byte_get_big_endian (field, size)
*** 389,394 ****
--- 410,416 ----
  	|   (((bfd_vma) (field [2])) << 40)
  	|   (((bfd_vma) (field [1])) << 48)
  	|   (((bfd_vma) (field [0])) << 56);
+ #endif
        
      default:
        error (_("Unhandled data length: %d\n"), size);
*************** dump_relocations (file, rel_offset, rel_
*** 612,618 ****
--- 634,645 ----
        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
  	}
  
  #ifdef _bfd_int64_low
*************** get_file_header (file)
*** 6271,6276 ****
--- 6310,6326 ----
    else
      {
        Elf64_External_Ehdr ehdr64;
+ 
+       /* If we have been compiled with sizeof (bfd_vma) == 4, then
+ 	 we will not be able to cope with the 64bit data found in
+ 	 64 ELF files.  Detect this now and abort before we start
+ 	 overwritting things.  */
+       if (sizeof (bfd_vma) < 8)
+ 	{
+ 	  error (_("This instance of readelf has been built without support for a\n"));
+ 	  error (_("64 bit data type and so it cannot read 64 bit ELF files.\n"));
+ 	  return 0;
+ 	}
        
        if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
  	return 0;

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