disas/cris: Pass buffer size to format_dec() to avoid overflow warning
Propagate the buffer size to format_dec() and use snprintf(). This should silence this UBSan -Wformat-overflow warning: In file included from /usr/include/stdio.h:906, from include/qemu/osdep.h:114, from ../disas/cris.c:21: In function 'sprintf', inlined from 'format_dec' at ../disas/cris.c:1737:3, inlined from 'print_with_operands' at ../disas/cris.c:2477:12, inlined from 'print_insn_cris_generic.constprop' at ../disas/cris.c:2690:8: /usr/include/bits/stdio2.h:30:10: warning: null destination pointer [-Wformat-overflow=] 30 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 31 | __glibc_objsize (__s), __fmt, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 32 | __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~ Reported-by: Akihiko Odaki <akihiko.odaki@daynix.com> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-ID: <20231120132222.82138-1-philmd@linaro.org> [Rewritten to fix logic and avoid repeated expression. - Paolo] Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
e4b9d1999c
commit
2037a73997
26
disas/cris.c
26
disas/cris.c
@ -1731,10 +1731,10 @@ format_hex (unsigned long number,
|
|||||||
unsigned (== 0). */
|
unsigned (== 0). */
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
format_dec (long number, char *outbuffer, int signedp)
|
format_dec (long number, char *outbuffer, size_t outsize, int signedp)
|
||||||
{
|
{
|
||||||
last_immediate = number;
|
last_immediate = number;
|
||||||
sprintf (outbuffer, signedp ? "%ld" : "%lu", number);
|
snprintf (outbuffer, outsize, signedp ? "%ld" : "%lu", number);
|
||||||
|
|
||||||
return outbuffer + strlen (outbuffer);
|
return outbuffer + strlen (outbuffer);
|
||||||
}
|
}
|
||||||
@ -1876,6 +1876,12 @@ print_flags (struct cris_disasm_data *disdata, unsigned int insn, char *cp)
|
|||||||
return cp;
|
return cp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define FORMAT_DEC(number, tp, signedp) \
|
||||||
|
format_dec (number, tp, ({ \
|
||||||
|
assert(tp >= temp && tp <= temp + sizeof(temp)); \
|
||||||
|
temp + sizeof(temp) - tp; \
|
||||||
|
}), signedp)
|
||||||
|
|
||||||
/* Print out an insn with its operands, and update the info->insn_type
|
/* Print out an insn with its operands, and update the info->insn_type
|
||||||
fields. The prefix_opcodep and the rest hold a prefix insn that is
|
fields. The prefix_opcodep and the rest hold a prefix insn that is
|
||||||
supposed to be output as an address mode. */
|
supposed to be output as an address mode. */
|
||||||
@ -2105,7 +2111,7 @@ print_with_operands (const struct cris_opcode *opcodep,
|
|||||||
if ((*cs == 'z' && (insn & 0x20))
|
if ((*cs == 'z' && (insn & 0x20))
|
||||||
|| (opcodep->match == BDAP_QUICK_OPCODE
|
|| (opcodep->match == BDAP_QUICK_OPCODE
|
||||||
&& (nbytes <= 2 || buffer[1 + nbytes] == 0)))
|
&& (nbytes <= 2 || buffer[1 + nbytes] == 0)))
|
||||||
tp = format_dec (number, tp, signedp);
|
tp = FORMAT_DEC (number, tp, signedp);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned int highbyte = (number >> 24) & 0xff;
|
unsigned int highbyte = (number >> 24) & 0xff;
|
||||||
@ -2241,7 +2247,7 @@ print_with_operands (const struct cris_opcode *opcodep,
|
|||||||
with_reg_prefix);
|
with_reg_prefix);
|
||||||
if (number >= 0)
|
if (number >= 0)
|
||||||
*tp++ = '+';
|
*tp++ = '+';
|
||||||
tp = format_dec (number, tp, 1);
|
tp = FORMAT_DEC (number, tp, 1);
|
||||||
|
|
||||||
info->flags |= CRIS_DIS_FLAG_MEM_TARGET_IS_REG;
|
info->flags |= CRIS_DIS_FLAG_MEM_TARGET_IS_REG;
|
||||||
info->target = (prefix_insn >> 12) & 15;
|
info->target = (prefix_insn >> 12) & 15;
|
||||||
@ -2340,7 +2346,7 @@ print_with_operands (const struct cris_opcode *opcodep,
|
|||||||
{
|
{
|
||||||
if (number >= 0)
|
if (number >= 0)
|
||||||
*tp++ = '+';
|
*tp++ = '+';
|
||||||
tp = format_dec (number, tp, 1);
|
tp = FORMAT_DEC (number, tp, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2397,7 +2403,7 @@ print_with_operands (const struct cris_opcode *opcodep,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'I':
|
case 'I':
|
||||||
tp = format_dec (insn & 63, tp, 0);
|
tp = FORMAT_DEC (insn & 63, tp, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'b':
|
case 'b':
|
||||||
@ -2426,11 +2432,11 @@ print_with_operands (const struct cris_opcode *opcodep,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'c':
|
case 'c':
|
||||||
tp = format_dec (insn & 31, tp, 0);
|
tp = FORMAT_DEC (insn & 31, tp, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'C':
|
case 'C':
|
||||||
tp = format_dec (insn & 15, tp, 0);
|
tp = FORMAT_DEC (insn & 15, tp, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'o':
|
case 'o':
|
||||||
@ -2463,7 +2469,7 @@ print_with_operands (const struct cris_opcode *opcodep,
|
|||||||
if (number > 127)
|
if (number > 127)
|
||||||
number = number - 256;
|
number = number - 256;
|
||||||
|
|
||||||
tp = format_dec (number, tp, 1);
|
tp = FORMAT_DEC (number, tp, 1);
|
||||||
*tp++ = ',';
|
*tp++ = ',';
|
||||||
tp = format_reg (disdata, (insn >> 12) & 15, tp, with_reg_prefix);
|
tp = format_reg (disdata, (insn >> 12) & 15, tp, with_reg_prefix);
|
||||||
}
|
}
|
||||||
@ -2474,7 +2480,7 @@ print_with_operands (const struct cris_opcode *opcodep,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
tp = format_dec ((insn & 32) ? (insn & 31) | ~31L : insn & 31, tp, 1);
|
tp = FORMAT_DEC ((insn & 32) ? (insn & 31) | ~31L : insn & 31, tp, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'P':
|
case 'P':
|
||||||
|
Loading…
Reference in New Issue
Block a user