binutils/
[deliverable/binutils-gdb.git] / binutils / dwarf.c
index ac3753809d60212009621afab4f8e3689df69e9a..599c0d2ba81d03863c5f4018f65ba550312519af 100644 (file)
@@ -1,5 +1,5 @@
 /* dwarf.c -- display DWARF contents of a BFD binary file
-   Copyright 2005, 2006, 2007, 2008, 2009
+   Copyright 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
@@ -27,6 +27,8 @@
 #include "dwarf2.h"
 #include "dwarf.h"
 
+static const char *regname (unsigned int regno, int row);
+
 static int have_frame_base;
 static int need_base_address;
 
@@ -45,6 +47,7 @@ int do_debug_info;
 int do_debug_abbrevs;
 int do_debug_lines;
 int do_debug_pubnames;
+int do_debug_pubtypes;
 int do_debug_aranges;
 int do_debug_ranges;
 int do_debug_frames;
@@ -52,6 +55,9 @@ int do_debug_frames_interp;
 int do_debug_macinfo;
 int do_debug_str;
 int do_debug_loc;
+int do_trace_info;
+int do_trace_abbrevs;
+int do_trace_aranges;
 int do_wide;
 
 /* Values for do_debug_lines.  */
@@ -226,7 +232,7 @@ print_dwarf_vma (dwarf_vma val, unsigned byte_size)
   fputs (buff + (byte_size == 4 ? 8 : 0), stdout);
 }
 
