]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - binutils/readelf.c
MIPS: Add Octeon 3 support
[thirdparty/binutils-gdb.git] / binutils / readelf.c
index 3cf46d8b16be7a22610523e40c718ae93201f391..f5aa28d9da50467092fe7841043dec53031bb7d2 100644 (file)
 char * program_name = "readelf";
 static long archive_file_offset;
 static unsigned long archive_file_size;
+static bfd_size_type current_file_size;
 static unsigned long dynamic_addr;
 static bfd_size_type dynamic_size;
 static unsigned int dynamic_nent;
@@ -4341,6 +4342,9 @@ process_program_headers (FILE * file)
            }
        }
 
+      if (do_segments)
+       putc ('\n', stdout);
+
       switch (segment->p_type)
        {
        case PT_DYNAMIC:
@@ -4351,6 +4355,12 @@ process_program_headers (FILE * file)
             section in the DYNAMIC segment.  */
          dynamic_addr = segment->p_offset;
          dynamic_size = segment->p_filesz;
+         /* PR binutils/17512: Avoid corrupt dynamic section info in the segment.  */
+         if (dynamic_addr + dynamic_size >= current_file_size)
+           {
+             error (_("the dynamic segment offset + size exceeds the size of the file\n"));
+             dynamic_addr = dynamic_size = 0;
+           }
 
          /* Try to locate the .dynamic section. If there is
             a section header table, we can easily locate it.  */
@@ -4394,7 +4404,7 @@ process_program_headers (FILE * file)
          else
            {
              char fmt [32];
-             int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX);
+             int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
 
              if (ret >= (int) sizeof (fmt) || ret < 0)
                error (_("Internal error: failed to create format string to display program interpreter\n"));
@@ -4404,14 +4414,11 @@ process_program_headers (FILE * file)
                error (_("Unable to read program interpreter name\n"));
 
              if (do_segments)
-               printf (_("\n      [Requesting program interpreter: %s]"),
+               printf (_("      [Requesting program interpreter: %s]\n"),
                    program_interpreter);
            }
          break;
        }
-
-      if (do_segments)
-       putc ('\n', stdout);
     }
 
   if (do_segments && section_headers != NULL && string_table != NULL)
@@ -4580,6 +4587,13 @@ get_32bit_elf_symbols (FILE * file,
       goto exit_point;
     }
 
+  if (section->sh_size > current_file_size)
+    {
+      error (_("Section %s has an invalid sh_size of 0x%lx\n"),
+            SECTION_NAME (section), section->sh_size);
+      goto exit_point;
+    }
+
   number = section->sh_size / section->sh_entsize;
 
   if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
@@ -4660,6 +4674,13 @@ get_64bit_elf_symbols (FILE * file,
       goto exit_point;
     }
 
+  if (section->sh_size > current_file_size)
+    {
+      error (_("Section %s has an invalid sh_size of 0x%lx\n"),
+            SECTION_NAME (section), section->sh_size);
+      goto exit_point;
+    }
+
   number = section->sh_size / section->sh_entsize;
 
   if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
@@ -5054,19 +5075,22 @@ process_section_headers (FILE * file)
       break;
     }
 
-#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
-  do                                                                       \
-    {                                                                      \
-      bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64;     \
-      if (section->sh_entsize != expected_entsize)                         \
+#define CHECK_ENTSIZE_VALUES(section, i, size32, size64)               \
+  do                                                                   \
+    {                                                                  \
+      bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
+      if (section->sh_entsize != expected_entsize)                     \
        {                                                               \
-         error (_("Section %d has invalid sh_entsize of %" BFD_VMA_FMT "x\n"), \
-                i, section->sh_entsize);       \
-         error (_("(Using the expected size of %d for the rest of this dump)\n"), \
-                  (int) expected_entsize); \
+         char buf[40];                                                 \
+         sprintf_vma (buf, section->sh_entsize);                       \
+         /* Note: coded this way so that there is a single string for  \
+            translation.  */ \
+         error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
+         error (_("(Using the expected size of %u for the rest of this dump)\n"), \
+                  (unsigned) expected_entsize);                        \
          section->sh_entsize = expected_entsize;                       \
-       } \
-    }                                                                      \
+       }                                                               \
+    }                                                                  \
   while (0)
 
 #define CHECK_ENTSIZE(section, i, type)                                        \
@@ -7776,7 +7800,12 @@ dynamic_section_mips_val (Elf_Internal_Dyn * entry)
       if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
        printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
       else
-       printf (_("<corrupt: %" BFD_VMA_FMT "d>"), entry->d_un.d_ptr);
+       {
+         char buf[40];
+         sprintf_vma (buf, entry->d_un.d_ptr);
+         /* Note: coded this way so that there is a single string for translation.  */
+         printf (_("<corrupt: %s>"), buf);
+       }
       break;
 
     case DT_MIPS_TIME_STAMP:
@@ -12723,6 +12752,8 @@ print_mips_ases (unsigned int mask)
     fputs ("\n\tXPA ASE", stdout);
   if (mask == 0)
     fprintf (stdout, "\n\t%s", _("None"));
+  else if ((mask & ~AFL_ASE_MASK) != 0)
+    fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
 }
 
 static void
@@ -12736,6 +12767,9 @@ print_mips_isa_ext (unsigned int isa_ext)
     case AFL_EXT_XLR:
       fputs ("RMI XLR", stdout);
       break;
+    case AFL_EXT_OCTEON3:
+      fputs ("Cavium Networks Octeon3", stdout);
+      break;
     case AFL_EXT_OCTEON2:
       fputs ("Cavium Networks Octeon2", stdout);
       break;
@@ -12788,7 +12822,7 @@ print_mips_isa_ext (unsigned int isa_ext)
       fputs ("ST Microelectronics Loongson 2F", stdout);
       break;
     default:
-      fputs (_("Unknown"), stdout);
+      fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
     }
 }
 
@@ -14876,6 +14910,8 @@ process_file (char * file_name)
       return 1;
     }
 
+  current_file_size = (bfd_size_type) statbuf.st_size;
+
   if (memcmp (armag, ARMAG, SARMAG) == 0)
     ret = process_archive (file_name, file, FALSE);
   else if (memcmp (armag, ARMAGT, SARMAG) == 0)
@@ -14893,6 +14929,7 @@ process_file (char * file_name)
 
   fclose (file);
 
+  current_file_size = 0;
   return ret;
 }