* hppa-dis.c (print_insn_hppa): Output a space after 'X' completer.
[deliverable/binutils-gdb.git] / binutils / readelf.c
index 388a0833e9e03d6924a2856578d1ce90accffb75..9a85549b50d05e8e03376cc073f1354fc48f3a9a 100644 (file)
 #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.  */
+   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"
@@ -62,6 +67,7 @@
 #include "elf/fr30.h"
 #include "elf/mcore.h"
 #include "elf/i960.h"
+#include "elf/pj.h"
 
 #include "bucomm.h"
 #include "getopt.h"
@@ -108,6 +114,8 @@ int                     do_debug_abbrevs;
 int                     do_debug_lines;
 int                     do_debug_pubnames;
 int                     do_debug_aranges;
+int                     do_arch;
+int                     do_notes;
 int                    is_32bit_elf;
 
 /* A dynamic array of flags indicating which sections require dumping.  */
@@ -123,6 +131,7 @@ static bfd_vma (*         byte_get)                   PARAMS ((unsigned char *,
 static bfd_vma            byte_get_little_endian      PARAMS ((unsigned char *, int));
 static bfd_vma            byte_get_big_endian         PARAMS ((unsigned char *, int));
 static const char *       get_mips_dynamic_type       PARAMS ((unsigned long));
+static const char *       get_sparc64_dynamic_type    PARAMS ((unsigned long));
 static const char *       get_dynamic_type            PARAMS ((unsigned long));
 static int                dump_relocations            PARAMS ((FILE *, unsigned long, unsigned long, Elf_Internal_Sym *, unsigned long, char *, int));
 static char *             get_file_type               PARAMS ((unsigned));
@@ -170,7 +179,7 @@ static int                display_debug_abbrev        PARAMS ((Elf32_Internal_Sh
 static int                display_debug_aranges       PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
 static unsigned char *    process_abbrev_section      PARAMS ((unsigned char *, unsigned char *));
 static unsigned long      read_leb128                 PARAMS ((unsigned char *, int *, int));
-static int                process_extended_line_op    PARAMS ((unsigned char *, int));
+static int                process_extended_line_op    PARAMS ((unsigned char *, int, int));
 static void               reset_state_machine         PARAMS ((int));
 static char *             get_TAG_name                PARAMS ((unsigned long));
 static char *             get_AT_name                 PARAMS ((unsigned long));
@@ -186,6 +195,11 @@ static const char *       get_elf_class               PARAMS ((unsigned char));
 static const char *       get_data_encoding           PARAMS ((unsigned char));
 static const char *       get_osabi_name              PARAMS ((unsigned char));
 static int               guess_is_rela               PARAMS ((unsigned long));
+static char *            get_note_type                  PARAMS ((unsigned int));
+static int               process_note                   PARAMS ((Elf_External_Note *));
+static int               process_corefile_note_segment  PARAMS ((FILE *, unsigned long, unsigned long));
+static int               process_corefile_note_segments PARAMS ((FILE *));
+static int               process_corefile_contents      PARAMS ((FILE *));
 
 typedef int Elf32_Word;
 
@@ -200,7 +214,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 +353,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 +367,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 +401,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 +415,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);
@@ -414,6 +444,8 @@ guess_is_rela (e_machine)
       
       /* Targets that use RELA relocations.  */
     case EM_68K:
+    case EM_SPARC32PLUS:
+    case EM_SPARCV9:
     case EM_SPARC:
     case EM_PPC:
     case EM_CYGNUS_V850:
@@ -605,8 +637,16 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
        }
       else
        {
-         type         = ELF64_R_TYPE (info);
+         if (elf_header.e_machine == EM_SPARCV9)
+           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
@@ -699,7 +739,11 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
          break;
 
        case EM_PARISC:
-         rtype = elf32_hppa_reloc_type (type);
+         rtype = elf_hppa_reloc_type (type);
+         break;
+
+       case EM_PJ:
+         rtype = elf_pj_reloc_type (type);
          break;
        }
 
@@ -742,6 +786,10 @@ dump_relocations (file, rel_offset, rel_size, symtab, nsyms, strtab, is_rela)
       else if (is_rela)
        printf ("%34c%lx", ' ', (unsigned long) relas[i].r_addend);
 
+      if (elf_header.e_machine == EM_SPARCV9
+         && !strcmp (rtype, "R_SPARC_OLO10"))
+       printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (info));
+
       putchar ('\n');
     }
 
@@ -804,6 +852,18 @@ get_mips_dynamic_type (type)
     }
 }
 
+static const char *
+get_sparc64_dynamic_type (type)
+     unsigned long type;
+{
+  switch (type)
+    {
+    case DT_SPARC_REGISTER: return "SPARC_REGISTER";
+    default:
+      return NULL;
+    }
+}    
+
 static const char *
 get_dynamic_type (type)
      unsigned long type;
@@ -878,6 +938,9 @@ get_dynamic_type (type)
            case EM_MIPS_RS4_BE:
              result = get_mips_dynamic_type (type);
              break;
+           case EM_SPARCV9:
+             result = get_sparc64_dynamic_type (type);
+             break;
            default:
              result = NULL;
              break;
@@ -974,7 +1037,7 @@ get_machine_name (e_machine)
     case EM_CYGNUS_MN10300:    return "mn10300";
     case EM_CYGNUS_MN10200:    return "mn10200";
     case EM_CYGNUS_FR30:       return "Fujitsu FR30";
-
+    case EM_PJ:                 return "picoJava";
     default:
       sprintf (buff, _("<unknown>: %x"), e_machine);
       return buff;
@@ -1062,6 +1125,40 @@ get_machine_flags (e_flags, e_machine)
          if ((e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_4)
            strcat (buf, ", mips4");
          break;
+
+       case EM_SPARCV9:
+         if (e_flags & EF_SPARC_32PLUS)
+           strcat (buf, ", v8+");
+
+         if (e_flags & EF_SPARC_SUN_US1)
+           strcat (buf, ", ultrasparcI");
+
+         if (e_flags & EF_SPARC_SUN_US3)
+           strcat (buf, ", ultrasparcIII");
+
+         if (e_flags & EF_SPARC_HAL_R1)
+           strcat (buf, ", halr1");
+
+         if (e_flags & EF_SPARC_LEDATA)
+           strcat (buf, ", ledata");
+
+         if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
+           strcat (buf, ", tso");
+
+         if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
+           strcat (buf, ", pso");
+
+         if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
+           strcat (buf, ", rmo");
+         break;
+
+       case EM_PJ:
+         if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
+           strcat (buf, ", new calling convention");
+
+         if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
+           strcat (buf, ", gnu calling convention");
+         break;
        }
     }
 
@@ -1250,14 +1347,16 @@ 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'},
   {"symbols",          no_argument, 0, 's'},
   {"syms",             no_argument, 0, 's'},
   {"relocs",           no_argument, 0, 'r'},