-static unsigned long int
+unsigned long int
 read_leb128 (unsigned char *data, unsigned int *length_return, int sign)
 {
   unsigned long int result = 0;
@@ -263,7 +269,8 @@ typedef struct State_Machine_Registers
   unsigned int column;
   int is_stmt;
   int basic_block;
-  int end_sequence;
+  unsigned char op_index;
+  unsigned char end_sequence;
 /* This variable hold the number of the last entry seen
    in the File Table.  */
   unsigned int last_file_entry;
@@ -275,6 +282,7 @@ static void
 reset_state_machine (int is_stmt)
 {
   state_machine_regs.address = 0;
+  state_machine_regs.op_index = 0;
   state_machine_regs.file = 1;
   state_machine_regs.line = 1;
   state_machine_regs.column = 0;
@@ -321,6 +329,7 @@ process_extended_line_op (unsigned char *data, int is_stmt)
       adr = byte_get (data, len - bytes_read - 1);
       printf (_("set Address to 0x%lx\n"), adr);
       state_machine_regs.address = adr;
+      state_machine_regs.op_index = 0;
       break;
 
     case DW_LNE_define_file:
@@ -437,23 +446,23 @@ static abbrev_entry *last_abbrev = NULL;
 static void
 free_abbrevs (void)
 {
-  abbrev_entry *abbrev;
+  abbrev_entry *abbrv;
 
-  for (abbrev = first_abbrev; abbrev;)
+  for (abbrv = first_abbrev; abbrv;)
     {
-      abbrev_entry *next = abbrev->next;
+      abbrev_entry *next_abbrev = abbrv->next;
       abbrev_attr *attr;
 
-      for (attr = abbrev->first_attr; attr;)
+      for (attr = abbrv->first_attr; attr;)
        {
-         abbrev_attr *next = attr->next;
+         abbrev_attr *next_attr = attr->next;
 
          free (attr);
-         attr = next;
+         attr = next_attr;
        }
 
-      free (abbrev);
-      abbrev = next;
+      free (abbrv);
+      abbrv = next_abbrev;
     }
 
   last_abbrev = first_abbrev = NULL;
@@ -929,7 +938,8 @@ decode_location_expression (unsigned char * data,
        case DW_OP_reg29:
        case DW_OP_reg30:
        case DW_OP_reg31:
-         printf ("DW_OP_reg%d", op - DW_OP_reg0);
+         printf ("DW_OP_reg%d (%s)", op - DW_OP_reg0,
+                 regname (op - DW_OP_reg0, 1));
          break;
 
        case DW_OP_breg0:
@@ -964,14 +974,16 @@ decode_location_expression (unsigned char * data,
        case DW_OP_breg29:
        case DW_OP_breg30:
        case DW_OP_breg31:
-         printf ("DW_OP_breg%d: %ld", op - DW_OP_breg0,
+         printf ("DW_OP_breg%d (%s): %ld", op - DW_OP_breg0,
+                 regname (op - DW_OP_breg0, 1),
                  read_leb128 (data, &bytes_read, 1));
          data += bytes_read;
          break;
 
        case DW_OP_regx:
-         printf ("DW_OP_regx: %lu", read_leb128 (data, &bytes_read, 0));
+         uvalue = read_leb128 (data, &bytes_read, 0);
          data += bytes_read;
+         printf ("DW_OP_regx: %lu (%s)", uvalue, regname (uvalue, 1));
          break;
        case DW_OP_fbreg:
          need_frame_base = 1;
@@ -981,7 +993,7 @@ decode_location_expression (unsigned char * data,
        case DW_OP_bregx:
          uvalue = read_leb128 (data, &bytes_read, 0);
          data += bytes_read;
-         printf ("DW_OP_bregx: %lu %ld", uvalue,
+         printf ("DW_OP_bregx: %lu (%s) %ld", uvalue, regname (uvalue, 1),
                  read_leb128 (data, &bytes_read, 1));
          data += bytes_read;
          break;
@@ -1153,14 +1165,14 @@ read_and_display_attr_value (unsigned long attribute,
          uvalue = byte_get (data, pointer_size);
          data += pointer_size;
        }
-      else if (dwarf_version == 3)
+      else if (dwarf_version == 3 || dwarf_version == 4)
        {
          uvalue = byte_get (data, offset_size);
          data += offset_size;
        }
       else
        {
-         error (_("Internal error: DWARF version is not 2 or 3.\n"));
+         error (_("Internal error: DWARF version is not 2, 3 or 4.\n"));
        }
       break;
 
@@ -1170,10 +1182,15 @@ read_and_display_attr_value (unsigned long attribute,
       break;
 
     case DW_FORM_strp:
+    case DW_FORM_sec_offset:
       uvalue = byte_get (data, offset_size);
       data += offset_size;
       break;
 
+    case DW_FORM_flag_present:
+      uvalue = 1;
+      break;
+
     case DW_FORM_ref1:
     case DW_FORM_flag:
     case DW_FORM_data1:
@@ -1232,10 +1249,12 @@ read_and_display_attr_value (unsigned long attribute,
 
     case DW_FORM_data4:
     case DW_FORM_addr:
+    case DW_FORM_sec_offset:
       if (!do_loc)
        printf (" 0x%lx", uvalue);
       break;
 
+    case DW_FORM_flag_present:
     case DW_FORM_flag:
     case DW_FORM_data1:
     case DW_FORM_data2:
@@ -1271,6 +1290,7 @@ read_and_display_attr_value (unsigned long attribute,
       break;
 
     case DW_FORM_block:
+    case DW_FORM_exprloc:
       uvalue = read_leb128 (data, & bytes_read, 0);
       block_start = data + bytes_read;
       if (do_loc)
@@ -1351,22 +1371,24 @@ read_and_display_attr_value (unsigned long attribute,
        case DW_AT_segment:
        case DW_AT_static_link:
        case DW_AT_use_location:
-         if (form == DW_FORM_data4 || form == DW_FORM_data8)
+         if (form == DW_FORM_data4
+             || form == DW_FORM_data8
+             || form == DW_FORM_sec_offset)
            {
              /* Process location list.  */
-             unsigned int max = debug_info_p->max_loc_offsets;
+             unsigned int lmax = debug_info_p->max_loc_offsets;
              unsigned int num = debug_info_p->num_loc_offsets;
 
-             if (max == 0 || num >= max)
+             if (lmax == 0 || num >= lmax)
                {
-                 max += 1024;
+                 lmax += 1024;
                  debug_info_p->loc_offsets = (long unsigned int *)
                       xcrealloc (debug_info_p->loc_offsets,
-                                max, sizeof (*debug_info_p->loc_offsets));
+                                lmax, sizeof (*debug_info_p->loc_offsets));
                  debug_info_p->have_frame_base = (int *)
                       xcrealloc (debug_info_p->have_frame_base,
-                                max, sizeof (*debug_info_p->have_frame_base));
-                 debug_info_p->max_loc_offsets = max;
+                                lmax, sizeof (*debug_info_p->have_frame_base));
+                 debug_info_p->max_loc_offsets = lmax;
                }
              debug_info_p->loc_offsets [num] = uvalue;
              debug_info_p->have_frame_base [num] = have_frame_base;
@@ -1380,19 +1402,21 @@ read_and_display_attr_value (unsigned long attribute,
          break;
 
        case DW_AT_ranges:
-         if (form == DW_FORM_data4 || form == DW_FORM_data8)
+         if (form == DW_FORM_data4
+             || form == DW_FORM_data8
+             || form == DW_FORM_sec_offset)
            {
              /* Process range list.  */
-             unsigned int max = debug_info_p->max_range_lists;
+             unsigned int lmax = debug_info_p->max_range_lists;
              unsigned int num = debug_info_p->num_range_lists;
 
-             if (max == 0 || num >= max)
+             if (lmax == 0 || num >= lmax)
                {
-                 max += 1024;
+                 lmax += 1024;
                  debug_info_p->range_lists = (long unsigned int *)
                       xcrealloc (debug_info_p->range_lists,
-                                max, sizeof (*debug_info_p->range_lists));
-                 debug_info_p->max_range_lists = max;
+                                lmax, sizeof (*debug_info_p->range_lists));
+                 debug_info_p->max_range_lists = lmax;
                }
              debug_info_p->range_lists [num] = uvalue;
              debug_info_p->num_range_lists++;
@@ -1590,7 +1614,9 @@ read_and_display_attr_value (unsigned long attribute,
     case DW_AT_segment:
     case DW_AT_static_link:
     case DW_AT_use_location:
-      if (form == DW_FORM_data4 || form == DW_FORM_data8)
+      if (form == DW_FORM_data4
+         || form == DW_FORM_data8
+         || form == DW_FORM_sec_offset)
        printf (_("(location list)"));
       /* Fall through.  */
     case DW_AT_allocated:
@@ -1801,6 +1827,8 @@ get_AT_name (unsigned long attribute)
     case DW_AT_GNU_exclusive_locks_required:   return "DW_AT_GNU_exclusive_locks_required";
     case DW_AT_GNU_shared_locks_required:      return "DW_AT_GNU_shared_locks_required";
     case DW_AT_GNU_odr_signature:              return "DW_AT_GNU_odr_signature";
+    case DW_AT_use_GNAT_descriptive_type:      return "DW_AT_use_GNAT_descriptive_type";
+    case DW_AT_GNAT_descriptive_type:          return "DW_AT_GNAT_descriptive_type";
 
       /* UPC extension.  */
     case DW_AT_upc_threads_scaled:     return "DW_AT_upc_threads_scaled";
@@ -1853,6 +1881,7 @@ read_and_display_attr (unsigned long attribute,
 static int
 process_debug_info (struct dwarf_section *section,
                    void *file,
+                    enum dwarf_section_display_enum abbrev_sec,
                    int do_loc,
                    int do_types)
 {
@@ -1924,11 +1953,11 @@ process_debug_info (struct dwarf_section *section,
       load_debug_section (str, file);
     }
 
-  load_debug_section (abbrev, file);
-  if (debug_displays [abbrev].section.start == NULL)
+  load_debug_section (abbrev_sec, file);
+  if (debug_displays [abbrev_sec].section.start == NULL)
     {
       warn (_("Unable to locate %s section!\n"),
-           debug_displays [abbrev].section.name);
+           debug_displays [abbrev_sec].section.name);
       return 0;
     }
 
@@ -1936,13 +1965,12 @@ process_debug_info (struct dwarf_section *section,
     {
       DWARF2_Internal_CompUnit compunit;
       unsigned char *hdrptr;
-      unsigned char *cu_abbrev_offset_ptr;
       unsigned char *tags;
       int level;
       unsigned long cu_offset;
       int offset_size;
       int initial_length_size;
-      unsigned char signature[8];
+      unsigned char signature[8] = { 0 };
       unsigned long type_offset = 0;
 
       hdrptr = start;
@@ -1968,7 +1996,6 @@ process_debug_info (struct dwarf_section *section,
 
       cu_offset = start - section_begin;
 
-      cu_abbrev_offset_ptr = hdrptr;
       compunit.cu_abbrev_offset = byte_get (hdrptr, offset_size);
       hdrptr += offset_size;
 
@@ -2035,7 +2062,9 @@ process_debug_info (struct dwarf_section *section,
       tags = hdrptr;
       start += compunit.cu_length + initial_length_size;
 
-      if (compunit.cu_version != 2 && compunit.cu_version != 3)
+      if (compunit.cu_version != 2
+         && compunit.cu_version != 3
+         && compunit.cu_version != 4)
        {
          warn (_("CU at offset %lx contains corrupt or unsupported version number: %d.\n"),
                cu_offset, compunit.cu_version);
@@ -2046,16 +2075,16 @@ process_debug_info (struct dwarf_section *section,
 
       /* Process the abbrevs used by this compilation unit. DWARF
         sections under Mach-O have non-zero addresses.  */
-      if (compunit.cu_abbrev_offset >= debug_displays [abbrev].section.size)
+      if (compunit.cu_abbrev_offset >= debug_displays [abbrev_sec].section.size)
        warn (_("Debug info is corrupted, abbrev offset (%lx) is larger than abbrev section size (%lx)\n"),
              (unsigned long) compunit.cu_abbrev_offset,
-             (unsigned long) debug_displays [abbrev].section.size);
+             (unsigned long) debug_displays [abbrev_sec].section.size);
       else
        process_abbrev_section
-         ((unsigned char *) debug_displays [abbrev].section.start
-          + compunit.cu_abbrev_offset - debug_displays [abbrev].section.address,
-          (unsigned char *) debug_displays [abbrev].section.start
-          + debug_displays [abbrev].section.size);
+         ((unsigned char *) debug_displays [abbrev_sec].section.start
+          + compunit.cu_abbrev_offset,
+          (unsigned char *) debug_displays [abbrev_sec].section.start
+          + debug_displays [abbrev_sec].section.size);
 
       level = 0;
       while (tags < start)
@@ -2206,7 +2235,7 @@ load_debug_info (void * file)
     return num_debug_info_entries;
 
   if (load_debug_section (info, file)
-      && process_debug_info (&debug_displays [info].section, file, 1, 0))
+      && process_debug_info (&debug_displays [info].section, file, abbrev, 1, 0))
     return num_debug_info_entries;
 
   num_debug_info_entries = DEBUG_INFO_UNAVAILABLE;
@@ -2225,7 +2254,7 @@ display_debug_lines_raw (struct dwarf_section *section,
 
   while (data < end)
     {
-      DWARF2_Internal_LineInfo info;
+      DWARF2_Internal_LineInfo linfo;
       unsigned char *standard_opcodes;
       unsigned char *end_of_sequence;
       unsigned char *hdrptr;
@@ -2238,13 +2267,13 @@ display_debug_lines_raw (struct dwarf_section *section,
       hdroff = hdrptr - start;
 
       /* Check the length of the block.  */
-      info.li_length = byte_get (hdrptr, 4);
+      linfo.li_length = byte_get (hdrptr, 4);
       hdrptr += 4;
 
-      if (info.li_length == 0xffffffff)
+      if (linfo.li_length == 0xffffffff)
        {
          /* This section is 64-bit DWARF 3.  */
-         info.li_length = byte_get (hdrptr, 8);
+         linfo.li_length = byte_get (hdrptr, 8);
          hdrptr += 8;
          offset_size = 8;
          initial_length_size = 12;
@@ -2255,7 +2284,7 @@ display_debug_lines_raw (struct dwarf_section *section,
          initial_length_size = 4;
        }
 
-      if (info.li_length + initial_length_size > section->size)
+      if (linfo.li_length + initial_length_size > section->size)
        {
          warn
            (_("The information in section %s appears to be corrupt - the section is too small\n"),
@@ -2264,55 +2293,71 @@ display_debug_lines_raw (struct dwarf_section *section,
        }
 
       /* Check its version number.  */
-      info.li_version = byte_get (hdrptr, 2);
+      linfo.li_version = byte_get (hdrptr, 2);
       hdrptr += 2;
-      if (info.li_version != 2 && info.li_version != 3)
+      if (linfo.li_version != 2
+         && linfo.li_version != 3
+         && linfo.li_version != 4)
        {
-         warn (_("Only DWARF version 2 and 3 line info is currently supported.\n"));
+         warn (_("Only DWARF version 2, 3 and 4 line info is currently supported.\n"));
          return 0;
        }
 
-      info.li_prologue_length = byte_get (hdrptr, offset_size);
+      linfo.li_prologue_length = byte_get (hdrptr, offset_size);
       hdrptr += offset_size;
-      info.li_min_insn_length = byte_get (hdrptr, 1);
+      linfo.li_min_insn_length = byte_get (hdrptr, 1);
       hdrptr++;
-      info.li_default_is_stmt = byte_get (hdrptr, 1);
+      if (linfo.li_version >= 4)
+       {
+         linfo.li_max_ops_per_insn = byte_get (hdrptr, 1);
+         hdrptr++;
+         if (linfo.li_max_ops_per_insn == 0)
+           {
+             warn (_("Invalid maximum operations per insn.\n"));
+             return 0;
+           }
+       }
+      else
+       linfo.li_max_ops_per_insn = 1;
+      linfo.li_default_is_stmt = byte_get (hdrptr, 1);
       hdrptr++;
-      info.li_line_base = byte_get (hdrptr, 1);
+      linfo.li_line_base = byte_get (hdrptr, 1);
       hdrptr++;
-      info.li_line_range = byte_get (hdrptr, 1);
+      linfo.li_line_range = byte_get (hdrptr, 1);
       hdrptr++;
-      info.li_opcode_base = byte_get (hdrptr, 1);
+      linfo.li_opcode_base = byte_get (hdrptr, 1);
       hdrptr++;
 
       /* Sign extend the line base field.  */
-      info.li_line_base <<= 24;
-      info.li_line_base >>= 24;
+      linfo.li_line_base <<= 24;
+      linfo.li_line_base >>= 24;
 
       printf (_("  Offset:                      0x%lx\n"), hdroff);
-      printf (_("  Length:                      %ld\n"), info.li_length);
-      printf (_("  DWARF Version:               %d\n"), info.li_version);
-      printf (_("  Prologue Length:             %d\n"), info.li_prologue_length);
-      printf (_("  Minimum Instruction Length:  %d\n"), info.li_min_insn_length);
-      printf (_("  Initial value of 'is_stmt':  %d\n"), info.li_default_is_stmt);
-      printf (_("  Line Base:                   %d\n"), info.li_line_base);
-      printf (_("  Line Range:                  %d\n"), info.li_line_range);
-      printf (_("  Opcode Base:                 %d\n"), info.li_opcode_base);
+      printf (_("  Length:                      %ld\n"), linfo.li_length);
+      printf (_("  DWARF Version:               %d\n"), linfo.li_version);
+      printf (_("  Prologue Length:             %d\n"), linfo.li_prologue_length);
+      printf (_("  Minimum Instruction Length:  %d\n"), linfo.li_min_insn_length);
+      if (linfo.li_version >= 4)
+       printf (_("  Maximum Ops per Instruction: %d\n"), linfo.li_max_ops_per_insn);
+      printf (_("  Initial value of 'is_stmt':  %d\n"), linfo.li_default_is_stmt);
+      printf (_("  Line Base:                   %d\n"), linfo.li_line_base);
+      printf (_("  Line Range:                  %d\n"), linfo.li_line_range);
+      printf (_("  Opcode Base:                 %d\n"), linfo.li_opcode_base);
 
-      end_of_sequence = data + info.li_length + initial_length_size;
+      end_of_sequence = data + linfo.li_length + initial_length_size;
 
-      reset_state_machine (info.li_default_is_stmt);
+      reset_state_machine (linfo.li_default_is_stmt);
 
       /* Display the contents of the Opcodes table.  */
       standard_opcodes = hdrptr;
 
       printf (_("\n Opcodes:\n"));
 
-      for (i = 1; i < info.li_opcode_base; i++)
+      for (i = 1; i < linfo.li_opcode_base; 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;
+      data = standard_opcodes + linfo.li_opcode_base - 1;
 
       if (*data == 0)
        printf (_("\n The Directory Table is empty.\n"));
@@ -2374,14 +2419,31 @@ display_debug_lines_raw (struct dwarf_section *section,
 
          op_code = *data++;
 
-         if (op_code >= info.li_opcode_base)
+         if (op_code >= linfo.li_opcode_base)
            {
-             op_code -= info.li_opcode_base;
-             uladv = (op_code / info.li_line_range) * info.li_min_insn_length;
-             state_machine_regs.address += uladv;
-             printf (_("  Special opcode %d: advance Address by %lu to 0x%lx"),
-                     op_code, uladv, state_machine_regs.address);
-             adv = (op_code % info.li_line_range) + info.li_line_base;
+             op_code -= linfo.li_opcode_base;
+             uladv = (op_code / linfo.li_line_range);
+             if (linfo.li_max_ops_per_insn == 1)
+               {
+                 uladv *= linfo.li_min_insn_length;
+                 state_machine_regs.address += uladv;
+                 printf (_("  Special opcode %d: advance Address by %lu to 0x%lx"),
+                         op_code, uladv, state_machine_regs.address);
+               }
+             else
+               {
+                 state_machine_regs.address
+                   += ((state_machine_regs.op_index + uladv)
+                       / linfo.li_max_ops_per_insn)
+                      * linfo.li_min_insn_length;
+                 state_machine_regs.op_index
+                   = (state_machine_regs.op_index + uladv)
+                     % linfo.li_max_ops_per_insn;
+                 printf (_("  Special opcode %d: advance Address by %lu to 0x%lx[%d]"),
+                         op_code, uladv, state_machine_regs.address,
+                         state_machine_regs.op_index);
+               }
+             adv = (op_code % linfo.li_line_range) + linfo.li_line_base;
              state_machine_regs.line += adv;
              printf (_(" and Line by %d to %d\n"),
                      adv, state_machine_regs.line);
@@ -2389,7 +2451,7 @@ display_debug_lines_raw (struct dwarf_section *section,
          else 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, linfo.li_default_is_stmt);
              break;
 
            case DW_LNS_copy:
@@ -2398,11 +2460,27 @@ display_debug_lines_raw (struct dwarf_section *section,
 
            case DW_LNS_advance_pc:
              uladv = read_leb128 (data, & bytes_read, 0);
-             uladv *= info.li_min_insn_length;
              data += bytes_read;
-             state_machine_regs.address += uladv;
-             printf (_("  Advance PC by %lu to 0x%lx\n"), uladv,
-                     state_machine_regs.address);
+             if (linfo.li_max_ops_per_insn == 1)
+               {
+                 uladv *= linfo.li_min_insn_length;
+                 state_machine_regs.address += uladv;
+                 printf (_("  Advance PC by %lu to 0x%lx\n"), uladv,
+                         state_machine_regs.address);
+               }
+             else
+               {
+                 state_machine_regs.address
+                   += ((state_machine_regs.op_index + uladv)
+                       / linfo.li_max_ops_per_insn)
+                      * linfo.li_min_insn_length;
+                 state_machine_regs.op_index
+                   = (state_machine_regs.op_index + uladv)
+                     % linfo.li_max_ops_per_insn;
+                 printf (_("  Advance PC by %lu to 0x%lx[%d]\n"), uladv,
+                         state_machine_regs.address,
+                         state_machine_regs.op_index);
+               }
              break;
 
            case DW_LNS_advance_line:
@@ -2441,17 +2519,34 @@ display_debug_lines_raw (struct dwarf_section *section,
              break;
 
            case DW_LNS_const_add_pc:
-             uladv = (((255 - info.li_opcode_base) / info.li_line_range)
-                     * info.li_min_insn_length);
-             state_machine_regs.address += uladv;
-             printf (_("  Advance PC by constant %lu to 0x%lx\n"), uladv,
-                     state_machine_regs.address);
+             uladv = ((255 - linfo.li_opcode_base) / linfo.li_line_range);
+             if (linfo.li_max_ops_per_insn)
+               {
+                 uladv *= linfo.li_min_insn_length;
+                 state_machine_regs.address += uladv;
+                 printf (_("  Advance PC by constant %lu to 0x%lx\n"), uladv,
+                         state_machine_regs.address);
+               }
+             else
+               {
+                 state_machine_regs.address
+                   += ((state_machine_regs.op_index + uladv)
+                       / linfo.li_max_ops_per_insn)
+                      * linfo.li_min_insn_length;
+                 state_machine_regs.op_index
+                   = (state_machine_regs.op_index + uladv)
+                     % linfo.li_max_ops_per_insn;
+                 printf (_("  Advance PC by constant %lu to 0x%lx[%d]\n"),
+                         uladv, state_machine_regs.address,
+                         state_machine_regs.op_index);
+               }
              break;
 
            case DW_LNS_fixed_advance_pc:
              uladv = byte_get (data, 2);
              data += 2;
              state_machine_regs.address += uladv;
+             state_machine_regs.op_index = 0;
              printf (_("  Advance PC by fixed size amount %lu to 0x%lx\n"),
                      uladv, state_machine_regs.address);
              break;
@@ -2510,7 +2605,7 @@ display_debug_lines_decoded (struct dwarf_section *section,
   while (data < end)
     {
       /* This loop amounts to one iteration per compilation unit.  */
-      DWARF2_Internal_LineInfo info;
+      DWARF2_Internal_LineInfo linfo;
       unsigned char *standard_opcodes;
       unsigned char *end_of_sequence;
       unsigned char *hdrptr;
@@ -2519,7 +2614,6 @@ display_debug_lines_decoded (struct dwarf_section *section,
       int i;
       File_Entry *file_table = NULL;
       unsigned char **directory_table = NULL;
-      unsigned int prev_line = 0;
 
       hdrptr = data;
 
@@ -2527,13 +2621,13 @@ display_debug_lines_decoded (struct dwarf_section *section,
         (section 6.2.4 in the Dwarf3 doc).  */
 
       /* Get the length of this CU's line number information block.  */
-      info.li_length = byte_get (hdrptr, 4);
+      linfo.li_length = byte_get (hdrptr, 4);
       hdrptr += 4;
 
-      if (info.li_length == 0xffffffff)
+      if (linfo.li_length == 0xffffffff)
         {
           /* This section is 64-bit DWARF 3.  */
-          info.li_length = byte_get (hdrptr, 8);
+          linfo.li_length = byte_get (hdrptr, 8);
           hdrptr += 8;
           offset_size = 8;
           initial_length_size = 12;
@@ -2544,7 +2638,7 @@ display_debug_lines_decoded (struct dwarf_section *section,
           initial_length_size = 4;
         }
 
-      if (info.li_length + initial_length_size > section->size)
+      if (linfo.li_length + initial_length_size > section->size)
         {
           warn (_("The line info appears to be corrupt - "
                   "the section is too small\n"));
@@ -2552,47 +2646,60 @@ display_debug_lines_decoded (struct dwarf_section *section,
         }
 
       /* Get this CU's Line Number Block version number.  */
-      info.li_version = byte_get (hdrptr, 2);
+      linfo.li_version = byte_get (hdrptr, 2);
       hdrptr += 2;
-      if (info.li_version != 2 && info.li_version != 3)
+      if (linfo.li_version != 2
+         && linfo.li_version != 3
+         && linfo.li_version != 4)
         {
-          warn (_("Only DWARF version 2 and 3 line info is currently "
+          warn (_("Only DWARF version 2, 3 and 4 line info is currently "
                 "supported.\n"));
           return 0;
         }
 
-      info.li_prologue_length = byte_get (hdrptr, offset_size);
+      linfo.li_prologue_length = byte_get (hdrptr, offset_size);
       hdrptr += offset_size;
-      info.li_min_insn_length = byte_get (hdrptr, 1);
+      linfo.li_min_insn_length = byte_get (hdrptr, 1);
       hdrptr++;
-      info.li_default_is_stmt = byte_get (hdrptr, 1);
+      if (linfo.li_version >= 4)
+       {
+         linfo.li_max_ops_per_insn = byte_get (hdrptr, 1);
+         hdrptr++;
+         if (linfo.li_max_ops_per_insn == 0)
+           {
+             warn (_("Invalid maximum operations per insn.\n"));
+             return 0;
+           }
+       }
+      else
+       linfo.li_max_ops_per_insn = 1;
+      linfo.li_default_is_stmt = byte_get (hdrptr, 1);
       hdrptr++;
-      info.li_line_base = byte_get (hdrptr, 1);
+      linfo.li_line_base = byte_get (hdrptr, 1);
       hdrptr++;
-      info.li_line_range = byte_get (hdrptr, 1);
+      linfo.li_line_range = byte_get (hdrptr, 1);
       hdrptr++;
-      info.li_opcode_base = byte_get (hdrptr, 1);
+      linfo.li_opcode_base = byte_get (hdrptr, 1);
       hdrptr++;
 
       /* Sign extend the line base field.  */
-      info.li_line_base <<= 24;
-      info.li_line_base >>= 24;
+      linfo.li_line_base <<= 24;
+      linfo.li_line_base >>= 24;
 
       /* Find the end of this CU's Line Number Information Block.  */
-      end_of_sequence = data + info.li_length + initial_length_size;
+      end_of_sequence = data + linfo.li_length + initial_length_size;
 
-      reset_state_machine (info.li_default_is_stmt);
+      reset_state_machine (linfo.li_default_is_stmt);
 
       /* Save a pointer to the contents of the Opcodes table.  */
       standard_opcodes = hdrptr;
 
       /* Traverse the Directory table just to count entries.  */
-      data = standard_opcodes + info.li_opcode_base - 1;
+      data = standard_opcodes + linfo.li_opcode_base - 1;
       if (*data != 0)
         {
           unsigned int n_directories = 0;
           unsigned char *ptr_directory_table = data;
-          int i;
 
          while (*data != 0)
            {
@@ -2620,7 +2727,6 @@ display_debug_lines_decoded (struct dwarf_section *section,
         {
           unsigned int n_files = 0;
           unsigned char *ptr_file_name_table = data;
-          int i;
 
           while (*data != 0)
             {
@@ -2697,15 +2803,28 @@ display_debug_lines_decoded (struct dwarf_section *section,
           int is_special_opcode = 0;
 
           op_code = *data++;
-          prev_line = state_machine_regs.line;
 
-          if (op_code >= info.li_opcode_base)
+          if (op_code >= linfo.li_opcode_base)
            {
-             op_code -= info.li_opcode_base;
-              uladv = (op_code / info.li_line_range) * info.li_min_insn_length;
-              state_machine_regs.address += uladv;
+             op_code -= linfo.li_opcode_base;
+             uladv = (op_code / linfo.li_line_range);
+             if (linfo.li_max_ops_per_insn == 1)
+               {
+                 uladv *= linfo.li_min_insn_length;
+                 state_machine_regs.address += uladv;
+               }
+             else
+               {
+                 state_machine_regs.address
+                   += ((state_machine_regs.op_index + uladv)
+                       / linfo.li_max_ops_per_insn)
+                      * linfo.li_min_insn_length;
+                 state_machine_regs.op_index
+                   = (state_machine_regs.op_index + uladv)
+                     % linfo.li_max_ops_per_insn;
+               }
 
-              adv = (op_code % info.li_line_range) + info.li_line_base;
+              adv = (op_code % linfo.li_line_range) + linfo.li_line_base;
               state_machine_regs.line += adv;
               is_special_opcode = 1;
             }
@@ -2714,7 +2833,6 @@ display_debug_lines_decoded (struct dwarf_section *section,
             case DW_LNS_extended_op:
               {
                 unsigned int ext_op_code_len;
-                unsigned int bytes_read;
                 unsigned char ext_op_code;
                 unsigned char *op_code_data = data;
 
@@ -2732,11 +2850,12 @@ display_debug_lines_decoded (struct dwarf_section *section,
                 switch (ext_op_code)
                   {
                   case DW_LNE_end_sequence:
-                    reset_state_machine (info.li_default_is_stmt);
+                    reset_state_machine (linfo.li_default_is_stmt);
                     break;
                   case DW_LNE_set_address:
                     state_machine_regs.address =
                     byte_get (op_code_data, ext_op_code_len - bytes_read - 1);
+                   state_machine_regs.op_index = 0;
                     break;
                   case DW_LNE_define_file:
                     {
@@ -2765,9 +2884,22 @@ display_debug_lines_decoded (struct dwarf_section *section,
 
             case DW_LNS_advance_pc:
               uladv = read_leb128 (data, & bytes_read, 0);
-              uladv *= info.li_min_insn_length;
               data += bytes_read;
-              state_machine_regs.address += uladv;
+             if (linfo.li_max_ops_per_insn == 1)
+               {
+                 uladv *= linfo.li_min_insn_length;
+                 state_machine_regs.address += uladv;
+               }
+             else
+               {
+                 state_machine_regs.address
+                   += ((state_machine_regs.op_index + uladv)
+                       / linfo.li_max_ops_per_insn)
+                      * linfo.li_min_insn_length;
+                 state_machine_regs.op_index
+                   = (state_machine_regs.op_index + uladv)
+                     % linfo.li_max_ops_per_insn;
+               }
               break;
 
             case DW_LNS_advance_line:
@@ -2812,15 +2944,29 @@ display_debug_lines_decoded (struct dwarf_section *section,
               break;
 
             case DW_LNS_const_add_pc:
-              uladv = (((255 - info.li_opcode_base) / info.li_line_range)
-                       * info.li_min_insn_length);
-              state_machine_regs.address += uladv;
+             uladv = ((255 - linfo.li_opcode_base) / linfo.li_line_range);
+             if (linfo.li_max_ops_per_insn == 1)
+               {
+                 uladv *= linfo.li_min_insn_length;
+                 state_machine_regs.address += uladv;
+               }
+             else
+               {
+                 state_machine_regs.address
+                   += ((state_machine_regs.op_index + uladv)
+                       / linfo.li_max_ops_per_insn)
+                      * linfo.li_min_insn_length;
+                 state_machine_regs.op_index
+                   = (state_machine_regs.op_index + uladv)
+                     % linfo.li_max_ops_per_insn;
+               }
               break;
 
             case DW_LNS_fixed_advance_pc:
               uladv = byte_get (data, 2);
               data += 2;
               state_machine_regs.address += uladv;
+             state_machine_regs.op_index = 0;
               break;
 
             case DW_LNS_set_prologue_end:
@@ -2874,13 +3020,27 @@ display_debug_lines_decoded (struct dwarf_section *section,
 
               if (!do_wide || (fileNameLength <= MAX_FILENAME_LENGTH))
                 {
-                  printf (_("%-35s  %11d  %#18lx\n"), newFileName,
-                          state_machine_regs.line, state_machine_regs.address);
+                 if (linfo.li_max_ops_per_insn == 1)
+                   printf (_("%-35s  %11d  %#18lx\n"), newFileName,
+                           state_machine_regs.line,
+                           state_machine_regs.address);
+                 else
+                   printf (_("%-35s  %11d  %#18lx[%d]\n"), newFileName,
+                           state_machine_regs.line,
+                           state_machine_regs.address,
+                           state_machine_regs.op_index);
                 }
               else
                 {
-                  printf (_("%s  %11d  %#18lx\n"), newFileName,
-                          state_machine_regs.line, state_machine_regs.address);
+                 if (linfo.li_max_ops_per_insn == 1)
+                   printf (_("%s  %11d  %#18lx\n"), newFileName,
+                           state_machine_regs.line,
+                           state_machine_regs.address);
+                 else
+                   printf (_("%s  %11d  %#18lx[%d]\n"), newFileName,
+                           state_machine_regs.line,
+                           state_machine_regs.address,
+                           state_machine_regs.op_index);
                 }
 
               if (op_code == DW_LNE_end_sequence)
@@ -2900,20 +3060,13 @@ display_debug_lines_decoded (struct dwarf_section *section,
 }
 
 static int
-display_debug_lines (struct dwarf_section *section, void *file)
+display_debug_lines (struct dwarf_section *section, void *file ATTRIBUTE_UNUSED)
 {
   unsigned char *data = section->start;
   unsigned char *end = data + section->size;
   int retValRaw = 1;
   int retValDecoded = 1;
 
-  if (load_debug_info (file) == 0)
-    {
-      warn (_("Unable to load/parse the .debug_info section, so cannot interpret the %s section.\n"),
-            section->name);
-      return 0;
-    }
-
   if (do_debug_lines == 0)
     do_debug_lines |= FLAG_DEBUG_LINES_RAW;
 
@@ -2948,7 +3101,7 @@ static int
 display_debug_pubnames (struct dwarf_section *section,
                        void *file ATTRIBUTE_UNUSED)
 {
-  DWARF2_Internal_PubNames pubnames;
+  DWARF2_Internal_PubNames names;
   unsigned char *start = section->start;
   unsigned char *end = start + section->size;
 
@@ -2966,11 +3119,11 @@ display_debug_pubnames (struct dwarf_section *section,
 
       data = start;
 
-      pubnames.pn_length = byte_get (data, 4);
+      names.pn_length = byte_get (data, 4);
       data += 4;
-      if (pubnames.pn_length == 0xffffffff)
+      if (names.pn_length == 0xffffffff)
        {
-         pubnames.pn_length = byte_get (data, 8);
+         names.pn_length = byte_get (data, 8);
          data += 8;
          offset_size = 8;
          initial_length_size = 12;
@@ -2981,24 +3134,24 @@ display_debug_pubnames (struct dwarf_section *section,
          initial_length_size = 4;
        }
 
-      pubnames.pn_version = byte_get (data, 2);
+      names.pn_version = byte_get (data, 2);
       data += 2;
 
-      pubnames.pn_offset = byte_get (data, offset_size);
+      names.pn_offset = byte_get (data, offset_size);
       data += offset_size;
 
       if (num_debug_info_entries != DEBUG_INFO_UNAVAILABLE
          && num_debug_info_entries > 0
-         && find_debug_info_for_offset (pubnames.pn_offset) == NULL)
+         && find_debug_info_for_offset (names.pn_offset) == NULL)
        warn (_(".debug_info offset of 0x%lx in %s section does not point to a CU header.\n"),
-             pubnames.pn_offset, section->name);
+             names.pn_offset, section->name);
 
-      pubnames.pn_size = byte_get (data, offset_size);
+      names.pn_size = byte_get (data, offset_size);
       data += offset_size;
 
-      start += pubnames.pn_length + initial_length_size;
+      start += names.pn_length + initial_length_size;
 
-      if (pubnames.pn_version != 2 && pubnames.pn_version != 3)
+      if (names.pn_version != 2 && names.pn_version != 3)
        {
          static int warned = 0;
 
@@ -3012,13 +3165,13 @@ display_debug_pubnames (struct dwarf_section *section,
        }
 
       printf (_("  Length:                              %ld\n"),
-             pubnames.pn_length);
+             names.pn_length);
       printf (_("  Version:                             %d\n"),
-             pubnames.pn_version);
+             names.pn_version);
       printf (_("  Offset into .debug_info section:     0x%lx\n"),
-             pubnames.pn_offset);
+             names.pn_offset);
       printf (_("  Size of area in .debug_info section: %ld\n"),
-             pubnames.pn_size);
+             names.pn_size);
 
       printf (_("\n    Offset\tName\n"));
 
@@ -3437,13 +3590,19 @@ display_debug_str (struct dwarf_section *section,
 static int
 display_debug_info (struct dwarf_section *section, void *file)
 {
-  return process_debug_info (section, file, 0, 0);
+  return process_debug_info (section, file, abbrev, 0, 0);
 }
 
 static int
 display_debug_types (struct dwarf_section *section, void *file)
 {
-  return process_debug_info (section, file, 0, 1);
+  return process_debug_info (section, file, abbrev, 0, 1);
+}
+
+static int
+display_trace_info (struct dwarf_section *section, void *file)
+{
+  return process_debug_info (section, file, trace_abbrev, 0, 0);
 }
 
 static int
@@ -3463,7 +3622,7 @@ display_debug_aranges (struct dwarf_section *section,
     {
       unsigned char *hdrptr;
       DWARF2_Internal_ARange arange;
-      unsigned char *ranges;
+      unsigned char *addr_ranges;
       dwarf_vma length;
       dwarf_vma address;
       unsigned char address_size;
@@ -3535,24 +3694,24 @@ display_debug_aranges (struct dwarf_section *section,
       else
        printf (_("\n    Address    Length\n"));
 
-      ranges = hdrptr;
+      addr_ranges = hdrptr;
 
       /* Must pad to an alignment boundary that is twice the address size.  */
       excess = (hdrptr - start) % (2 * address_size);
       if (excess)
-       ranges += (2 * address_size) - excess;
+       addr_ranges += (2 * address_size) - excess;
 
       start += arange.ar_length + initial_length_size;
 
-      while (ranges + 2 * address_size <= start)
+      while (addr_ranges + 2 * address_size <= start)
        {
-         address = byte_get (ranges, address_size);
+         address = byte_get (addr_ranges, address_size);
 
-         ranges += address_size;
+         addr_ranges += address_size;
 
-         length  = byte_get (ranges, address_size);
+         length  = byte_get (addr_ranges, address_size);
 
-         ranges += address_size;
+         addr_ranges += address_size;
 
          printf ("    ");
          print_dwarf_vma (address, address_size);
@@ -3596,14 +3755,12 @@ display_debug_ranges (struct dwarf_section *section,
                      void *file ATTRIBUTE_UNUSED)
 {
   unsigned char *start = section->start;
-  unsigned char *section_end;
   unsigned long bytes;
   unsigned char *section_begin = start;
   unsigned int num_range_list, i;
   struct range_entry *range_entries, *range_entry_fill;
 
   bytes = section->size;
-  section_end = start + bytes;
 
   if (bytes == 0)
     {
@@ -3751,6 +3908,8 @@ typedef struct Frame_Chunk
   int ra;
   unsigned char fde_encoding;
   unsigned char cfa_exp;
+  unsigned char ptr_size;
+  unsigned char segment_size;
 }
 Frame_Chunk;
 
@@ -3807,6 +3966,13 @@ static const char *const dwarf_regnames_i386[] =
   "tr", "ldtr"
 };
 
+void
+init_dwarf_regnames_i386 (void)
+{
+  dwarf_regnames = dwarf_regnames_i386;
+  dwarf_regnames_count = ARRAY_SIZE (dwarf_regnames_i386);
+}
+
 static const char *const dwarf_regnames_x86_64[] =
 {
   "rax", "rdx", "rcx", "rbx",
@@ -3829,6 +3995,13 @@ static const char *const dwarf_regnames_x86_64[] =
   "mxcsr", "fcw", "fsw"
 };
 
+void
+init_dwarf_regnames_x86_64 (void)
+{
+  dwarf_regnames = dwarf_regnames_x86_64;
+  dwarf_regnames_count = ARRAY_SIZE (dwarf_regnames_x86_64);
+}
+
 void
 init_dwarf_regnames (unsigned int e_machine)
 {
@@ -3836,13 +4009,12 @@ init_dwarf_regnames (unsigned int e_machine)
     {
     case EM_386:
     case EM_486:
-      dwarf_regnames = dwarf_regnames_i386;
-      dwarf_regnames_count = ARRAY_SIZE (dwarf_regnames_i386);
+      init_dwarf_regnames_i386 ();
       break;
 
     case EM_X86_64:
-      dwarf_regnames = dwarf_regnames_x86_64;
-      dwarf_regnames_count = ARRAY_SIZE (dwarf_regnames_x86_64);
+    case EM_L1OM:
+      init_dwarf_regnames_x86_64 ();
       break;
 
     default:
@@ -3879,11 +4051,11 @@ frame_display_row (Frame_Chunk *fc, int *need_col_headers, int *max_regs)
 
   if (*need_col_headers)
     {
-      static const char *loc = "   LOC";
+      static const char *sloc = "   LOC";
 
       *need_col_headers = 0;
 
-      printf ("%-*s CFA      ", eh_addr_size * 2, loc);
+      printf ("%-*s CFA      ", eh_addr_size * 2, sloc);
 
       for (r = 0; r < *max_regs; r++)
        if (fc->col_type[r] != DW_CFA_unreferenced)
@@ -3959,6 +4131,7 @@ display_debug_frames (struct dwarf_section *section,
   unsigned int length_return;
   int max_regs = 0;
   const char *bad_reg = _("bad register: ");
+  int saved_eh_addr_size = eh_addr_size;
 
   printf (_("Contents of the %s section:\n"), section->name);
 
@@ -3973,7 +4146,7 @@ display_debug_frames (struct dwarf_section *section,
       int need_col_headers = 1;
       unsigned char *augmentation_data = NULL;
       unsigned long augmentation_data_len = 0;
-      int encoded_ptr_size = eh_addr_size;
+      int encoded_ptr_size = saved_eh_addr_size;
       int offset_size;
       int initial_length_size;
 
@@ -4029,48 +4202,36 @@ display_debug_frames (struct dwarf_section *section,
          fc->augmentation = (char *) start;
          start = (unsigned char *) strchr ((char *) start, '\0') + 1;
 
-         if (fc->augmentation[0] == 'z')
+         if (strcmp (fc->augmentation, "eh") == 0)
+           start += eh_addr_size;
+
+         if (version >= 4)
            {
-             fc->code_factor = LEB ();
-             fc->data_factor = SLEB ();
-             if (version == 1)
-               {
-                 fc->ra = GET (1);
-               }
-             else
-               {
-                 fc->ra = LEB ();
-               }
-             augmentation_data_len = LEB ();
-             augmentation_data = start;
-             start += augmentation_data_len;
+             fc->ptr_size = GET (1);
+             fc->segment_size = GET (1);
+             eh_addr_size = fc->ptr_size;
            }
-         else if (strcmp (fc->augmentation, "eh") == 0)
+         else
            {
-             start += eh_addr_size;
-             fc->code_factor = LEB ();
-             fc->data_factor = SLEB ();
-             if (version == 1)
-               {
-                 fc->ra = GET (1);
-               }
-             else
-               {
-                 fc->ra = LEB ();
-               }
+             fc->ptr_size = eh_addr_size;
+             fc->segment_size = 0;
+           }
+         fc->code_factor = LEB ();
+         fc->data_factor = SLEB ();
+         if (version == 1)
+           {
+             fc->ra = GET (1);
            }
          else
            {
-             fc->code_factor = LEB ();
-             fc->data_factor = SLEB ();
-             if (version == 1)
-               {
-                 fc->ra = GET (1);
-               }
-             else
-               {
-                 fc->ra = LEB ();
-               }
+             fc->ra = LEB ();
+           }
+
+         if (fc->augmentation[0] == 'z')
+           {
+             augmentation_data_len = LEB ();
+             augmentation_data = start;
+             start += augmentation_data_len;
            }
          cie = fc;
 
@@ -4085,6 +4246,11 @@ display_debug_frames (struct dwarf_section *section,
                      (unsigned long)(saved_start - section_start), length, cie_id);
              printf ("  Version:               %d\n", version);
              printf ("  Augmentation:          \"%s\"\n", fc->augmentation);
+             if (version >= 4)
+               {
+                 printf ("  Pointer Size:          %u\n", fc->ptr_size);
+                 printf ("  Segment Size:          %u\n", fc->segment_size);
+               }
              printf ("  Code alignment factor: %u\n", fc->code_factor);
              printf ("  Data alignment factor: %d\n", fc->data_factor);
              printf ("  Return address column: %d\n", fc->ra);
@@ -4114,6 +4280,8 @@ display_debug_frames (struct dwarf_section *section,
                    q += 1 + size_of_encoded_value (*q);
                  else if (*p == 'R')
                    fc->fde_encoding = *q++;
+                 else if (*p == 'S')
+                   ;
                  else
                    break;
                  p++;
@@ -4129,6 +4297,7 @@ display_debug_frames (struct dwarf_section *section,
        {
          unsigned char *look_for;
          static Frame_Chunk fde_fc;
+         unsigned long segment_selector;
 
          fc = & fde_fc;
          memset (fc, 0, sizeof (Frame_Chunk));
@@ -4150,6 +4319,8 @@ display_debug_frames (struct dwarf_section *section,
              cie = fc;
              fc->augmentation = "";
              fc->fde_encoding = 0;
+             fc->ptr_size = eh_addr_size;
+             fc->segment_size = 0;
            }
          else
            {
@@ -4159,6 +4330,9 @@ display_debug_frames (struct dwarf_section *section,
              memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int));
              memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
              fc->augmentation = cie->augmentation;
+             fc->ptr_size = cie->ptr_size;
+             eh_addr_size = cie->ptr_size;
+             fc->segment_size = cie->segment_size;
              fc->code_factor = cie->code_factor;
              fc->data_factor = cie->data_factor;
              fc->cfa_reg = cie->cfa_reg;
@@ -4171,6 +4345,12 @@ display_debug_frames (struct dwarf_section *section,
          if (fc->fde_encoding)
            encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
 
+         segment_selector = 0;
+         if (fc->segment_size)
+           {
+             segment_selector = byte_get (start, fc->segment_size);
+             start += fc->segment_size;
+           }
          fc->pc_begin = get_encoded_value (start, fc->fde_encoding);
          if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel)
            fc->pc_begin += section->address + (start - section_start);
@@ -4185,10 +4365,12 @@ display_debug_frames (struct dwarf_section *section,
              start += augmentation_data_len;
            }
 
-         printf ("\n%08lx %08lx %08lx FDE cie=%08lx pc=%08lx..%08lx\n",
+         printf ("\n%08lx %08lx %08lx FDE cie=%08lx pc=",
                  (unsigned long)(saved_start - section_start), length, cie_id,
-                 (unsigned long)(cie->chunk_start - section_start),
-                 fc->pc_begin, fc->pc_begin + fc->pc_range);
+                 (unsigned long)(cie->chunk_start - section_start));
+         if (fc->segment_size)
+           printf ("%04lx:", segment_selector);
+         printf ("%08lx..%08lx\n", fc->pc_begin, fc->pc_begin + fc->pc_range);
          if (! do_debug_frames_interp && augmentation_data_len)
            {
              unsigned long i;
@@ -4217,7 +4399,7 @@ display_debug_frames (struct dwarf_section *section,
          while (start < block_end)
            {
              unsigned op, opa;
-             unsigned long reg, tmp;
+             unsigned long reg, temp;
 
              op = *start++;
              opa = op & 0x3f;
@@ -4288,14 +4470,14 @@ display_debug_frames (struct dwarf_section *section,
                  LEB ();
                  break;
                case DW_CFA_def_cfa_expression:
-                 tmp = LEB ();
-                 start += tmp;
+                 temp = LEB ();
+                 start += temp;
                  break;
                case DW_CFA_expression:
                case DW_CFA_val_expression:
                  reg = LEB ();
-                 tmp = LEB ();
-                 start += tmp;
+                 temp = LEB ();
+                 start += temp;
                  if (frame_need_space (fc, reg) >= 0)
                    fc->col_type[reg] = DW_CFA_undefined;
                  break;
@@ -4736,6 +4918,7 @@ display_debug_frames (struct dwarf_section *section,
        frame_display_row (fc, &need_col_headers, &max_regs);
 
       start = block_end;
+      eh_addr_size = saved_eh_addr_size;
     }
 
   printf ("\n");
@@ -4848,7 +5031,7 @@ dwarf_select_sections_by_names (const char *names)
   {
     const char * option;
     int *        variable;
-    int val;
+    int          val;
   }
   debug_dump_long_opts;
 
@@ -4867,10 +5050,15 @@ dwarf_select_sections_by_names (const char *names)
       { "loc",  & do_debug_loc, 1 },
       { "macro", & do_debug_macinfo, 1 },
       { "pubnames", & do_debug_pubnames, 1 },
+      { "pubtypes", & do_debug_pubtypes, 1 },
       /* This entry is for compatability
         with earlier versions of readelf.  */
       { "ranges", & do_debug_aranges, 1 },
       { "str", & do_debug_str, 1 },
+      /* These trace_* sections are used by Itanium VMS.  */
+      { "trace_abbrev", & do_trace_abbrevs, 1 },
+      { "trace_aranges", & do_trace_aranges, 1 },
+      { "trace_info", & do_trace_info, 1 },
       { NULL, NULL, 0 }
     };
 
@@ -4916,10 +5104,10 @@ dwarf_select_sections_by_names (const char *names)
 void
 dwarf_select_sections_by_letters (const char *letters)
 {
-  unsigned int index = 0;
+  unsigned int lindex = 0;
 
-  while (letters[index])
-    switch (letters[index++])
+  while (letters[lindex])
+    switch (letters[lindex++])
       {
       case 'i':
        do_debug_info = 1;
@@ -4941,6 +5129,10 @@ dwarf_select_sections_by_letters (const char *letters)
        do_debug_pubnames = 1;
        break;
        
+      case 't':
+       do_debug_pubtypes = 1;
+       break;
+       
       case 'r':
        do_debug_aranges = 1;
        break;
@@ -4980,46 +5172,56 @@ dwarf_select_sections_all (void)
   do_debug_abbrevs = 1;
   do_debug_lines = FLAG_DEBUG_LINES_RAW;
   do_debug_pubnames = 1;
+  do_debug_pubtypes = 1;
   do_debug_aranges = 1;
   do_debug_ranges = 1;
   do_debug_frames = 1;
   do_debug_macinfo = 1;
   do_debug_str = 1;
   do_debug_loc = 1;
+  do_trace_info = 1;
+  do_trace_abbrevs = 1;
+  do_trace_aranges = 1;
 }
 
 struct dwarf_section_display debug_displays[] =
 {
-  { { ".debug_abbrev",         ".zdebug_abbrev",       NULL,   NULL,   0,      0 },
+  { { ".debug_abbrev",         ".zdebug_abbrev",       NULL, NULL, 0, 0 },
     display_debug_abbrev,              &do_debug_abbrevs,      0 },
-  { { ".debug_aranges",                ".zdebug_aranges",      NULL,   NULL,   0,      0 },
+  { { ".debug_aranges",                ".zdebug_aranges",      NULL, NULL, 0, 0 },
     display_debug_aranges,             &do_debug_aranges,      1 },
-  { { ".debug_frame",          ".zdebug_frame",        NULL,   NULL,   0,      0 },
+  { { ".debug_frame",          ".zdebug_frame",        NULL, NULL, 0, 0 },
     display_debug_frames,              &do_debug_frames,       1 },
-  { { ".debug_info",           ".zdebug_info",         NULL,   NULL,   0,      0 },
+  { { ".debug_info",           ".zdebug_info",         NULL, NULL, 0, 0 },
     display_debug_info,                        &do_debug_info,         1 },
-  { { ".debug_line",           ".zdebug_line",         NULL,   NULL,   0,      0 },
+  { { ".debug_line",           ".zdebug_line",         NULL, NULL, 0, 0 },
     display_debug_lines,               &do_debug_lines,        1 },
-  { { ".debug_pubnames",       ".zdebug_pubnames",     NULL,   NULL,   0,      0 },
+  { { ".debug_pubnames",       ".zdebug_pubnames",     NULL, NULL, 0, 0 },
     display_debug_pubnames,            &do_debug_pubnames,     0 },
-  { { ".eh_frame",             "",                     NULL,   NULL,   0,      0 },
+  { { ".eh_frame",             "",                     NULL, NULL, 0, 0 },
     display_debug_frames,              &do_debug_frames,       1 },
-  { { ".debug_macinfo",                ".zdebug_macinfo",      NULL,   NULL,   0,      0 },
+  { { ".debug_macinfo",                ".zdebug_macinfo",      NULL, NULL, 0, 0 },
     display_debug_macinfo,             &do_debug_macinfo,      0 },
-  { { ".debug_str",            ".zdebug_str",          NULL,   NULL,   0,      0 },
+  { { ".debug_str",            ".zdebug_str",          NULL, NULL, 0, 0 },
     display_debug_str,                 &do_debug_str,          0 },
-  { { ".debug_loc",            ".zdebug_loc",          NULL,   NULL,   0,      0 },
+  { { ".debug_loc",            ".zdebug_loc",          NULL, NULL, 0, 0 },
     display_debug_loc,                 &do_debug_loc,          1 },
-  { { ".debug_pubtypes",       ".zdebug_pubtypes",     NULL,   NULL,   0,      0 },
-    display_debug_pubnames,            &do_debug_pubnames,     0 },
-  { { ".debug_ranges",         ".zdebug_ranges",       NULL,   NULL,   0,      0 },
+  { { ".debug_pubtypes",       ".zdebug_pubtypes",     NULL, NULL, 0, 0 },
+    display_debug_pubnames,            &do_debug_pubtypes,     0 },
+  { { ".debug_ranges",         ".zdebug_ranges",       NULL, NULL, 0, 0 },
     display_debug_ranges,              &do_debug_ranges,       1 },
-  { { ".debug_static_func",    ".zdebug_static_func",  NULL,   NULL,   0,      0 },
+  { { ".debug_static_func",    ".zdebug_static_func",  NULL, NULL, 0, 0 },
     display_debug_not_supported,       NULL,                   0 },
-  { { ".debug_static_vars",    ".zdebug_static_vars",  NULL,   NULL,   0,      0 },
+  { { ".debug_static_vars",    ".zdebug_static_vars",  NULL, NULL, 0, 0 },
     display_debug_not_supported,       NULL,                   0 },
-  { { ".debug_types",          ".zdebug_types",        NULL,   NULL,   0,      0 },
+  { { ".debug_types",          ".zdebug_types",        NULL, NULL, 0, 0 },
     display_debug_types,               &do_debug_info,         1 },
-  { { ".debug_weaknames",      ".zdebug_weaknames",    NULL,   NULL,   0,      0 },
-    display_debug_not_supported,       NULL,                   0 }
+  { { ".debug_weaknames",      ".zdebug_weaknames",    NULL, NULL, 0, 0 },
+    display_debug_not_supported,       NULL,                   0 },
+  { { ".trace_info",           "",                     NULL, NULL, 0, 0 },
+    display_trace_info,                        &do_trace_info,         1 },
+  { { ".trace_abbrev",         "",                     NULL, NULL, 0, 0 },
+    display_debug_abbrev,              &do_trace_abbrevs,      0 },
+  { { ".trace_aranges",                "",                     NULL, NULL, 0, 0 },
+    display_debug_aranges,             &do_trace_aranges,      0 }
 };
This page took 0.043832 seconds and 4 git commands to generate.