Close memory and resource leaks detected by coverity in the binutils directory.
[deliverable/binutils-gdb.git] / binutils / unwind-ia64.c
index 38382351a8f6e33b2422e80c1cb08b4010c61dac..e98f9d349431cf822f60ec92293db4fe314d9b6a 100644 (file)
@@ -1,6 +1,7 @@
 /* unwind-ia64.c -- utility routines to dump IA-64 unwind info for readelf.
-   Copyright 2000, 2001, 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
-       Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+   Copyright (C) 2000-2018 Free Software Foundation, Inc.
+
+   Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
 
    This file is part of GNU Binutils.
 
@@ -19,6 +20,7 @@
    Foundation, 51 Franklin Street - Fifth Floor, Boston,
    MA 02110-1301, USA.  */
 
+#include "config.h"
 #include "unwind-ia64.h"
 #include <stdio.h>
 #include <string.h>
@@ -347,14 +349,22 @@ typedef bfd_vma unw_word;
   printf ("\t%s:spill_base(pspoff=0x10-0x%lx)\n",              \
          fmt, 4*(unsigned long)pspoff)
 
-#define UNW_DEC_SPILL_MASK(fmt, dp, arg)                                       \
-  do                                                                           \
-    {                                                                          \
-      static const char *spill_type = "-frb";                                  \
+#define UNW_DEC_SPILL_MASK(fmt, dp, arg, end)                          \
+  do                                                                   \
+    {                                                                  \
+      static const char *spill_type = "-frb";                          \
       unsigned const char *imaskp = dp;                                        \
-      unsigned char mask = 0;                                                  \
-      bfd_vma insn = 0;                                                                \
-                                                                               \
+      unsigned char mask = 0;                                          \
+      bfd_vma insn = 0;                                                        \
+                                                                       \
+      /* PR 18420.  */                                                 \
+      if ((dp + (unw_rlen / 4)) > end)                                 \
+       {                                                               \
+         printf ("\nERROR: unwind length too long (0x%lx > 0x%lx)\n\n",\
+                 (long) (unw_rlen / 4), (long)(end - dp));             \
+         /* FIXME: Should we reset unw_rlen ?  */                      \
+         break;                                                        \
+       }                                                               \
       printf ("\t%s:spill_mask(imask=[", fmt);                                 \
       for (insn = 0; insn < unw_rlen; ++insn)                                  \
        {                                                                       \
@@ -531,36 +541,6 @@ typedef bfd_vma unw_word;
  *     UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
  */
 
-static unw_word unw_decode_uleb128 (const unsigned char **);
-static const unsigned char *unw_decode_x1
-  (const unsigned char *, unsigned int, void *);
-static const unsigned char *unw_decode_x2
-  (const unsigned char *, unsigned int, void *);
-static const unsigned char *unw_decode_x3
-  (const unsigned char *, unsigned int, void *);
-static const unsigned char *unw_decode_x4
-  (const unsigned char *, unsigned int, void *);
-static const unsigned char *unw_decode_r1
-  (const unsigned char *, unsigned int, void *);
-static const unsigned char *unw_decode_r2
-  (const unsigned char *, unsigned int, void *);
-static const unsigned char *unw_decode_r3
-  (const unsigned char *, unsigned int, void *);
-static const unsigned char *unw_decode_p1
-  (const unsigned char *, unsigned int, void *);
-static const unsigned char *unw_decode_p2_p5
-  (const unsigned char *, unsigned int, void *);
-static const unsigned char *unw_decode_p6
-  (const unsigned char *, unsigned int, void *);
-static const unsigned char *unw_decode_p7_p10
-  (const unsigned char *, unsigned int, void *);
-static const unsigned char *unw_decode_b1
-  (const unsigned char *, unsigned int, void *);
-static const unsigned char *unw_decode_b2
-  (const unsigned char *, unsigned int, void *);
-static const unsigned char *unw_decode_b3_x4
-  (const unsigned char *, unsigned int, void *);
-
 static unw_word
 unw_decode_uleb128 (const unsigned char **dpp)
 {
@@ -669,7 +649,8 @@ unw_decode_x4 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
 }
 
 static const unsigned char *
-unw_decode_r1 (const unsigned char *dp, unsigned int code, void *arg)
+unw_decode_r1 (const unsigned char *dp, unsigned int code, void *arg,
+              const unsigned char * end ATTRIBUTE_UNUSED)
 {
   int body = (code & 0x20) != 0;
   unw_word rlen;
@@ -680,7 +661,8 @@ unw_decode_r1 (const unsigned char *dp, unsigned int code, void *arg)
 }
 
 static const unsigned char *
-unw_decode_r2 (const unsigned char *dp, unsigned int code, void *arg)
+unw_decode_r2 (const unsigned char *dp, unsigned int code, void *arg,
+              const unsigned char * end ATTRIBUTE_UNUSED)
 {
   unsigned char byte1, mask, grsave;
   unw_word rlen;
@@ -695,7 +677,8 @@ unw_decode_r2 (const unsigned char *dp, unsigned int code, void *arg)
 }
 
 static const unsigned char *
-unw_decode_r3 (const unsigned char *dp, unsigned int code, void *arg)
+unw_decode_r3 (const unsigned char *dp, unsigned int code, void *arg,
+              const unsigned char * end ATTRIBUTE_UNUSED)
 {
   unw_word rlen;
 
@@ -706,7 +689,8 @@ unw_decode_r3 (const unsigned char *dp, unsigned int code, void *arg)
 
 static const unsigned char *
 unw_decode_p1 (const unsigned char *dp, unsigned int code,
-              void *arg ATTRIBUTE_UNUSED)
+              void *arg ATTRIBUTE_UNUSED,
+              const unsigned char * end ATTRIBUTE_UNUSED)
 {
   unsigned char brmask = (code & 0x1f);
 
@@ -716,7 +700,8 @@ unw_decode_p1 (const unsigned char *dp, unsigned int code,
 
 static const unsigned char *
 unw_decode_p2_p5 (const unsigned char *dp, unsigned int code,
-                 void *arg ATTRIBUTE_UNUSED)
+                 void *arg ATTRIBUTE_UNUSED,
+                 const unsigned char * end)
 {
   if ((code & 0x10) == 0)
     {
@@ -775,7 +760,7 @@ unw_decode_p2_p5 (const unsigned char *dp, unsigned int code,
        }
     }
   else if ((code & 0x7) == 0)
-    UNW_DEC_SPILL_MASK ("P4", dp, arg);
+    UNW_DEC_SPILL_MASK ("P4", dp, arg, end);
   else if ((code & 0x7) == 1)
     {
       unw_word grmask, frmask, byte1, byte2, byte3;
@@ -795,7 +780,8 @@ unw_decode_p2_p5 (const unsigned char *dp, unsigned int code,
 
 static const unsigned char *
 unw_decode_p6 (const unsigned char *dp, unsigned int code,
-              void *arg ATTRIBUTE_UNUSED)
+              void *arg ATTRIBUTE_UNUSED,
+              const unsigned char * end ATTRIBUTE_UNUSED)
 {
   int gregs = (code & 0x10) != 0;
   unsigned char mask = (code & 0x0f);
@@ -808,7 +794,8 @@ unw_decode_p6 (const unsigned char *dp, unsigned int code,
 }
 
 static const unsigned char *
-unw_decode_p7_p10 (const unsigned char *dp, unsigned int code, void *arg)
+unw_decode_p7_p10 (const unsigned char *dp, unsigned int code, void *arg,
+                  const unsigned char * end ATTRIBUTE_UNUSED)
 {
   unsigned char r, byte1, byte2;
   unw_word t, size;
@@ -982,7 +969,8 @@ unw_decode_p7_p10 (const unsigned char *dp, unsigned int code, void *arg)
 
 static const unsigned char *
 unw_decode_b1 (const unsigned char *dp, unsigned int code,
-              void *arg ATTRIBUTE_UNUSED)
+              void *arg ATTRIBUTE_UNUSED,
+              const unsigned char * end ATTRIBUTE_UNUSED)
 {
   unw_word label = (code & 0x1f);
 
@@ -995,7 +983,8 @@ unw_decode_b1 (const unsigned char *dp, unsigned int code,
 
 static const unsigned char *
 unw_decode_b2 (const unsigned char *dp, unsigned int code,
-              void *arg ATTRIBUTE_UNUSED)
+              void *arg ATTRIBUTE_UNUSED,
+              const unsigned char * end ATTRIBUTE_UNUSED)
 {
   unw_word t;
 
@@ -1005,7 +994,8 @@ unw_decode_b2 (const unsigned char *dp, unsigned int code,
 }
 
 static const unsigned char *
-unw_decode_b3_x4 (const unsigned char *dp, unsigned int code, void *arg)
+unw_decode_b3_x4 (const unsigned char *dp, unsigned int code, void *arg,
+                 const unsigned char * end ATTRIBUTE_UNUSED)
 {
   unw_word t, ecount, label;
 
@@ -1042,7 +1032,7 @@ unw_decode_b3_x4 (const unsigned char *dp, unsigned int code, void *arg)
 }
 
 typedef const unsigned char *(*unw_decoder)
-     (const unsigned char *, unsigned int, void *);
+  (const unsigned char *, unsigned int, void *, const unsigned char *);
 
 static const unw_decoder unw_decode_table[2][8] =
   {
@@ -1072,12 +1062,12 @@ static const unw_decoder unw_decode_table[2][8] =
 /* Decode one descriptor and return address of next descriptor.  */
 const unsigned char *
 unw_decode (const unsigned char *dp, int inside_body,
-           void *ptr_inside_body)
+           void *ptr_inside_body, const unsigned char * end)
 {
   unw_decoder decoder;
   unsigned char code;
 
   code = *dp++;
   decoder = unw_decode_table[inside_body][code >> 5];
-  return (*decoder) (dp, code, ptr_inside_body);
+  return (*decoder) (dp, code, ptr_inside_body, end);
 }
This page took 0.027081 seconds and 4 git commands to generate.