+  {"notes",            no_argument, 0, 'n'},
   {"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'},
@@ -1276,7 +1375,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"));
@@ -1284,9 +1383,11 @@ usage ()
   fprintf (stdout, _("                            Display the sections' header\n"));
   fprintf (stdout, _("  -e or --headers           Equivalent to: -h -l -S\n"));
   fprintf (stdout, _("  -s or --syms or --symbols Display the symbol table\n"));
+  fprintf (stdout, _("  -n or --notes             Display the core notes (if present)\n"));
   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 <number> or --hex-dump=<number>\n"));
   fprintf (stdout, _("                            Dump the contents of section <number>\n"));
@@ -1296,7 +1397,7 @@ usage ()
   fprintf (stdout, _("  -i <number> or --instruction-dump=<number>\n"));
   fprintf (stdout, _("                            Disassemble the contents of section <number>\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"));
@@ -1346,7 +1447,7 @@ parse_args (argc, argv)
     usage ();
 
   while ((c = getopt_long
-         (argc, argv, "ersahldSDw::x:i:vV", options, NULL)) != EOF)
+         (argc, argv, "ersahnldSDAIw::x:i:vV", options, NULL)) != EOF)
     {
       char *    cp;
       int      section;
@@ -1369,12 +1470,17 @@ parse_args (argc, argv)
          do_segments ++;
          do_version ++;
          do_histogram ++;
+         do_arch ++;
+         do_notes ++;
          break;
        case 'e':
          do_header ++;
          do_sections ++;
          do_segments ++;
          break;
+       case 'A':
+         do_arch ++;
+         break;
        case 'D':
          do_using_dynamic ++;
          break;
@@ -1396,6 +1502,12 @@ parse_args (argc, argv)
        case 'd':
          do_dynamic ++;
          break;
+       case 'I':
+         do_histogram ++;
+         break;
+       case 'n':
+         do_notes ++;
+         break;
        case 'x':
          do_dump ++;
          section = strtoul (optarg, & cp, 0);
@@ -1474,7 +1586,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 && !do_notes)
     usage ();
   else if (argc < 3)
     {
@@ -1495,7 +1607,7 @@ get_elf_class (elf_class)
     case ELFCLASS32:   return _("ELF32");
     case ELFCLASS64:   return _("ELF64");
     default:
-      sprintf (buff, _("<unknown: %lx>"), elf_class);
+      sprintf (buff, _("<unknown: %x>"), elf_class);
       return buff;
     }
 }
@@ -1512,7 +1624,7 @@ get_data_encoding (encoding)
     case ELFDATA2LSB: return _("2's complement, little endian");
     case ELFDATA2MSB: return _("2's complement, big endian");
     default:          
-      sprintf (buff, _("<unknown: %lx>"), encoding);
+      sprintf (buff, _("<unknown: %x>"), encoding);
       return buff;
     }
 }
@@ -1529,7 +1641,7 @@ get_osabi_name (osabi)
     case ELFOSABI_HPUX:       return _("UNIX - HP-UX");
     case ELFOSABI_STANDALONE: return _("Standalone App");
     default:
-      sprintf (buff, _("<unknown: %lx>"), osabi);
+      sprintf (buff, _("<unknown: %x>"), osabi);
       return buff;
     }
 }
@@ -1563,9 +1675,11 @@ process_file_header ()
              get_data_encoding (elf_header.e_ident [EI_DATA]));
       printf (_("  Version:                           %d %s\n"),
              elf_header.e_ident [EI_VERSION],
-             elf_header.e_ident [EI_VERSION] == EV_CURRENT ? "(current)" :
-             elf_header.e_ident [EI_VERSION] != EV_NONE ? "<unknown: %lx>" : "",
-             elf_header.e_ident [EI_VERSION]);
+             (elf_header.e_ident [EI_VERSION] == EV_CURRENT
+              ? "(current)"
+              : (elf_header.e_ident [EI_VERSION] != EV_NONE
+                 ? "<unknown: %lx>"
+                 : "")));
       printf (_("  OS/ABI:                            %s\n"),
              get_osabi_name (elf_header.e_ident [EI_OSABI]));
       printf (_("  ABI Version:                       %d\n"),
@@ -1810,7 +1924,7 @@ process_program_headers (file)
                      ? (section->sh_addr >= segment->p_vaddr
                         && section->sh_addr + section->sh_size
                         <= segment->p_vaddr + segment->p_memsz)
-                     : (section->sh_offset >= segment->p_offset
+                     : ((bfd_vma) section->sh_offset >= segment->p_offset
                         && (section->sh_offset + section->sh_size
                             <= segment->p_offset + segment->p_filesz))))
                printf ("%s ", SECTION_NAME (section));
@@ -2135,7 +2249,7 @@ process_relocs (file)
 
   if (do_using_dynamic)
     {
-      int is_rela;
+      int is_rela = FALSE;
 
       rel_size   = 0;
       rel_offset = 0;
@@ -2553,8 +2667,8 @@ process_dynamic_segment (file)
     }
 
   if (do_dynamic && dynamic_addr)
-    printf (_("\nDynamic segment at offset 0x%x contains %d entries:\n"),
-           dynamic_addr, dynamic_size);
+    printf (_("\nDynamic segment at offset 0x%x contains %ld entries:\n"),
+           dynamic_addr, (long) dynamic_size);
   if (do_dynamic)
     printf (_("  Tag        Type                         Name/Value\n"));
 
@@ -3388,7 +3502,15 @@ get_symbol_type (type)
     case STT_FILE:     return _("FILE");
     default:
       if (type >= STT_LOPROC && type <= STT_HIPROC)
-       sprintf (buff, _("<processor specific>: %d"), type);
+       {
+         if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
+           return _("THUMB_FUNC");
+           
+         if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
+           return _("REGISTER");
+         
+         sprintf (buff, _("<processor specific>: %d"), type);
+       }
       else if (type >= STT_LOOS && type <= STT_HIOS)
        sprintf (buff, _("<OS specific>: %d"), type);
       else
@@ -3471,7 +3593,7 @@ process_symbol_table (file)
   Elf32_Internal_Shdr *   section;
   char   nb [4];
   char   nc [4];
-  int    nbuckets;
+  int    nbuckets = 0;
   int    nchains;
   int *  buckets = NULL;
   int *  chains = NULL;
@@ -3806,9 +3928,9 @@ process_symbol_table (file)
 
 static int
 process_syminfo (file)
