[ARC] Don't allow pc-rel relocations for J* instructions.
[deliverable/binutils-gdb.git] / binutils / unwind-ia64.c
index 7c06c7b49aef3f4687401f4084dddc3eeb13cd3f..43c1b0f4c29639ab65f8bf847130703ec0afa177 100644 (file)
@@ -1,23 +1,26 @@
 /* unwind-ia64.c -- utility routines to dump IA-64 unwind info for readelf.
-   Copyright 2000, 2001, 2003 Free Software Foundation, Inc.
-       Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
+   Copyright (C) 2000-2016 Free Software Foundation, Inc.
 
-This file is part of GNU Binutils.
+   Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
 
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+   This file is part of GNU Binutils.
 
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
 
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#include "config.h"
 #include "unwind-ia64.h"
 #include <stdio.h>
 #include <string.h>
@@ -25,7 +28,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #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.
-   Only do this if we belive that the compiler can support a 64 bit
+   Only do this if we believe 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
@@ -111,7 +114,7 @@ unw_print_frmask (char *cp, unsigned int mask)
 static void
 unw_print_abreg (char *cp, unsigned int abreg)
 {
-  static const char *special_reg[16] =
+  static const char * const special_reg[16] =
   {
     "pr", "psp", "@priunat", "rp", "ar.bsp", "ar.bspstore", "ar.rnat",
     "ar.unat", "ar.fpsr", "ar.pfs", "ar.lc",
@@ -302,7 +305,7 @@ typedef bfd_vma unw_word;
 #define UNW_DEC_ABI(fmt, abi, context, arg)                    \
   do                                                           \
     {                                                          \
-      static const char *abiname[] =                           \
+      static const char * const abiname[] =                    \
       {                                                                \
        "@svr4", "@hpux", "@nt"                                 \
       };                                                       \
@@ -346,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)                                  \
        {                                                                       \
@@ -371,7 +382,7 @@ typedef bfd_vma unw_word;
 #define UNW_DEC_SPILL_SPREL(fmt, t, abreg, spoff, arg)                         \
   do                                                                           \
     {                                                                          \
-      char regname[10];                                                                \
+      char regname[20];                                                                \
                                                                                \
       unw_print_abreg (regname, abreg);                                                \
       printf ("\t%s:spill_sprel(reg=%s,t=%lu,spoff=0x%lx)\n",                  \
@@ -382,7 +393,7 @@ typedef bfd_vma unw_word;
 #define UNW_DEC_SPILL_PSPREL(fmt, t, abreg, pspoff, arg)                       \
   do                                                                           \
     {                                                                          \
-      char regname[10];                                                                \
+      char regname[20];                                                                \
                                                                                \
       unw_print_abreg (regname, abreg);                                                \
       printf ("\t%s:spill_psprel(reg=%s,t=%lu,pspoff=0x10-0x%lx)\n",           \
@@ -393,7 +404,7 @@ typedef bfd_vma unw_word;
 #define UNW_DEC_RESTORE(fmt, t, abreg, arg)                    \
   do                                                           \
     {                                                          \
-      char regname[10];                                                \
+      char regname[20];                                                \
                                                                \
       unw_print_abreg (regname, abreg);                                \
       printf ("\t%s:restore(t=%lu,reg=%s)\n",                  \
@@ -404,7 +415,7 @@ typedef bfd_vma unw_word;
 #define UNW_DEC_SPILL_REG(fmt, t, abreg, x, ytreg, arg)                \
   do                                                           \
     {                                                          \
-      char abregname[10], tregname[10];                                \
+      char abregname[20], tregname[20];                                \
                                                                \
       unw_print_abreg (abregname, abreg);                      \
       unw_print_xyreg (tregname, x, ytreg);                    \
@@ -530,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)
 {
@@ -668,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;
@@ -679,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;
@@ -694,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;
 
@@ -705,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);
 
@@ -715,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)
     {
@@ -774,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;
@@ -794,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);
@@ -807,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;
@@ -981,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);
 
@@ -994,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;
 
@@ -1004,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;
 
@@ -1041,9 +1032,9 @@ 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 unw_decoder unw_decode_table[2][8] =
+static const unw_decoder unw_decode_table[2][8] =
   {
     /* prologue table: */
     {
@@ -1071,12 +1062,12 @@ static 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.029187 seconds and 4 git commands to generate.