PR 25281
* sh-dis.c (print_insn_ddt): Properly check validity of MOVX_NOPY
and MOVY_NOPX insns. For invalid cases include 0xf000 in the word
printed. Print .word in more cases.
This patch prevents print_insn_mode recursing into another index mode
byte, which if repeated enough times will overflow private.the_buffer
and scribble over other memory.
* vax-dis.c (print_insn_mode): Stop index mode recursion.
fadd, fmul, and fdiv are now, by ISO/IEC TS 18661-3:2015, defined to
refer to functions from the runtime subsystem.
PR 25277
* microblaze-opcm.h (enum microblaze_instr): Prefix fadd, fmul and
fdiv with "mbi_".
* microblaze-opc.h (opcodes): Adjust to suit.
The arc fix in create_map avoiding signed overflow by casting an
unsigned char to unsigned int before shifting, shows one of the
dangers of blinding doing that. The problem in this case was that the
variable storing the value, newAuxRegister->address, was a long.
Using the unsigned cast meant that the 32-bit value was zero extended
when long is 64 bits. Previously we had a sign extension. Net result
was that comparisons in arcExtMap_auxRegName didn't match. Of course,
I could have cast the 32-bit unsigned value back to signed before
storing in a long, but it's neater to just use an unsigned int for the
address.
opcodes/
* alpha-opc.c (OP): Avoid signed overflow.
* arm-dis.c (print_insn): Likewise.
* mcore-dis.c (print_insn_mcore): Likewise.
* pj-dis.c (get_int): Likewise.
* ppc-opc.c (EBD15, EBD15BI): Likewise.
* score7-dis.c (s7_print_insn): Likewise.
* tic30-dis.c (print_insn_tic30): Likewise.
* v850-opc.c (insert_SELID): Likewise.
* vax-dis.c (print_insn_vax): Likewise.
* arc-ext.c (create_map): Likewise.
(struct ExtAuxRegister): Make "address" field unsigned int.
(arcExtMap_auxRegName): Pass unsigned address.
(dump_ARC_extmap): Adjust.
* arc-ext.h (arcExtMap_auxRegName): Update prototype.
I'm flying blind here, not having an s+core s3 insn set reference,
but this seems reasonably obvious from what is done by the assembler.
s3_do16_rpop does some mixing of imm and reg values to place in the
rpop reg field, but I'm not going to try to fix the disassembly
there.
* score-dis.c (print_insn_score16): Move rpush/rpop imm field
value adjustment so that it doesn't affect reg field too.
The ubsan complaint is fixed by the SBM change, with similar possible
complaints fixed by the EXTRACT change. The rest is just cleanup.
include/
* opcode/crx.h (inst <match>): Make unsigned int.
opcodes/
* crx-dis.c (EXTRACT, SBM): Avoid signed overflow.
(get_number_of_operands, getargtype, getbits, getregname),
(getcopregname, getprocregname, gettrapstring, getcinvstring),
(getregliststring, get_word_at_PC, get_words_at_PC, build_mask),
(powerof2, match_opcode, make_instruction, print_arguments),
(print_arg): Delete forward declarations, moving static to..
(getregname, getcopregname, getregliststring): ..these definitions.
(build_mask): Return unsigned int mask.
(match_opcode): Use unsigned int vars.
Note that using 1u in N32_BIT makes all of N32_BIT, __MASK, __MF, __GF
and __SEXT evaluate as unsigned int (the latter three when when their
v arg is int or smaller). This would be a problem if assigning the
result to a bfd_vma, long, or other type wider than an int since the
__SEXT result would be zero extended to the wider type. Fortunately
nds32 target code doesn't use wider types unnecessarily.
include/
* opcode/nds32.h (N32_BIT): Define using 1u.
(__SEXT): Use __MASK and N32_BIT.
(N32_IMMS): Remove duplicate mask.
opcodes/
* nds32-dis.c (print_insn16, print_insn32): Remove forward decls.
(struct objdump_disasm_info): Delete.
(nds32_parse_audio_ext, nds32_parse_opcode): Cast result of
N32_IMMS to unsigned before shifting left.
Commit 8c9b417187 didn't remove a glaring left shift of a number
that had just been sign extended.
* moxie-dis.c (INST2OFFSET): Don't left shift a signed value.
(print_insn_moxie): Remove unnecessary cast.
This is
*cst = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3];
data is unsigned char which promotes to int.
* h8300-dis.c (extract_immediate): Avoid signed overflow.
(bfd_h8_disassemble): Likewise.
In the following buf is an unsigned char array, so elements are
promoted to int before arithmetic operations.
if (dis_info.info->endian == BFD_ENDIAN_BIG)
while (n--)
val |= buf[n] << (n*8);
else
for (i = 0; i < n; i++)
val |= buf[i] << (i*8);
* csky-dis.c (csky_chars_to_number): Rewrite. Avoid signed
overflow when collecting bytes of a number.
This was the following in print_with_operands
case 4:
number
= buffer[2] + buffer[3] * 256 + buffer[4] * 65536
+ buffer[5] * 0x1000000;
and buffer[5] * 0x1000000 can indeed overflow. So to fix this we need
to use unsigned arithmetic where overflow semantics are specified.
But number is a long, and the expression is int which will be sign
extended to long. If we make the expression unsigned it will be zero
extended. So make number an int32_t and rearrange a little for some
of the places that need fixing.
* cris-dis.c (print_with_operands): Avoid signed integer
overflow when collecting bytes of a 32-bit integer.
This was:
unsigned long mask = SBM (instruction->match_bits);
with
#define SBM(offs) ((((1 << (32 - offs)) -1) << (offs)))
Well, there are a couple of problems. Firstly, the expression uses
int values (1 rather than 1u or 1ul) resulting in the ubsan error, and
secondly, a zero offs will result in a 32-bit shift which is undefined
if ints are only 32 bits.
* cr16-dis.c (EXTRACT, SBM): Rewrite.
(cr16_match_opcode): Delete duplicate bcond test.
This was the following in fmtconst_val, x is unsigned int.
x = SIGNEXTEND (x, constant_formats[cf].nbits);
Problem is, the SIGNEXTEND macro assumed its arg was a long and sign
extended by shifting left then shifting right, and didn't cast the
arg. So don't do the silly shift thing. It's not guaranteed to work
anyway according to the C standard. ">>" might do a logical shift
even if its args are signed.
* bfin-dis.c (HOST_LONG_WORD_SIZE, XFIELD): Delete.
(SIGNBIT): New.
(MASKBITS, SIGNEXTEND): Rewrite.
(fmtconst): Don't use ? expression now that SIGNEXTEND uses
unsigned arithmetic, instead assign result of SIGNEXTEND back
to x.
(fmtconst_val): Use 1u in shift expression.
When operand->bits is 32, the following results in UB.
value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
* arc-dis.c (find_format_from_table): Use ull constant when
shifting by up to 32.
Assembling this to an object and trying to disassemble results in
objdump -d looping forever.
.inst 0x45205120
PR 25270
* aarch64-dis.c (aarch64_decode_variant_using_iclass): Return
false when field is zero for sve_size_tsz_bhs.
Two places in epiphany_cgen_extract_operand, "value" is a long.
value = ((((value) << (1))) + (pc));
cpu/
* epiphany.cpu (f-simm8, f-simm24): Use multiply rather than
shift left to avoid UB on left shift of negative values.
opcodes/
* epiphany-ibld.c: Regenerate.
ppc-dis.c used a global struct whenever malloc failed to provide the
eight bytes of memory necessary for struct dis_private. Which is
quite ridiculous. If that malloc failed there is zero chance some
other malloc won't fail too.
* ppc-dis.c (private): Delete variable.
(get_powerpc_dialect): Don't segfault on NULL info->private_data.
(powerpc_init_dialect): Don't use global private.
This, at the assembler level, is just a "brace" feature covering both
AES and SHA2. Hence there's no need for it to have a separate feature
flag, freeing up a bit for future re-use. Along these lines there are
also a number of dead definitions/variables in the opcode table file.