From a952a37550523872520cc6bd73a1e8aae92128a5 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Fri, 9 Jul 1999 03:14:15 +0000 Subject: [PATCH] Only decode 64bit ELF files if the host compiler supports a 64bit data type. --- binutils/ChangeLog | 7 +++++ binutils/readelf.c | 64 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 64 insertions(+), 7 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 17f6805331..f7f25a1d01 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,10 @@ +1999-07-09 Nick Clifton + + * readelf.c: Only support decoding 64bit ELF files if the compiler + supports a 64 bit data type. + Add -I equivalent for --histogram. + Add -A command-line option to display architecture specific information. + 1999-07-08 Jakub Jelinek * readelf.c (guess_is_rela): Sparcv9 and v8plus use rela. diff --git a/binutils/readelf.c b/binutils/readelf.c index 84f73f13b7..3c613a6fa4 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -27,9 +27,14 @@ #include #include +#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. */ + 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" @@ -108,6 +113,7 @@ int do_debug_abbrevs; int do_debug_lines; int do_debug_pubnames; int do_debug_aranges; +int do_arch; int is_32bit_elf; /* A dynamic array of flags indicating which sections require dumping. */ @@ -200,7 +206,20 @@ typedef int Elf32_Word; #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])) @@ -326,6 +345,7 @@ byte_get_little_endian (field, size) | (((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 @@ -339,7 +359,7 @@ byte_get_little_endian (field, size) | (((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 (); @@ -373,6 +393,7 @@ byte_get_big_endian (field, size) | (((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 @@ -386,6 +407,7 @@ byte_get_big_endian (field, size) | (((bfd_vma) (field [2])) << 40) | (((bfd_vma) (field [1])) << 48) | (((bfd_vma) (field [0])) << 56); +#endif default: error (_("Unhandled data length: %d\n"), size); @@ -611,7 +633,12 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela) 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 } #ifdef _bfd_int64_low @@ -1282,7 +1309,7 @@ struct option options [] = {"file-header", no_argument, 0, 'h'}, {"program-headers", no_argument, 0, 'l'}, {"headers", no_argument, 0, 'e'}, - {"histogram", no_argument, & do_histogram, 1}, + {"histogram", no_argument, 0, 'I'}, {"segments", no_argument, 0, 'l'}, {"sections", no_argument, 0, 'S'}, {"section-headers", no_argument, 0, 'S'}, @@ -1290,6 +1317,7 @@ struct option options [] = {"syms", no_argument, 0, 's'}, {"relocs", no_argument, 0, 'r'}, {"dynamic", no_argument, 0, 'd'}, + {"arch-specific", no_argument, 0, 'A'}, {"version-info", no_argument, 0, 'V'}, {"use-dynamic", no_argument, 0, 'D'}, {"hex-dump", required_argument, 0, 'x'}, @@ -1308,7 +1336,7 @@ usage () { fprintf (stdout, _("Usage: readelf {options} elf-file(s)\n")); fprintf (stdout, _(" Options are:\n")); - fprintf (stdout, _(" -a or --all Equivalent to: -h -l -S -s -r -d -V --histogram\n")); + fprintf (stdout, _(" -a or --all Equivalent to: -h -l -S -s -r -d -V -A -I\n")); fprintf (stdout, _(" -h or --file-header Display the ELF file header\n")); fprintf (stdout, _(" -l or --program-headers or --segments\n")); fprintf (stdout, _(" Display the program headers\n")); @@ -1319,6 +1347,7 @@ usage () fprintf (stdout, _(" -r or --relocs Display the relocations (if present)\n")); fprintf (stdout, _(" -d or --dynamic Display the dynamic segment (if present)\n")); fprintf (stdout, _(" -V or --version-info Display the version sections (if present)\n")); + fprintf (stdout, _(" -A or --arch-specific Display architecture specific information (if any).\n")); fprintf (stdout, _(" -D or --use-dynamic Use the dynamic section info when displaying symbols\n")); fprintf (stdout, _(" -x or --hex-dump=\n")); fprintf (stdout, _(" Dump the contents of section \n")); @@ -1328,7 +1357,7 @@ usage () fprintf (stdout, _(" -i or --instruction-dump=\n")); fprintf (stdout, _(" Disassemble the contents of section \n")); #endif - fprintf (stdout, _(" --histogram Display histogram of bucket list lengths\n")); + fprintf (stdout, _(" -I or --histogram Display histogram of bucket list lengths\n")); fprintf (stdout, _(" -v or --version Display the version number of readelf\n")); fprintf (stdout, _(" -H or --help Display this information\n")); fprintf (stdout, _("Report bugs to bug-gnu-utils@gnu.org\n")); @@ -1378,7 +1407,7 @@ parse_args (argc, argv) usage (); while ((c = getopt_long - (argc, argv, "ersahldSDw::x:i:vV", options, NULL)) != EOF) + (argc, argv, "ersahldSDAIw::x:i:vV", options, NULL)) != EOF) { char * cp; int section; @@ -1401,12 +1430,16 @@ parse_args (argc, argv) do_segments ++; do_version ++; do_histogram ++; + do_arch ++; break; case 'e': do_header ++; do_sections ++; do_segments ++; break; + case 'A': + do_arch ++; + break; case 'D': do_using_dynamic ++; break; @@ -1428,6 +1461,9 @@ parse_args (argc, argv) case 'd': do_dynamic ++; break; + case 'I': + do_histogram ++; + break; case 'x': do_dump ++; section = strtoul (optarg, & cp, 0); @@ -1506,7 +1542,7 @@ parse_args (argc, argv) if (!do_dynamic && !do_syms && !do_reloc && !do_sections && !do_segments && !do_header && !do_dump && !do_version - && !do_histogram && !do_debugging) + && !do_histogram && !do_debugging && !do_arch) usage (); else if (argc < 3) { @@ -6229,6 +6265,9 @@ static int process_arch_specific (file) FILE * file; { + if (! do_arch) + return 1; + switch (elf_header.e_machine) { case EM_MIPS: @@ -6286,6 +6325,17 @@ get_file_header (file) 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;