target/riscv: fix undefined operation

Scan-build reports:
	Logic error: Result of operation is garbage or undefined
	riscv.c:1614 The result of the left shift is undefined due
		to shifting by '4294967281', which is greater or
		equal to the width of type 'target_addr_t'

This is a false warning due to clang that considers the impossible
case of 32 bits hart (xlen = 32) in SATP_MODE_SV48 mode
(info->va_bits = 48).
Under such case:
	riscv.c:1614 ... ((target_addr_t)1 << (xlen - (info->va_bits - 1))) ...
the shift amount wraps around the unsigned type and assumes the
value 4294967281 (0xfffffff1).

Use assert() to prevent clang from complaining.

Change-Id: I08fdd2a806c350d061641e28cf15a51b397db099
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/7209
Reviewed-by: Tim Newsome <tim@sifive.com>
Reviewed-by: Jan Matyas <matyas@codasip.com>
Tested-by: jenkins
This commit is contained in:
Antonio Borneo 2022-09-19 15:28:15 +02:00
parent aff48a6a31
commit fd2a44ab55
1 changed files with 1 additions and 0 deletions

View File

@ -1607,6 +1607,7 @@ static int riscv_address_translate(struct target *target,
LOG_DEBUG("virtual=0x%" TARGET_PRIxADDR "; mode=%s", virtual, info->name); LOG_DEBUG("virtual=0x%" TARGET_PRIxADDR "; mode=%s", virtual, info->name);
/* verify bits xlen-1:va_bits-1 are all equal */ /* verify bits xlen-1:va_bits-1 are all equal */
assert(xlen >= info->va_bits);
target_addr_t mask = ((target_addr_t)1 << (xlen - (info->va_bits - 1))) - 1; target_addr_t mask = ((target_addr_t)1 << (xlen - (info->va_bits - 1))) - 1;
target_addr_t masked_msbs = (virtual >> (info->va_bits - 1)) & mask; target_addr_t masked_msbs = (virtual >> (info->va_bits - 1)) & mask;
if (masked_msbs != 0 && masked_msbs != mask) { if (masked_msbs != 0 && masked_msbs != mask) {