From 7731a90a695688c8757ed6ee863b5c923f1f1607 Mon Sep 17 00:00:00 2001 From: Florian Krohm Date: Sun, 16 Dec 2012 22:49:05 +0000 Subject: [PATCH] Fix an assert in s390 disassembly. Eliminate a few magic array width constants and use S390_MAX_MNEMONIC_LEN instead. New function "mnemonic" to construct a mnemonic string padded with blanks for alignment. git-svn-id: svn://svn.valgrind.org/vex/trunk@2592 --- VEX/priv/guest_s390_toIR.c | 12 +++++------ VEX/priv/s390_disasm.c | 42 ++++++++++++++++++++++++++++---------- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/VEX/priv/guest_s390_toIR.c b/VEX/priv/guest_s390_toIR.c index 81f827e69c..f4907926b8 100644 --- a/VEX/priv/guest_s390_toIR.c +++ b/VEX/priv/guest_s390_toIR.c @@ -9509,32 +9509,32 @@ s390_irgen_EX(UChar r1, IRTemp addr2) case 0xd200000000000000ULL: /* special case MVC */ s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64); - return "mvc via ex"; + return "ex@mvc"; case 0xd500000000000000ULL: /* special case CLC */ s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64); - return "clc via ex"; + return "ex@clc"; case 0xd700000000000000ULL: /* special case XC */ s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32); - return "xc via ex"; + return "ex@xc"; case 0xd600000000000000ULL: /* special case OC */ s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32); - return "oc via ex"; + return "ex@oc"; case 0xd400000000000000ULL: /* special case NC */ s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32); - return "nc via ex"; + return "ex@nc"; case 0xdc00000000000000ULL: /* special case TR */ s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64); - return "tr via ex"; + return "ex@tr"; default: { diff --git a/VEX/priv/s390_disasm.c b/VEX/priv/s390_disasm.c index 66cdbd3723..4e37a8d6fa 100644 --- a/VEX/priv/s390_disasm.c +++ b/VEX/priv/s390_disasm.c @@ -36,8 +36,23 @@ #include "main_globals.h" // vex_traceflags #include "s390_disasm.h" -/* The format that is used to write out a mnemonic. */ -static const HChar s390_mnm_fmt[] = "%-8s"; +/* The length of the longest mnemonic: locgrnhe */ +#define S390_MAX_MNEMONIC_LEN 8 + + +/* Return the mnemonic padded with blanks to its right */ +static const HChar * +mnemonic(const HChar *mnm) +{ + vex_printf("MNEMONIC = |%s|\n", mnm); + vassert(vex_strlen(mnm) <= S390_MAX_MNEMONIC_LEN); + + static HChar buf[S390_MAX_MNEMONIC_LEN + 1]; + + vex_sprintf(buf, "%-*s", S390_MAX_MNEMONIC_LEN, mnm); + + return buf; +} /* Return the name of a general purpose register for dis-assembly purposes. */ @@ -100,12 +115,15 @@ cab_operand(const HChar *base, UInt mask) HChar *to; const HChar *from; - static HChar buf[10]; /* Maximum is 6 + 2 */ + static HChar buf[S390_MAX_MNEMONIC_LEN + 1]; - static const HChar *suffix[] = { + static const HChar suffix[8][3] = { "", "h", "l", "ne", "e", "nl", "nh", "" }; + /* Guard against buffer overflow */ + vassert(vex_strlen(base) + sizeof suffix[0] <= sizeof buf); + /* strcpy(buf, from); */ for (from = base, to = buf; *from; ++from, ++to) { *to = *from; @@ -119,6 +137,7 @@ cab_operand(const HChar *base, UInt mask) return buf; } + /* Common function used to construct a mnemonic based on a condition code mask. */ static const HChar * @@ -127,7 +146,7 @@ construct_mnemonic(const HChar *prefix, const HChar *suffix, UInt mask) HChar *to; const HChar *from; - static HChar buf[10]; + static HChar buf[S390_MAX_MNEMONIC_LEN + 1]; static HChar mask_id[16][4] = { "", /* 0 -> unused */ @@ -137,7 +156,8 @@ construct_mnemonic(const HChar *prefix, const HChar *suffix, UInt mask) }; /* Guard against buffer overflow */ - vassert(vex_strlen(prefix) + vex_strlen(suffix) + sizeof mask_id[0] <= sizeof buf); + vassert(vex_strlen(prefix) + vex_strlen(suffix) + + sizeof mask_id[0] <= sizeof buf); /* strcpy(buf, prefix); */ for (from = prefix, to = buf; *from; ++from, ++to) { @@ -304,7 +324,7 @@ s390_disasm(UInt command, ...) /* argument */ switch (argkind) { case S390_ARG_MNM: - p += vex_sprintf(p, s390_mnm_fmt, va_arg(args, HChar *)); + p += vex_sprintf(p, "%s", mnemonic(va_arg(args, HChar *))); separator = ' '; continue; @@ -320,7 +340,7 @@ s390_disasm(UInt command, ...) case S390_XMNM_BCR: mask = va_arg(args, UInt); mnm = kind == S390_XMNM_BCR ? bcr_operand(mask) : bc_operand(mask); - p += vex_sprintf(p, s390_mnm_fmt, mnm); + p += vex_sprintf(p, "%s", mnemonic(mnm)); /* mask == 0 is a NOP and has no argument */ if (mask == 0) goto done; break; @@ -329,7 +349,7 @@ s390_disasm(UInt command, ...) case S390_XMNM_BRCL: mask = va_arg(args, UInt); mnm = kind == S390_XMNM_BRC ? brc_operand(mask) : brcl_operand(mask); - p += vex_sprintf(p, s390_mnm_fmt, mnm); + p += vex_sprintf(p, "%s", mnemonic(mnm)); /* mask == 0 has no special mnemonic */ if (mask == 0) { @@ -341,7 +361,7 @@ s390_disasm(UInt command, ...) case S390_XMNM_CAB: mnm = va_arg(args, HChar *); mask = va_arg(args, UInt); - p += vex_sprintf(p, s390_mnm_fmt, cab_operand(mnm, mask)); + p += vex_sprintf(p, "%s", mnemonic(cab_operand(mnm, mask))); break; case S390_XMNM_LOCR: @@ -352,7 +372,7 @@ s390_disasm(UInt command, ...) case S390_XMNM_STOCG: mask = va_arg(args, UInt); mnm = cls_operand(kind, mask); - p += vex_sprintf(p, s390_mnm_fmt, mnm); + p += vex_sprintf(p, "%s", mnemonic(mnm)); /* There are no special opcodes when mask == 0 or 15. In that case the integer mask is appended as the final operand */ if (mask == 0 || mask == 15) mask_suffix = mask; -- 2.47.2