X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=binutils%2Funwind-ia64.c;h=f6f73ce83ea895fa95a64b9cc0b05e8d7eeb7c53;hb=62e6599087efba193e0156d89ee65fb74fc99cb2;hp=8c91d651a114cf83b132abac0b319c0b6160e10a;hpb=2571583aed598dd3f9651b53434e5f177a0e3cf7;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/unwind-ia64.c b/binutils/unwind-ia64.c index 8c91d651a1..f6f73ce83e 100644 --- a/binutils/unwind-ia64.c +++ b/binutils/unwind-ia64.c @@ -1,5 +1,5 @@ /* unwind-ia64.c -- utility routines to dump IA-64 unwind info for readelf. - Copyright (C) 2000-2017 Free Software Foundation, Inc. + Copyright (C) 2000-2019 Free Software Foundation, Inc. Contributed by David Mosberger-Tang @@ -21,9 +21,8 @@ MA 02110-1301, USA. */ #include "config.h" +#include "sysdep.h" #include "unwind-ia64.h" -#include -#include #if __GNUC__ >= 2 /* Define BFD64 here, even if our default architecture is 32 bit ELF @@ -174,7 +173,7 @@ unw_print_xyreg (char *cp, unsigned int x, unsigned int ytreg) typedef bfd_vma unw_word; #define UNW_DEC_BAD_CODE(code) \ - printf ("Unknown code 0x%02x\n", code) + printf (_("Unknown code 0x%02x\n"), code) #define UNW_DEC_PROLOGUE(fmt, body, rlen, arg) \ do \ @@ -360,7 +359,7 @@ typedef bfd_vma unw_word; /* PR 18420. */ \ if ((dp + (unw_rlen / 4)) > end) \ { \ - printf ("\nERROR: unwind length too long (0x%lx > 0x%lx)\n\n",\ + 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; \ @@ -542,13 +541,13 @@ typedef bfd_vma unw_word; */ static unw_word -unw_decode_uleb128 (const unsigned char **dpp) +unw_decode_uleb128 (const unsigned char **dpp, const unsigned char * end) { unsigned shift = 0; unw_word byte, result = 0; const unsigned char *bp = *dpp; - while (1) + while (bp < end) { byte = *bp++; result |= (byte & 0x7f) << shift; @@ -566,14 +565,20 @@ unw_decode_uleb128 (const unsigned char **dpp) static const unsigned char * unw_decode_x1 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED, - void *arg ATTRIBUTE_UNUSED) + void *arg ATTRIBUTE_UNUSED, const unsigned char * end) { unsigned char byte1, abreg; unw_word t, off; + if ((end - dp) < 3) + { + printf (_("\t\n")); + return end; + } + byte1 = *dp++; - t = unw_decode_uleb128 (&dp); - off = unw_decode_uleb128 (&dp); + t = unw_decode_uleb128 (&dp, end); + off = unw_decode_uleb128 (&dp, end); abreg = (byte1 & 0x7f); if (byte1 & 0x80) UNW_DEC_SPILL_SPREL ("X1", t, abreg, off, arg); @@ -584,14 +589,20 @@ unw_decode_x1 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED, static const unsigned char * unw_decode_x2 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED, - void *arg ATTRIBUTE_UNUSED) + void *arg ATTRIBUTE_UNUSED, const unsigned char * end) { unsigned char byte1, byte2, abreg, x, ytreg; unw_word t; + if ((end - dp) < 3) + { + printf (_("\t\n")); + return end; + } + byte1 = *dp++; byte2 = *dp++; - t = unw_decode_uleb128 (&dp); + t = unw_decode_uleb128 (&dp, end); abreg = (byte1 & 0x7f); ytreg = byte2; x = (byte1 >> 7) & 1; @@ -604,15 +615,21 @@ unw_decode_x2 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED, static const unsigned char * unw_decode_x3 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED, - void *arg ATTRIBUTE_UNUSED) + void *arg ATTRIBUTE_UNUSED, const unsigned char * end) { unsigned char byte1, byte2, abreg, qp; unw_word t, off; + if ((end - dp) < 4) + { + printf (_("\t\n")); + return end; + } + byte1 = *dp++; byte2 = *dp++; - t = unw_decode_uleb128 (&dp); - off = unw_decode_uleb128 (&dp); + t = unw_decode_uleb128 (&dp, end); + off = unw_decode_uleb128 (&dp, end); qp = (byte1 & 0x3f); abreg = (byte2 & 0x7f); @@ -626,15 +643,21 @@ unw_decode_x3 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED, static const unsigned char * unw_decode_x4 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED, - void *arg ATTRIBUTE_UNUSED) + void *arg ATTRIBUTE_UNUSED, const unsigned char * end) { unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg; unw_word t; + if ((end - dp) < 4) + { + printf (_("\t\n")); + return end; + } + byte1 = *dp++; byte2 = *dp++; byte3 = *dp++; - t = unw_decode_uleb128 (&dp); + t = unw_decode_uleb128 (&dp, end); qp = (byte1 & 0x3f); abreg = (byte2 & 0x7f); @@ -662,27 +685,33 @@ 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, - const unsigned char * end ATTRIBUTE_UNUSED) + const unsigned char * end) { unsigned char byte1, mask, grsave; unw_word rlen; + if ((end - dp) < 2) + { + printf (_("\t\n")); + return end; + } + byte1 = *dp++; mask = ((code & 0x7) << 1) | ((byte1 >> 7) & 1); grsave = (byte1 & 0x7f); - rlen = unw_decode_uleb128 (& dp); + rlen = unw_decode_uleb128 (& dp, end); UNW_DEC_PROLOGUE_GR ("R2", rlen, mask, grsave, arg); return dp; } static const unsigned char * unw_decode_r3 (const unsigned char *dp, unsigned int code, void *arg, - const unsigned char * end ATTRIBUTE_UNUSED) + const unsigned char * end) { unw_word rlen; - rlen = unw_decode_uleb128 (& dp); + rlen = unw_decode_uleb128 (& dp, end); UNW_DEC_PROLOGUE ("R3", ((code & 0x3) == 1), rlen, arg); return dp; } @@ -705,14 +734,30 @@ unw_decode_p2_p5 (const unsigned char *dp, unsigned int code, { if ((code & 0x10) == 0) { - unsigned char byte1 = *dp++; + unsigned char byte1; + + if ((end - dp) < 1) + { + printf (_("\t\n")); + return end; + } + + byte1 = *dp++; UNW_DEC_BR_GR ("P2", ((code & 0xf) << 1) | ((byte1 >> 7) & 1), (byte1 & 0x7f), arg); } else if ((code & 0x08) == 0) { - unsigned char byte1 = *dp++, r, dst; + unsigned char byte1, r, dst; + + if ((end - dp) < 1) + { + printf (_("\t\n")); + return end; + } + + byte1 = *dp++; r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1); dst = (byte1 & 0x7f); @@ -765,6 +810,11 @@ unw_decode_p2_p5 (const unsigned char *dp, unsigned int code, { unw_word grmask, frmask, byte1, byte2, byte3; + if ((end - dp) < 3) + { + printf (_("\t\n")); + return end; + } byte1 = *dp++; byte2 = *dp++; byte3 = *dp++; @@ -795,7 +845,7 @@ 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, - const unsigned char * end ATTRIBUTE_UNUSED) + const unsigned char * end) { unsigned char r, byte1, byte2; unw_word t, size; @@ -803,11 +853,11 @@ unw_decode_p7_p10 (const unsigned char *dp, unsigned int code, void *arg, if ((code & 0x10) == 0) { r = (code & 0xf); - t = unw_decode_uleb128 (&dp); + t = unw_decode_uleb128 (&dp, end); switch (r) { case 0: - size = unw_decode_uleb128 (&dp); + size = unw_decode_uleb128 (&dp, end); UNW_DEC_MEM_STACK_F ("P7", t, size, arg); break; @@ -867,8 +917,14 @@ unw_decode_p7_p10 (const unsigned char *dp, unsigned int code, void *arg, { case 0x0: /* p8 */ { + if ((end - dp) < 2) + { + printf (_("\t\n")); + return end; + } + r = *dp++; - t = unw_decode_uleb128 (&dp); + t = unw_decode_uleb128 (&dp, end); switch (r) { case 1: @@ -936,28 +992,40 @@ unw_decode_p7_p10 (const unsigned char *dp, unsigned int code, void *arg, break; case 0x1: + if ((end - dp) < 2) + { + printf (_("\t\n")); + return end; + } + byte1 = *dp++; byte2 = *dp++; UNW_DEC_GR_GR ("P9", (byte1 & 0xf), (byte2 & 0x7f), arg); break; case 0xf: /* p10 */ + if ((end - dp) < 2) + { + printf (_("\t\n")); + return end; + } + byte1 = *dp++; byte2 = *dp++; UNW_DEC_ABI ("P10", byte1, byte2, arg); break; case 0x9: - return unw_decode_x1 (dp, code, arg); + return unw_decode_x1 (dp, code, arg, end); case 0xa: - return unw_decode_x2 (dp, code, arg); + return unw_decode_x2 (dp, code, arg, end); case 0xb: - return unw_decode_x3 (dp, code, arg); + return unw_decode_x3 (dp, code, arg, end); case 0xc: - return unw_decode_x4 (dp, code, arg); + return unw_decode_x4 (dp, code, arg, end); default: UNW_DEC_BAD_CODE (code); @@ -984,30 +1052,30 @@ 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, - const unsigned char * end ATTRIBUTE_UNUSED) + const unsigned char * end) { unw_word t; - t = unw_decode_uleb128 (& dp); + t = unw_decode_uleb128 (& dp, end); UNW_DEC_EPILOGUE ("B2", t, (code & 0x1f), arg); return dp; } static const unsigned char * unw_decode_b3_x4 (const unsigned char *dp, unsigned int code, void *arg, - const unsigned char * end ATTRIBUTE_UNUSED) + const unsigned char * end) { unw_word t, ecount, label; if ((code & 0x10) == 0) { - t = unw_decode_uleb128 (&dp); - ecount = unw_decode_uleb128 (&dp); + t = unw_decode_uleb128 (&dp, end); + ecount = unw_decode_uleb128 (&dp, end); UNW_DEC_EPILOGUE ("B3", t, ecount, arg); } else if ((code & 0x07) == 0) { - label = unw_decode_uleb128 (&dp); + label = unw_decode_uleb128 (&dp, end); if ((code & 0x08) != 0) UNW_DEC_COPY_STATE ("B4", label, arg); else @@ -1017,13 +1085,13 @@ unw_decode_b3_x4 (const unsigned char *dp, unsigned int code, void *arg, switch (code & 0x7) { case 1: - return unw_decode_x1 (dp, code, arg); + return unw_decode_x1 (dp, code, arg, end); case 2: - return unw_decode_x2 (dp, code, arg); + return unw_decode_x2 (dp, code, arg, end); case 3: - return unw_decode_x3 (dp, code, arg); + return unw_decode_x3 (dp, code, arg, end); case 4: - return unw_decode_x4 (dp, code, arg); + return unw_decode_x4 (dp, code, arg, end); default: UNW_DEC_BAD_CODE (code); break; @@ -1067,6 +1135,12 @@ unw_decode (const unsigned char *dp, int inside_body, unw_decoder decoder; unsigned char code; + if ((end - dp) < 1) + { + printf (_("\t\n")); + return end; + } + code = *dp++; decoder = unw_decode_table[inside_body][code >> 5]; return (*decoder) (dp, code, ptr_inside_body, end);