-     FILE * file;
+     FILE * file ATTRIBUTE_UNUSED;
 {
-  int i;
+  unsigned int i;
 
   if (dynamic_syminfo == NULL
       || !do_dynamic)
@@ -3916,7 +4038,7 @@ dump_section (section, file)
 
       lbytes = (bytes > 16 ? 16 : bytes);
 
-      printf ("  0x%8.8x ", addr);
+      printf ("  0x%8.8lx ", (unsigned long) addr);
 
       switch (elf_header.e_ident [EI_DATA])
        {
@@ -4035,9 +4157,10 @@ reset_state_machine (is_stmt)
 /* Handled an extend line op.  Returns true if this is the end
    of sequence.  */
 static int
-process_extended_line_op (data, is_stmt)
+process_extended_line_op (data, is_stmt, pointer_size)
      unsigned char * data;
      int is_stmt;
+     int pointer_size;
 {
   unsigned char   op_code;
   int             bytes_read;
@@ -4067,8 +4190,7 @@ process_extended_line_op (data, is_stmt)
       break;
 
     case DW_LNE_set_address:
-      /* XXX - assumption here that address size is 4! */
-      adr = byte_get (data, 4);
+      adr = byte_get (data, pointer_size);
       printf (_("set Address to 0x%lx\n"), adr);
       state_machine_regs.address = adr;
       break;
@@ -4096,12 +4218,16 @@ process_extended_line_op (data, is_stmt)
   return len;
 }
 
+/* Size of pointers in the .debug_line section.  This information is not
+   really present in that section.  It's obtained before dumping the debug
+   sections by doing some pre-scan of the .debug_info section.  */
+static int debug_line_pointer_size = 4;
 
 static int
 display_debug_lines (section, start, file)
      Elf32_Internal_Shdr * section;
      unsigned char *       start;
-     FILE *                file;
+     FILE *                file ATTRIBUTE_UNUSED;
 {
   DWARF2_External_LineInfo * external;
   DWARF2_Internal_LineInfo   info;
@@ -4165,7 +4291,7 @@ display_debug_lines (section, start, file)
       printf (_("\n Opcodes:\n"));
       
       for (i = 1; i < info.li_opcode_base; i++)
-       printf (_("  Opcode %d has %d args\n"), i, standard_opcodes[i]);
+       printf (_("  Opcode %d has %d args\n"), i, standard_opcodes[i - 1]);
       
       /* Display the contents of the Directory table.  */
       data = standard_opcodes + info.li_opcode_base - 1;
@@ -4233,7 +4359,8 @@ display_debug_lines (section, start, file)
          switch (op_code)
            {
            case DW_LNS_extended_op:
-             data += process_extended_line_op (data, info.li_default_is_stmt);
+             data += process_extended_line_op (data, info.li_default_is_stmt,
+                                                debug_line_pointer_size);
              break;
              
            case DW_LNS_copy:
@@ -4284,7 +4411,8 @@ display_debug_lines (section, start, file)
              break;
              
            case DW_LNS_const_add_pc:
-             adv = (255 - info.li_opcode_base) / info.li_line_range;
+             adv = (((255 - info.li_opcode_base) / info.li_line_range)
+                    * info.li_min_insn_length);
              state_machine_regs.address += adv;
              printf (_("  Advance PC by constant %d to 0x%lx\n"), adv,
                      state_machine_regs.address);
@@ -4304,7 +4432,7 @@ display_debug_lines (section, start, file)
              state_machine_regs.address += adv;
              printf (_("  Special opcode %d: advance Address by %d to 0x%lx"),
                      op_code, adv, state_machine_regs.address);
-             adv    += (op_code % info.li_line_range) + info.li_line_base;
+             adv = (op_code % info.li_line_range) + info.li_line_base;
              state_machine_regs.line += adv;
              printf (_(" and Line by %d to %d\n"),
                      adv, state_machine_regs.line);
@@ -4321,7 +4449,7 @@ static int
 display_debug_pubnames (section, start, file)
      Elf32_Internal_Shdr * section;
      unsigned char *       start;
-     FILE *                file;
+     FILE *                file ATTRIBUTE_UNUSED;
 {
   DWARF2_External_PubNames * external;
   DWARF2_Internal_PubNames   pubnames;
@@ -4709,8 +4837,11 @@ process_abbrev_section (start, end)
       entry = read_leb128 (start, & bytes_read, 0);
       start += bytes_read;
 
+      /* A single zero is supposed to end the section according
+        to the standard.  If there's more, then signal that to
+        the caller.  */
       if (entry == 0)
-       return start;
+       return start == end ? NULL : start;
 
       tag = read_leb128 (start, & bytes_read, 0);
       start += bytes_read;
@@ -4743,7 +4874,7 @@ static int
 display_debug_abbrev (section, start, file)
      Elf32_Internal_Shdr * section;
      unsigned char *       start;
-     FILE *                file;
+     FILE *                file ATTRIBUTE_UNUSED;
 {
   abbrev_entry * entry;
   unsigned char * end = start + section->sh_size;
@@ -4789,7 +4920,7 @@ display_block (data, length)
   printf (_(" %lu byte block: "), length);
 
   while (length --)
-    printf ("%lx ", byte_get (data ++, 1));
+    printf ("%lx ", (unsigned long) byte_get (data ++, 1));
 
   return data;
 }
@@ -4801,156 +4932,451 @@ decode_location_expression (data, pointer_size)
 {
   unsigned char op;
   int           bytes_read;
+  unsigned long uvalue;
 
   op = * data ++;
 
   switch (op)
     {
-    case DW_OP_addr:   printf ("DW_OP_addr: %lx", byte_get (data, pointer_size)); break;
-    case DW_OP_deref:  printf ("DW_OP_deref"); break;
-    case DW_OP_const1u:        printf ("DW_OP_const1u: %lu", byte_get (data, 1)); break;
-    case DW_OP_const1s:        printf ("DW_OP_const1s: %ld", (long) byte_get (data, 1)); break;
-    case DW_OP_const2u:        printf ("DW_OP_const2u: %lu", byte_get (data, 2)); break;
-    case DW_OP_const2s:        printf ("DW_OP_const2s: %ld", (long) byte_get (data, 2)); break;
-    case DW_OP_const4u:        printf ("DW_OP_const4u: %lu", byte_get (data, 4)); break;
-    case DW_OP_const4s:        printf ("DW_OP_const4s: %ld", (long) byte_get (data, 4)); break;
-    case DW_OP_const8u:        printf ("DW_OP_const8u: %lu %lu", byte_get (data, 4), byte_get (data + 4, 4)); break;
-    case DW_OP_const8s:        printf ("DW_OP_const8s: %ld %ld", byte_get (data, 4), byte_get (data + 4, 4)); break;
-    case DW_OP_constu: printf ("DW_OP_constu: %lu", read_leb128 (data, NULL, 0)); break;
-    case DW_OP_consts: printf ("DW_OP_consts: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_dup:    printf ("DW_OP_dup"); break;
-    case DW_OP_drop:   printf ("DW_OP_drop"); break;
-    case DW_OP_over:   printf ("DW_OP_over"); break;
-    case DW_OP_pick:   printf ("DW_OP_pick: %ld", byte_get (data, 1)); break;
-    case DW_OP_swap:   printf ("DW_OP_swap"); break;
-    case DW_OP_rot:    printf ("DW_OP_rot"); break;
-    case DW_OP_xderef: printf ("DW_OP_xderef"); break;
-    case DW_OP_abs:    printf ("DW_OP_abs"); break;
-    case DW_OP_and:    printf ("DW_OP_and"); break;
-    case DW_OP_div:    printf ("DW_OP_div"); break;
-    case DW_OP_minus:  printf ("DW_OP_minus"); break;
-    case DW_OP_mod:    printf ("DW_OP_mod"); break;
-    case DW_OP_mul:    printf ("DW_OP_mul"); break;
-    case DW_OP_neg:    printf ("DW_OP_neg"); break;
-    case DW_OP_not:    printf ("DW_OP_not"); break;
-    case DW_OP_or:     printf ("DW_OP_or"); break;
-    case DW_OP_plus:   printf ("DW_OP_plus"); break;
-    case DW_OP_plus_uconst:    printf ("DW_OP_plus_uconst: %lu", read_leb128 (data, NULL, 0)); break;
-    case DW_OP_shl:    printf ("DW_OP_shl"); break;
-    case DW_OP_shr:    printf ("DW_OP_shr"); break;
-    case DW_OP_shra:   printf ("DW_OP_shra"); break;
-    case DW_OP_xor:    printf ("DW_OP_xor"); break;
-    case DW_OP_bra:    printf ("DW_OP_bra: %ld", byte_get (data, 2)); break;
-    case DW_OP_eq:     printf ("DW_OP_eq"); break;
-    case DW_OP_ge:     printf ("DW_OP_ge"); break;
-    case DW_OP_gt:     printf ("DW_OP_gt"); break;
-    case DW_OP_le:     printf ("DW_OP_le"); break;
-    case DW_OP_lt:     printf ("DW_OP_lt"); break;
-    case DW_OP_ne:     printf ("DW_OP_ne"); break;
-    case DW_OP_skip:   printf ("DW_OP_skip: %ld", byte_get (data, 2)); break;
-    case DW_OP_lit0:   printf ("DW_OP_lit0"); break;
-    case DW_OP_lit1:   printf ("DW_OP_lit1"); break;
-    case DW_OP_lit2:   printf ("DW_OP_lit2"); break;
-    case DW_OP_lit3:   printf ("DW_OP_lit3"); break;
-    case DW_OP_lit4:   printf ("DW_OP_lit4"); break;
-    case DW_OP_lit5:   printf ("DW_OP_lit5"); break;
-    case DW_OP_lit6:   printf ("DW_OP_lit6"); break;
-    case DW_OP_lit7:   printf ("DW_OP_lit7"); break;
-    case DW_OP_lit8:   printf ("DW_OP_lit8"); break;
-    case DW_OP_lit9:   printf ("DW_OP_lit9"); break;
-    case DW_OP_lit10:  printf ("DW_OP_lit10"); break;
-    case DW_OP_lit11:  printf ("DW_OP_lit11"); break;
-    case DW_OP_lit12:  printf ("DW_OP_lit12"); break;
-    case DW_OP_lit13:  printf ("DW_OP_lit13"); break;
-    case DW_OP_lit14:  printf ("DW_OP_lit14"); break;
-    case DW_OP_lit15:  printf ("DW_OP_lit15"); break;
-    case DW_OP_lit16:  printf ("DW_OP_lit16"); break;
-    case DW_OP_lit17:  printf ("DW_OP_lit17"); break;
-    case DW_OP_lit18:  printf ("DW_OP_lit18"); break;
-    case DW_OP_lit19:  printf ("DW_OP_lit19"); break;
-    case DW_OP_lit20:  printf ("DW_OP_lit20"); break;
-    case DW_OP_lit21:  printf ("DW_OP_lit21"); break;
-    case DW_OP_lit22:  printf ("DW_OP_lit22"); break;
-    case DW_OP_lit23:  printf ("DW_OP_lit23"); break;
-    case DW_OP_lit24:  printf ("DW_OP_lit24"); break;
-    case DW_OP_lit25:  printf ("DW_OP_lit25"); break;
-    case DW_OP_lit26:  printf ("DW_OP_lit26"); break;
-    case DW_OP_lit27:  printf ("DW_OP_lit27"); break;
-    case DW_OP_lit28:  printf ("DW_OP_lit28"); break;
-    case DW_OP_lit29:  printf ("DW_OP_lit29"); break;
-    case DW_OP_lit30:  printf ("DW_OP_lit30"); break;
-    case DW_OP_lit31:  printf ("DW_OP_lit31"); break;
-    case DW_OP_reg0:   printf ("DW_OP_reg0"); break;
-    case DW_OP_reg1:   printf ("DW_OP_reg1"); break;
-    case DW_OP_reg2:   printf ("DW_OP_reg2"); break;
-    case DW_OP_reg3:   printf ("DW_OP_reg3"); break;
-    case DW_OP_reg4:   printf ("DW_OP_reg4"); break;
-    case DW_OP_reg5:   printf ("DW_OP_reg5"); break;
-    case DW_OP_reg6:   printf ("DW_OP_reg6"); break;
-    case DW_OP_reg7:   printf ("DW_OP_reg7"); break;
-    case DW_OP_reg8:   printf ("DW_OP_reg8"); break;
-    case DW_OP_reg9:   printf ("DW_OP_reg9"); break;
-    case DW_OP_reg10:  printf ("DW_OP_reg10"); break;
-    case DW_OP_reg11:  printf ("DW_OP_reg11"); break;
-    case DW_OP_reg12:  printf ("DW_OP_reg12"); break;
-    case DW_OP_reg13:  printf ("DW_OP_reg13"); break;
-    case DW_OP_reg14:  printf ("DW_OP_reg14"); break;
-    case DW_OP_reg15:  printf ("DW_OP_reg15"); break;
-    case DW_OP_reg16:  printf ("DW_OP_reg16"); break;
-    case DW_OP_reg17:  printf ("DW_OP_reg17"); break;
-    case DW_OP_reg18:  printf ("DW_OP_reg18"); break;
-    case DW_OP_reg19:  printf ("DW_OP_reg19"); break;
-    case DW_OP_reg20:  printf ("DW_OP_reg20"); break;
-    case DW_OP_reg21:  printf ("DW_OP_reg21"); break;
-    case DW_OP_reg22:  printf ("DW_OP_reg22"); break;
-    case DW_OP_reg23:  printf ("DW_OP_reg23"); break;
-    case DW_OP_reg24:  printf ("DW_OP_reg24"); break;
-    case DW_OP_reg25:  printf ("DW_OP_reg25"); break;
-    case DW_OP_reg26:  printf ("DW_OP_reg26"); break;
-    case DW_OP_reg27:  printf ("DW_OP_reg27"); break;
-    case DW_OP_reg28:  printf ("DW_OP_reg28"); break;
-    case DW_OP_reg29:  printf ("DW_OP_reg29"); break;
-    case DW_OP_reg30:  printf ("DW_OP_reg30"); break;
-    case DW_OP_reg31:  printf ("DW_OP_reg31"); break;
-    case DW_OP_breg0:  printf ("DW_OP_breg0: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg1:  printf ("DW_OP_breg1: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg2:  printf ("DW_OP_breg2: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg3:  printf ("DW_OP_breg3: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg4:  printf ("DW_OP_breg4: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg5:  printf ("DW_OP_breg5: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg6:  printf ("DW_OP_breg6: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg7:  printf ("DW_OP_breg7: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg8:  printf ("DW_OP_breg8: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg9:  printf ("DW_OP_breg9: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg10: printf ("DW_OP_breg10: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg11: printf ("DW_OP_breg11: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg12: printf ("DW_OP_breg12: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg13: printf ("DW_OP_breg13: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg14: printf ("DW_OP_breg14: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg15: printf ("DW_OP_breg15: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg16: printf ("DW_OP_breg16: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg17: printf ("DW_OP_breg17: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg18: printf ("DW_OP_breg18: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg19: printf ("DW_OP_breg19: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg20: printf ("DW_OP_breg20: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg21: printf ("DW_OP_breg21: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg22: printf ("DW_OP_breg22: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg23: printf ("DW_OP_breg23: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg24: printf ("DW_OP_breg24: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg25: printf ("DW_OP_breg25: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg26: printf ("DW_OP_breg26: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg27: printf ("DW_OP_breg27: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg28: printf ("DW_OP_breg28: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg29: printf ("DW_OP_breg29: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg30: printf ("DW_OP_breg30: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_breg31: printf ("DW_OP_breg31: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_regx:   printf ("DW_OP_regx: %lu", read_leb128 (data, NULL, 0)); break;
-    case DW_OP_fbreg:  printf ("DW_OP_fbreg: %ld", read_leb128 (data, NULL, 1)); break;
-    case DW_OP_bregx:  printf ("DW_OP_bregx: %lu %ld", read_leb128 (data, & bytes_read, 0), read_leb128 (data + bytes_read, NULL, 1)); break;
-    case DW_OP_piece:  printf ("DW_OP_piece: %lu", read_leb128 (data, NULL, 0)); break;
-    case DW_OP_deref_size:     printf ("DW_OP_deref_size: %ld", byte_get (data, 1)); break;
-    case DW_OP_xderef_size:    printf ("DW_OP_xderef_size: %ld", byte_get (data, 1)); break;
-    case DW_OP_nop:    printf ("DW_OP_nop"); break;
+    case DW_OP_addr:
+      printf ("DW_OP_addr: %lx", (unsigned long) byte_get (data, pointer_size));
+      break;
+    case DW_OP_deref:
+      printf ("DW_OP_deref");
+      break;
+    case DW_OP_const1u:
+      printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data, 1));
+      break;
+    case DW_OP_const1s:
+      printf ("DW_OP_const1s: %ld", (long) byte_get (data, 1));
+      break;
+    case DW_OP_const2u:
+      printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
+      break;
+    case DW_OP_const2s:
+      printf ("DW_OP_const2s: %ld", (long) byte_get (data, 2));
+      break;
+    case DW_OP_const4u:
+      printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
+      break;
+    case DW_OP_const4s:
+      printf ("DW_OP_const4s: %ld", (long) byte_get (data, 4));
+      break;
+    case DW_OP_const8u:
+      printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
+             (unsigned long) byte_get (data + 4, 4));
+      break;
+    case DW_OP_const8s:
+      printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
+             (long) byte_get (data + 4, 4));
+      break;
+    case DW_OP_constu:
+      printf ("DW_OP_constu: %lu", read_leb128 (data, NULL, 0));
+      break;
+    case DW_OP_consts:
+      printf ("DW_OP_consts: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_dup:
+      printf ("DW_OP_dup");
+      break;
+    case DW_OP_drop:
+      printf ("DW_OP_drop");
+      break;
+    case DW_OP_over:
+      printf ("DW_OP_over");
+      break;
+    case DW_OP_pick:
+      printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data, 1));
+      break;
+    case DW_OP_swap:
+      printf ("DW_OP_swap");
+      break;
+    case DW_OP_rot:
+      printf ("DW_OP_rot");
+      break;
+    case DW_OP_xderef:
+      printf ("DW_OP_xderef");
+      break;
+    case DW_OP_abs:
+      printf ("DW_OP_abs");
+      break;
+    case DW_OP_and:
+      printf ("DW_OP_and");
+      break;
+    case DW_OP_div:
+      printf ("DW_OP_div");
+      break;
+    case DW_OP_minus:
+      printf ("DW_OP_minus");
+      break;
+    case DW_OP_mod:
+      printf ("DW_OP_mod");
+      break;
+    case DW_OP_mul:
+      printf ("DW_OP_mul");
+      break;
+    case DW_OP_neg:
+      printf ("DW_OP_neg");
+      break;
+    case DW_OP_not:
+      printf ("DW_OP_not");
+      break;
+    case DW_OP_or:
+      printf ("DW_OP_or");
+      break;
+    case DW_OP_plus:
+      printf ("DW_OP_plus");
+      break;
+    case DW_OP_plus_uconst:
+      printf ("DW_OP_plus_uconst: %lu", read_leb128 (data, NULL, 0));
+      break;
+    case DW_OP_shl:
+      printf ("DW_OP_shl");
+      break;
+    case DW_OP_shr:
+      printf ("DW_OP_shr");
+      break;
+    case DW_OP_shra:
+      printf ("DW_OP_shra");
+      break;
+    case DW_OP_xor:
+      printf ("DW_OP_xor");
+      break;
+    case DW_OP_bra:
+      printf ("DW_OP_bra: %ld", (long) byte_get (data, 2));
+      break;
+    case DW_OP_eq:
+      printf ("DW_OP_eq");
+      break;
+    case DW_OP_ge:
+      printf ("DW_OP_ge");
+      break;
+    case DW_OP_gt:
+      printf ("DW_OP_gt");
+      break;
+    case DW_OP_le:
+      printf ("DW_OP_le");
+      break;
+    case DW_OP_lt:
+      printf ("DW_OP_lt");
+      break;
+    case DW_OP_ne:
+      printf ("DW_OP_ne");
+      break;
+    case DW_OP_skip:
+      printf ("DW_OP_skip: %ld", (long) byte_get (data, 2));
+      break;
+    case DW_OP_lit0:
+      printf ("DW_OP_lit0");
+      break;
+    case DW_OP_lit1:
+      printf ("DW_OP_lit1");
+      break;
+    case DW_OP_lit2:
+      printf ("DW_OP_lit2");
+      break;
+    case DW_OP_lit3:
+      printf ("DW_OP_lit3");
+      break;
+    case DW_OP_lit4:
+      printf ("DW_OP_lit4");
+      break;
+    case DW_OP_lit5:
+      printf ("DW_OP_lit5");
+      break;
+    case DW_OP_lit6:
+      printf ("DW_OP_lit6");
+      break;
+    case DW_OP_lit7:
+      printf ("DW_OP_lit7");
+      break;
+    case DW_OP_lit8:
+      printf ("DW_OP_lit8");
+      break;
+    case DW_OP_lit9:
+      printf ("DW_OP_lit9");
+      break;
+    case DW_OP_lit10:
+      printf ("DW_OP_lit10");
+      break;
+    case DW_OP_lit11:
+      printf ("DW_OP_lit11");
+      break;
+    case DW_OP_lit12:
+      printf ("DW_OP_lit12");
+      break;
+    case DW_OP_lit13:
+      printf ("DW_OP_lit13");
+      break;
+    case DW_OP_lit14:
+      printf ("DW_OP_lit14");
+      break;
+    case DW_OP_lit15:
+      printf ("DW_OP_lit15");
+      break;
+    case DW_OP_lit16:
+      printf ("DW_OP_lit16");
+      break;
+    case DW_OP_lit17:
+      printf ("DW_OP_lit17");
+      break;
+    case DW_OP_lit18:
+      printf ("DW_OP_lit18");
+      break;
+    case DW_OP_lit19:
+      printf ("DW_OP_lit19");
+      break;
+    case DW_OP_lit20:
+      printf ("DW_OP_lit20");
+      break;
+    case DW_OP_lit21:
+      printf ("DW_OP_lit21");
+      break;
+    case DW_OP_lit22:
+      printf ("DW_OP_lit22");
+      break;
+    case DW_OP_lit23:
+      printf ("DW_OP_lit23");
+      break;
+    case DW_OP_lit24:
+      printf ("DW_OP_lit24");
+      break;
+    case DW_OP_lit25:
+      printf ("DW_OP_lit25");
+      break;
+    case DW_OP_lit26:
+      printf ("DW_OP_lit26");
+      break;
+    case DW_OP_lit27:
+      printf ("DW_OP_lit27");
+      break;
+    case DW_OP_lit28:
+      printf ("DW_OP_lit28");
+      break;
+    case DW_OP_lit29:
+      printf ("DW_OP_lit29");
+      break;
+    case DW_OP_lit30:
+      printf ("DW_OP_lit30");
+      break;
+    case DW_OP_lit31:
+      printf ("DW_OP_lit31");
+      break;
+    case DW_OP_reg0:
+      printf ("DW_OP_reg0");
+      break;
+    case DW_OP_reg1:
+      printf ("DW_OP_reg1");
+      break;
+    case DW_OP_reg2:
+      printf ("DW_OP_reg2");
+      break;
+    case DW_OP_reg3:
+      printf ("DW_OP_reg3");
+      break;
+    case DW_OP_reg4:
+      printf ("DW_OP_reg4");
+      break;
+    case DW_OP_reg5:
+      printf ("DW_OP_reg5");
+      break;
+    case DW_OP_reg6:
+      printf ("DW_OP_reg6");
+      break;
+    case DW_OP_reg7:
+      printf ("DW_OP_reg7");
+      break;
+    case DW_OP_reg8:
+      printf ("DW_OP_reg8");
+      break;
+    case DW_OP_reg9:
+      printf ("DW_OP_reg9");
+      break;
+    case DW_OP_reg10:
+      printf ("DW_OP_reg10");
+      break;
+    case DW_OP_reg11:
+      printf ("DW_OP_reg11");
+      break;
+    case DW_OP_reg12:
+      printf ("DW_OP_reg12");
+      break;
+    case DW_OP_reg13:
+      printf ("DW_OP_reg13");
+      break;
+    case DW_OP_reg14:
+      printf ("DW_OP_reg14");
+      break;
+    case DW_OP_reg15:
+      printf ("DW_OP_reg15");
+      break;
+    case DW_OP_reg16:
+      printf ("DW_OP_reg16");
+      break;
+    case DW_OP_reg17:
+      printf ("DW_OP_reg17");
+      break;
+    case DW_OP_reg18:
+      printf ("DW_OP_reg18");
+      break;
+    case DW_OP_reg19:
+      printf ("DW_OP_reg19");
+      break;
+    case DW_OP_reg20:
+      printf ("DW_OP_reg20");
+      break;
+    case DW_OP_reg21:
+      printf ("DW_OP_reg21");
+      break;
+    case DW_OP_reg22:
+      printf ("DW_OP_reg22");
+      break;
+    case DW_OP_reg23:
+      printf ("DW_OP_reg23");
+      break;
+    case DW_OP_reg24:
+      printf ("DW_OP_reg24");
+      break;
+    case DW_OP_reg25:
+      printf ("DW_OP_reg25");
+      break;
+    case DW_OP_reg26:
+      printf ("DW_OP_reg26");
+      break;
+    case DW_OP_reg27:
+      printf ("DW_OP_reg27");
+      break;
+    case DW_OP_reg28:
+      printf ("DW_OP_reg28");
+      break;
+    case DW_OP_reg29:
+      printf ("DW_OP_reg29");
+      break;
+    case DW_OP_reg30:
+      printf ("DW_OP_reg30");
+      break;
+    case DW_OP_reg31:
+      printf ("DW_OP_reg31");
+      break;
+    case DW_OP_breg0:
+      printf ("DW_OP_breg0: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg1:
+      printf ("DW_OP_breg1: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg2:
+      printf ("DW_OP_breg2: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg3:
+      printf ("DW_OP_breg3: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg4:
+      printf ("DW_OP_breg4: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg5:
+      printf ("DW_OP_breg5: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg6:
+      printf ("DW_OP_breg6: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg7:
+      printf ("DW_OP_breg7: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg8:
+      printf ("DW_OP_breg8: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg9:
+      printf ("DW_OP_breg9: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg10:
+      printf ("DW_OP_breg10: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg11:
+      printf ("DW_OP_breg11: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg12:
+      printf ("DW_OP_breg12: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg13:
+      printf ("DW_OP_breg13: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg14:
+      printf ("DW_OP_breg14: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg15:
+      printf ("DW_OP_breg15: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg16:
+      printf ("DW_OP_breg16: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg17:
+      printf ("DW_OP_breg17: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg18:
+      printf ("DW_OP_breg18: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg19:
+      printf ("DW_OP_breg19: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg20:
+      printf ("DW_OP_breg20: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg21:
+      printf ("DW_OP_breg21: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg22:
+      printf ("DW_OP_breg22: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg23:
+      printf ("DW_OP_breg23: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg24:
+      printf ("DW_OP_breg24: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg25:
+      printf ("DW_OP_breg25: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg26:
+      printf ("DW_OP_breg26: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg27:
+      printf ("DW_OP_breg27: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg28:
+      printf ("DW_OP_breg28: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg29:
+      printf ("DW_OP_breg29: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg30:
+      printf ("DW_OP_breg30: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_breg31:
+      printf ("DW_OP_breg31: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_regx:
+      printf ("DW_OP_regx: %lu", read_leb128 (data, NULL, 0));
+      break;
+    case DW_OP_fbreg:
+      printf ("DW_OP_fbreg: %ld", read_leb128 (data, NULL, 1));
+      break;
+    case DW_OP_bregx:
+      uvalue = read_leb128 (data, &bytes_read, 0);
+      printf ("DW_OP_bregx: %lu %ld", uvalue,
+             read_leb128 (data + bytes_read, NULL, 1));
+      break;
+    case DW_OP_piece:
+      printf ("DW_OP_piece: %lu", read_leb128 (data, NULL, 0));
+      break;
+    case DW_OP_deref_size:
+      printf ("DW_OP_deref_size: %ld", (long) byte_get (data, 1));
+      break;
+    case DW_OP_xderef_size:
+      printf ("DW_OP_xderef_size: %ld", (long) byte_get (data, 1));
+      break;
+    case DW_OP_nop:
+      printf ("DW_OP_nop");
+      break;
 
     default:
       if (op >= DW_OP_lo_user
@@ -4970,8 +5396,8 @@ read_and_display_attr (attribute, form, data, pointer_size)
      unsigned char * data;
      unsigned long   pointer_size;
 {
-  unsigned long   uvalue;
-  unsigned char * block_start;
+  unsigned long   uvalue = 0;
+  unsigned char * block_start = NULL;
   int             bytes_read;
   int            is_ref = 0;
 
@@ -5022,7 +5448,7 @@ read_and_display_attr (attribute, form, data, pointer_size)
     case DW_FORM_data8:
       uvalue = byte_get (data, 4);
       printf (" %lx", uvalue);
-      printf (" %lx", byte_get (data + 4, 4));
+      printf (" %lx", (unsigned long) byte_get (data + 4, 4));
       data += 8;
       break;
 
@@ -5292,7 +5718,7 @@ display_debug_info (section, start, file)
       while (tags < start)
        {
          int            bytes_read;
-         int            abbrev_number;
+         unsigned long  abbrev_number;
          abbrev_entry * entry;
          abbrev_attr  * attr;
 
@@ -5315,12 +5741,12 @@ display_debug_info (section, start, file)
 
          if (entry == NULL)
            {
-             warn (_("Unable to locate entry %d in the abbreviation table\n"),
+             warn (_("Unable to locate entry %lu in the abbreviation table\n"),
                    abbrev_number);
              return 0;
            }
 
-         printf (_(" <%d><%x>: Abbrev Number: %d (%s)\n"),
+         printf (_(" <%d><%x>: Abbrev Number: %lu (%s)\n"),
                  level, tags - section_begin - bytes_read,
                  abbrev_number,
                  get_TAG_name (entry->tag));
@@ -5345,7 +5771,7 @@ static int
 display_debug_aranges (section, start, file)
      Elf32_Internal_Shdr * section;
      unsigned char *       start;
-     FILE *                file;
+     FILE *                file ATTRIBUTE_UNUSED;
 {
   unsigned char * end = start + section->sh_size;
 
@@ -5358,6 +5784,7 @@ display_debug_aranges (section, start, file)
       unsigned char *          ranges;
       unsigned long            length;
       unsigned long            address;
+      int                     excess;
 
       external = (DWARF2_External_ARange *) start;
 
@@ -5377,19 +5804,25 @@ display_debug_aranges (section, start, file)
 
       ranges = start + sizeof (* external);
 
+      /* Must pad to an alignment boundary that is twice the pointer size.  */
+      excess = sizeof (*external) % (2 * arange.ar_pointer_size);
+      if (excess)
+       ranges += (2 * arange.ar_pointer_size) - excess;
+
       for (;;)
        {
          address = byte_get (ranges, arange.ar_pointer_size);
 
-         if (address == 0)
-           break;
-
          ranges += arange.ar_pointer_size;
 
          length  = byte_get (ranges, arange.ar_pointer_size);
 
          ranges += arange.ar_pointer_size;
 
+         /* A pair of zeros marks the end of the list.  */
+         if (address == 0 && length == 0)
+           break;
+         
          printf ("    %8.8lx %lu\n", address, length);
        }
 
@@ -5405,8 +5838,8 @@ display_debug_aranges (section, start, file)
 static int
 display_debug_not_supported (section, start, file)
      Elf32_Internal_Shdr * section;
-     unsigned char *       start;
-     FILE *                file;
+     unsigned char *       start ATTRIBUTE_UNUSED;
+     FILE *                file ATTRIBUTE_UNUSED;
 {
   printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
            SECTION_NAME (section));
@@ -5414,27 +5847,47 @@ display_debug_not_supported (section, start, file)
   return 1;
 }
 
+/* Pre-scan the .debug_info section to record the size of address.
+   When dumping the .debug_line, we use that size information, assuming
+   that all compilation units have the same address size.  */
+static int
+prescan_debug_info (section, start, file)
+     Elf32_Internal_Shdr * section ATTRIBUTE_UNUSED;
+     unsigned char *       start;
+     FILE *                file ATTRIBUTE_UNUSED;
+{
+  DWARF2_External_CompUnit * external;
+
+  external = (DWARF2_External_CompUnit *) start;
+
+  debug_line_pointer_size = BYTE_GET (external->cu_pointer_size);
+  return 0;
+}
+
   /* A structure containing the name of a debug section and a pointer
-     to a function that can decode it.  */
+     to a function that can decode it.  The third field is a prescan
+     function to be run over the section before displaying any of the
+     sections.  */
 struct
 {
   char * name;
-  int (* display) PARAMS((Elf32_Internal_Shdr *, unsigned char *, FILE *));
+  int (* display) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
+  int (* prescan) PARAMS ((Elf32_Internal_Shdr *, unsigned char *, FILE *));
 }
 debug_displays[] =
 {
-  { ".debug_info",        display_debug_info },
-  { ".debug_abbrev",      display_debug_abbrev },
-  { ".debug_line",        display_debug_lines },
-  { ".debug_aranges",     display_debug_aranges },
-  { ".debug_pubnames",    display_debug_pubnames },
-  { ".debug_macinfo",     display_debug_not_supported },
-  { ".debug_frame",       display_debug_not_supported },
-  { ".debug_str",         display_debug_not_supported },
-  { ".debug_static_func", display_debug_not_supported },
-  { ".debug_static_vars", display_debug_not_supported },
-  { ".debug_types",       display_debug_not_supported },
-  { ".debug_weaknames",   display_debug_not_supported }
+  { ".debug_info",        display_debug_info, prescan_debug_info },
+  { ".debug_abbrev",      display_debug_abbrev, NULL },
+  { ".debug_line",        display_debug_lines, NULL },
+  { ".debug_aranges",     display_debug_aranges, NULL },
+  { ".debug_pubnames",    display_debug_pubnames, NULL },
+  { ".debug_macinfo",     display_debug_not_supported, NULL },
+  { ".debug_frame",       display_debug_not_supported, NULL },
+  { ".debug_str",         display_debug_not_supported, NULL },
+  { ".debug_static_func", display_debug_not_supported, NULL },
+  { ".debug_static_vars", display_debug_not_supported, NULL },
+  { ".debug_types",       display_debug_not_supported, NULL },
+  { ".debug_weaknames",   display_debug_not_supported, NULL }
 };
 
 static int
@@ -5482,15 +5935,48 @@ static int
 process_section_contents (file)
      FILE * file;
 {
-  Elf32_Internal_Shdr *    section;
-  unsigned int  i;
+  Elf32_Internal_Shdr * section;
+  unsigned int         i;
 
   if (! do_dump)
     return 1;
 
+  /* Pre-scan the debug sections to find some debug information not
+     present in some of them.  For the .debug_line, we must find out the
+     size of address (specified in .debug_info and .debug_aranges).  */
+  for (i = 0, section = section_headers;
+       i < elf_header.e_shnum && i < num_dump_sects;
+       i ++, section ++)
+    {
+      char *   name = SECTION_NAME (section);
+      int       j;
+
+      if (section->sh_size == 0)
+        continue;
+
+      /* See if there is some pre-scan operation for this section.  */
+      for (j = NUM_ELEM (debug_displays); j--;)
+        if (strcmp (debug_displays[j].name, name) == 0)
+         {
+           if (debug_displays[j].prescan != NULL)
+             {
+               bfd_size_type   length;
+               unsigned char * start;
+
+               length = section->sh_size;
+               GET_DATA_ALLOC (section->sh_offset, length, start, unsigned char *,
+                               "debug section data");
+
+               debug_displays[j].prescan (section, start, file);
+               free (start);
+             }
+           
+            break;
+          }
+    }
+
   for (i = 0, section = section_headers;
-       i < elf_header.e_shnum
-       && i < num_dump_sects;
+       i < elf_header.e_shnum && i < num_dump_sects;
        i ++, section ++)
     {
 #ifdef SUPPORT_DISASSEMBLY
@@ -5618,7 +6104,7 @@ process_mips_specific (file)
                  { " DELTA", LL_DELTA }
                };
              int flags = liblist.l_flags;
-             int fcnt;
+             size_t fcnt;
 
              for (fcnt = 0;
                   fcnt < sizeof (l_flags_vals) / sizeof (l_flags_vals[0]);
@@ -5888,10 +6374,171 @@ process_mips_specific (file)
   return 1;
 }
 
+static char *
+get_note_type (e_type)
+     unsigned e_type;
+{
+  static char buff[64];
+  
+  switch (e_type)
+    {
+    case NT_PRSTATUS:  return _("NT_PRSTATUS (prstatus structure)");
+    case NT_FPREGSET:  return _("NT_FPREGSET (floating point registers)");
+    case NT_PRPSINFO:   return _("NT_PRPSINFO (prpsinfo structure)");
+    case NT_TASKSTRUCT: return _("NT_TASKSTRUCT (task structure)");
+    case NT_PSTATUS:   return _("NT_PSTATUS (pstatus structure)");
+    case NT_FPREGS:    return _("NT_FPREGS (floating point registers)");
+    case NT_PSINFO:    return _("NT_PSINFO (psinfo structure)");
+    case NT_LWPSTATUS: return _("NT_LWPSTATUS (lwpstatus_t structure)");
+    case NT_LWPSINFO:  return _("NT_LWPSINFO (lwpsinfo_t structure)");
+    default:
+      sprintf (buff, _("Unknown note type: (0x%08x)"), e_type);
+      return buff;
+    }
+}
+
+static int
+process_note (pnote)
+  Elf_External_Note * pnote;
+{
+  Elf32_Internal_Note * internal;
+  char * pname;
+  
+  internal = (Elf32_Internal_Note *) pnote;
+  pname = malloc (internal->namesz + 1);
+  
+  if (pname == NULL)
+    {
+      error (_("Out of memory\n"));
+      return 0;
+    }
+
+  memcpy (pname, pnote->name, internal->namesz);
+  pname[internal->namesz] = '\0';
+
+  printf ("  %s\t\t0x%08lx\t%s\n", 
+         pname, internal->descsz, get_note_type (internal->type));
+          
+  free (pname);
+
+  return 1;
+}
+
+static int
+process_corefile_note_segment (file, offset, length)
+     FILE * file;
+     unsigned long offset;
+     unsigned long length;
+{
+  Elf_External_Note *  pnotes;
+  Elf_External_Note *  external;
+  Elf32_Internal_Note* internal;
+  unsigned int        notesz;
+  unsigned int         nlength;
+  unsigned char *      p;
+  int                  res = 1;
+  
+  if (length <= 0)
+    return 0;
+    
+  GET_DATA_ALLOC (offset, length, pnotes, Elf_External_Note *, "notes");
+
+  external = pnotes; 
+  p = (unsigned char *) pnotes;
+  nlength = length;
+  printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"), offset, length);
+  printf (_("  Owner\t\tData size\tDescription\n"));
+  
+  while (nlength > 0)
+    {
+      res &= process_note (external);
+      
+      internal = (Elf32_Internal_Note *) p;
+      notesz   = 3 * sizeof(unsigned long) + internal->namesz + internal->descsz;
+      nlength -= notesz;
+      p       += notesz;
+      external = (Elf_External_Note *) p;
+    }
+
+  free (pnotes);
+  
+  return res;
+}
+
+static int
+process_corefile_note_segments (file)
+     FILE * file;
+{
+  Elf_Internal_Phdr * program_headers;
+  Elf_Internal_Phdr * segment;
+  unsigned int       i;
+  int                 res = 1;
+  
+  program_headers = (Elf_Internal_Phdr *) malloc
+    (elf_header.e_phnum * sizeof (Elf_Internal_Phdr));
+
+  if (program_headers == NULL)
+    {
+      error (_("Out of memory\n"));
+      return 0;
+    }
+
+  if (is_32bit_elf)
+    i = get_32bit_program_headers (file, program_headers);
+  else
+    i = get_64bit_program_headers (file, program_headers);
+
+  if (i == 0)
+    {
+      free (program_headers);
+      return 0;
+    }
+  
+  for (i = 0, segment = program_headers;
+       i < elf_header.e_phnum;
+       i ++, segment ++)
+    {
+      if (segment->p_type == PT_NOTE)
+       res &= process_corefile_note_segment (file, 
+                                             (unsigned long)segment->p_offset,
+                                             (unsigned long)segment->p_filesz);
+    }
+    
+  free (program_headers);
+
+  return res;
+}
+
+static int
+process_corefile_contents (file)
+     FILE * file;
+{
+  /* If we have not been asked to display the notes then do nothing.  */
+  if (! do_notes)
+    return 1;
+  
+  /* If file is not a core file then exit.  */
+  if (elf_header.e_type != ET_CORE)
+    return 1;
+    
+  /* No program headers means no NOTE segment.  */
+  if (elf_header.e_phnum == 0)
+    {
+      printf (_("No note segments present in the core file.\n"));
+      return 1;
+   }
+
+  return process_corefile_note_segments (file);
+}
+
 static int
 process_arch_specific (file)
      FILE * file;
 {
+  if (! do_arch)
+    return 1;
+
   switch (elf_header.e_machine)
     {
     case EM_MIPS:
@@ -5949,6 +6596,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;
@@ -6031,7 +6689,9 @@ process_file (file_name)
   process_version_sections (file);
 
   process_section_contents (file);
-
+  
+  process_corefile_contents (file);
+  
   process_arch_specific (file);
 
   fclose (file);
This page took 0.044715 seconds and 4 git commands to generate.