btrace: remove leftover comment
[deliverable/binutils-gdb.git] / binutils / dwarf.c
index 282e069958d1d59fd8a05a6e451d98ba62a325e7..fee6a605e71d452fcb3166b7dac166b548b0b65b 100644 (file)
@@ -1824,6 +1824,7 @@ read_and_display_attr_value (unsigned long attribute,
        {
        case DW_AT_frame_base:
          have_frame_base = 1;
+         /* Fall through.  */
        case DW_AT_location:
        case DW_AT_string_length:
        case DW_AT_return_addr:
@@ -2099,6 +2100,7 @@ read_and_display_attr_value (unsigned long attribute,
 
     case DW_AT_frame_base:
       have_frame_base = 1;
+      /* Fall through.  */
     case DW_AT_location:
     case DW_AT_string_length:
     case DW_AT_return_addr:
@@ -3252,16 +3254,32 @@ display_debug_lines_decoded (struct dwarf_section *section,
 
          /* Traverse the Directory table just to count entries.  */
          data = standard_opcodes + linfo.li_opcode_base - 1;
+         /* PR 20440 */
+         if (data >= end)
+           {
+             warn (_("opcode base of %d extends beyond end of section\n"),
+                   linfo.li_opcode_base);
+             return 0;
+           }
+
          if (*data != 0)
            {
              unsigned char *ptr_directory_table = data;
 
-             while (*data != 0)
+             while (data < end && *data != 0)
                {
                  data += strnlen ((char *) data, end - data) + 1;
                  n_directories++;
                }
 
+             /* PR 20440 */
+             if (data >= end)
+               {
+                 warn (_("directory table ends unexpectedly\n"));
+                 n_directories = 0;
+                 break;
+               }
+
              /* Go through the directory table again to save the directories.  */
              directory_table = (unsigned char **)
                xmalloc (n_directories * sizeof (unsigned char *));
@@ -3279,11 +3297,11 @@ display_debug_lines_decoded (struct dwarf_section *section,
          data++;
 
          /* Traverse the File Name table just to count the entries.  */
-         if (*data != 0)
+         if (data < end && *data != 0)
            {
              unsigned char *ptr_file_name_table = data;
 
-             while (*data != 0)
+             while (data < end && *data != 0)
                {
                  unsigned int bytes_read;
 
@@ -3300,6 +3318,13 @@ display_debug_lines_decoded (struct dwarf_section *section,
                  n_files++;
                }
 
+             if (data >= end)
+               {
+                 warn (_("file table ends unexpectedly\n"));
+                 n_files = 0;
+                 break;
+               }
+
              /* Go through the file table again to save the strings.  */
              file_table = (File_Entry *) xmalloc (n_files * sizeof (File_Entry));
 
@@ -3334,7 +3359,20 @@ display_debug_lines_decoded (struct dwarf_section *section,
              else
                {
                  unsigned int ix = file_table[0].directory_index;
-                 const char *directory = ix ? (char *)directory_table[ix - 1] : ".";
+                 const char *directory;
+
+                 if (ix == 0)
+                   directory = ".";
+                 /* PR 20439 */
+                 else if (n_directories == 0)
+                   directory = _("<unknown>");
+                 else if (ix > n_directories)
+                   {
+                     warn (_("directory index %u > number of directories %u\n"), ix, n_directories);
+                     directory = _("<corrupt>");
+                   }
+                 else
+                   directory = (char *) directory_table[ix - 1];
 
                  if (do_wide || strlen (directory) < 76)
                    printf (_("CU: %s/%s:\n"), directory, file_table[0].name);
@@ -3492,20 +3530,35 @@ display_debug_lines_decoded (struct dwarf_section *section,
                   data += bytes_read;
                   state_machine_regs.file = adv;
 
-                  if (file_table == NULL)
-                    printf (_("\n [Use file table entry %d]\n"), state_machine_regs.file - 1);
-                  else if (file_table[state_machine_regs.file - 1].directory_index == 0)
-                    /* If directory index is 0, that means current directory.  */
-                    printf ("\n./%s:[++]\n",
-                            file_table[state_machine_regs.file - 1].name);
-                  else if (directory_table == NULL)
-                    printf (_("\n [Use directory table entry %d]\n"),
-                            file_table[state_machine_regs.file - 1].directory_index - 1);
-                  else
-                    /* The directory index starts counting at 1.  */
-                    printf ("\n%s/%s:\n",
-                            directory_table[file_table[state_machine_regs.file - 1].directory_index - 1],
-                            file_table[state_machine_regs.file - 1].name);
+                  {
+                    unsigned file = state_machine_regs.file - 1;
+                    unsigned dir;
+
+                    if (file_table == NULL || n_files == 0)
+                      printf (_("\n [Use file table entry %d]\n"), file);
+                    /* PR 20439 */
+                    else if (file >= n_files)
+                      {
+                        warn (_("file index %u > number of files %u\n"), file + 1, n_files);
+                        printf (_("\n <over large file table index %u>"), file);
+                      }
+                    else if ((dir = file_table[file].directory_index) == 0)
+                      /* If directory index is 0, that means current directory.  */
+                      printf ("\n./%s:[++]\n", file_table[file].name);
+                    else if (directory_table == NULL || n_directories == 0)
+                      printf (_("\n [Use file %s in directory table entry %d]\n"),
+                              file_table[file].name, dir);
+                    /* PR 20439 */
+                    else if (dir > n_directories)
+                      {
+                        warn (_("directory index %u > number of directories %u\n"), dir, n_directories);
+                        printf (_("\n <over large directory table entry %u>\n"), dir);
+                      }
+                    else
+                      printf ("\n%s/%s:\n",
+                              /* The directory index starts counting at 1.  */
+                              directory_table[dir - 1], file_table[file].name);
+                  }
                   break;
 
                 case DW_LNS_set_column:
@@ -3587,9 +3640,19 @@ display_debug_lines_decoded (struct dwarf_section *section,
              size_t fileNameLength;
 
              if (file_table)
-               fileName = (char *) file_table[state_machine_regs.file - 1].name;
+               {
+                 unsigned indx = state_machine_regs.file - 1;
+                 /* PR 20439  */
+                 if (indx >= n_files)
+                   {
+                     warn (_("corrupt file index %u encountered\n"), indx);
+                     fileName = _("<corrupt>");
+                   }
+                 else
+                   fileName = (char *) file_table[indx].name;
+               }
              else
-               fileName = "<unknown>";
+               fileName = _("<unknown>");
 
              fileNameLength = strlen (fileName);
 
@@ -5544,7 +5607,7 @@ frame_display_row (Frame_Chunk *fc, int *need_col_headers, unsigned int *max_reg
   unsigned int r;
   char tmp[100];
 
-  if (*max_regs < fc->ncols)
+  if (*max_regs != fc->ncols)
     *max_regs = fc->ncols;
 
   if (*need_col_headers)
@@ -5559,7 +5622,7 @@ frame_display_row (Frame_Chunk *fc, int *need_col_headers, unsigned int *max_reg
        if (fc->col_type[r] != DW_CFA_unreferenced)
          {
            if (r == fc->ra)
-             printf ("ra      ");
+             printf ("ra    ");
            else
              printf ("%-5s ", regname (r, 1));
          }
@@ -6270,19 +6333,25 @@ display_debug_frames (struct dwarf_section *section,
              break;
 
            case DW_CFA_restore:
-             if (opa >= (unsigned int) cie->ncols
-                 || opa >= (unsigned int) fc->ncols)
+             if (opa >= (unsigned int) fc->ncols)
                reg_prefix = bad_reg;
              if (! do_debug_frames_interp || *reg_prefix != '\0')
                printf ("  DW_CFA_restore: %s%s\n",
                        reg_prefix, regname (opa, 0));
-             if (*reg_prefix == '\0')
+             if (*reg_prefix != '\0')
+               break;
+
+             if (opa >= (unsigned int) cie->ncols
+                 || (do_debug_frames_interp
+                     && cie->col_type[opa] == DW_CFA_unreferenced))
+               {
+                 fc->col_type[opa] = DW_CFA_undefined;
+                 fc->col_offset[opa] = 0;
+               }
+             else
                {
                  fc->col_type[opa] = cie->col_type[opa];
                  fc->col_offset[opa] = cie->col_offset[opa];
-                 if (do_debug_frames_interp
-                     && fc->col_type[opa] == DW_CFA_unreferenced)
-                   fc->col_type[opa] = DW_CFA_undefined;
                }
              break;
 
@@ -6357,7 +6426,7 @@ display_debug_frames (struct dwarf_section *section,
              if (reg >= (unsigned int) fc->ncols)
                reg_prefix = bad_reg;
              if (! do_debug_frames_interp || *reg_prefix != '\0')
-               printf ("  DW_CFA_val_offset: %s%s at cfa%+ld\n",
+               printf ("  DW_CFA_val_offset: %s%s is cfa%+ld\n",
                        reg_prefix, regname (reg, 0),
                        roffs * fc->data_factor);
              if (*reg_prefix == '\0')
@@ -6369,13 +6438,20 @@ display_debug_frames (struct dwarf_section *section,
 
            case DW_CFA_restore_extended:
              reg = LEB ();
-             if (reg >= (unsigned int) cie->ncols
-                 || reg >= (unsigned int) fc->ncols)
+             if (reg >= (unsigned int) fc->ncols)
                reg_prefix = bad_reg;
              if (! do_debug_frames_interp || *reg_prefix != '\0')
                printf ("  DW_CFA_restore_extended: %s%s\n",
                        reg_prefix, regname (reg, 0));
-             if (*reg_prefix == '\0')
+             if (*reg_prefix != '\0')
+               break;
+
+             if (reg >= (unsigned int) cie->ncols)
+               {
+                 fc->col_type[reg] = DW_CFA_undefined;
+                 fc->col_offset[reg] = 0;
+               }
+             else
                {
                  fc->col_type[reg] = cie->col_type[reg];
                  fc->col_offset[reg] = cie->col_offset[reg];
@@ -6592,7 +6668,7 @@ display_debug_frames (struct dwarf_section *section,
              if (frame_need_space (fc, reg) < 0)
                reg_prefix = bad_reg;
              if (! do_debug_frames_interp || *reg_prefix != '\0')
-               printf ("  DW_CFA_val_offset_sf: %s%s at cfa%+ld\n",
+               printf ("  DW_CFA_val_offset_sf: %s%s is cfa%+ld\n",
                        reg_prefix, regname (reg, 0),
                        (long)(l * fc->data_factor));
              if (*reg_prefix == '\0')
@@ -7580,6 +7656,7 @@ dwarf_select_sections_by_letters (const char *letters)
 
       case 'F':
        do_debug_frames_interp = 1;
+       /* Fall through.  */
       case 'f':
        do_debug_frames = 1;
        break;
This page took 0.027418 seconds and 4 git commands to generate.