summaryrefslogtreecommitdiffstats
path: root/disas
diff options
context:
space:
mode:
authorMilica Lazarevic2022-09-12 14:26:32 +0200
committerPhilippe Mathieu-Daudé2022-10-31 11:32:07 +0100
commit39399c381d3bfc8f651f6d64f9f1f37d9763a8e3 (patch)
treef304025b5eab751cc4817643eefeadfcab3a5bdd /disas
parentdisas/nanomips: Expand Dis_info struct (diff)
downloadqemu-39399c381d3bfc8f651f6d64f9f1f37d9763a8e3.tar.gz
qemu-39399c381d3bfc8f651f6d64f9f1f37d9763a8e3.tar.xz
qemu-39399c381d3bfc8f651f6d64f9f1f37d9763a8e3.zip
disas/nanomips: Replace exception handling
Since there's no support for exception handling in C, the try-catch blocks have been deleted, and throw clauses are replaced. When a runtime error happens, we're printing out the error message. Disassembling of the current instruction interrupts. This behavior is achieved by adding sigsetjmp() to discard further disassembling after the error message prints and by adding the siglongjmp() function to imitate throwing an error. The goal was to maintain the same output as it was. Signed-off-by: Milica Lazarevic <milica.lazarevic@syrmia.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20220912122635.74032-22-milica.lazarevic@syrmia.com> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Diffstat (limited to 'disas')
-rw-r--r--disas/nanomips.cpp100
1 files changed, 45 insertions, 55 deletions
diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
index 73329462ee..1832c2d3cf 100644
--- a/disas/nanomips.cpp
+++ b/disas/nanomips.cpp
@@ -31,7 +31,6 @@
#include "disas/dis-asm.h"
#include <string.h>
-#include <stdexcept>
#include <stdio.h>
#include <stdarg.h>
@@ -133,10 +132,9 @@ static uint64 renumber_registers(uint64 index, uint64 *register_list,
return register_list[index];
}
- throw std::runtime_error(img_format(
- "Invalid register mapping index %" PRIu64
- ", size of list = %zu",
- index, register_list_size));
+ info->fprintf_func(info->stream, "Invalid register mapping index %" PRIu64
+ ", size of list = %zu", index, register_list_size);
+ siglongjmp(info->buf, 1);
}
@@ -466,8 +464,9 @@ static const char *GPR(uint64 reg, Dis_info *info)
return gpr_reg[reg];
}
- throw std::runtime_error(img_format("Invalid GPR register index %" PRIu64,
- reg));
+ info->fprintf_func(info->stream, "Invalid GPR register index %" PRIu64,
+ reg);
+ siglongjmp(info->buf, 1);
}
@@ -503,8 +502,9 @@ static const char *FPR(uint64 reg, Dis_info *info)
return fpr_reg[reg];
}
- throw std::runtime_error(img_format("Invalid FPR register index %" PRIu64,
- reg));
+ info->fprintf_func(info->stream, "Invalid FPR register index %" PRIu64,
+ reg);
+ siglongjmp(info->buf, 1);
}
@@ -518,8 +518,9 @@ static const char *AC(uint64 reg, Dis_info *info)
return ac_reg[reg];
}
- throw std::runtime_error(img_format("Invalid AC register index %" PRIu64,
- reg));
+ info->fprintf_func(info->stream, "Invalid AC register index %" PRIu64,
+ reg);
+ siglongjmp(info->buf, 1);
}
@@ -562,55 +563,38 @@ static int Disassemble(const uint16 *data, char **dis,
TABLE_ENTRY_TYPE & type, const Pool *table,
int table_size, Dis_info *info)
{
- try
- {
- for (int i = 0; i < table_size; i++) {
- uint64 op_code = extract_op_code_value(data,
- table[i].instructions_size);
- if ((op_code & table[i].mask) == table[i].value) {
- /* possible match */
- conditional_function cond = table[i].condition;
- if ((cond == NULL) || cond(op_code)) {
- try
- {
- if (table[i].type == pool) {
- return Disassemble(data, dis, type,
- table[i].next_table,
- table[i].next_table_size,
- info);
- } else if ((table[i].type == instruction) ||
- (table[i].type == call_instruction) ||
- (table[i].type == branch_instruction) ||
- (table[i].type == return_instruction)) {
- disassembly_function dis_fn = table[i].disassembly;
- if (dis_fn == 0) {
- *dis = g_strdup(
- "disassembler failure - bad table entry");
- return -6;
- }
- type = table[i].type;
- *dis = dis_fn(op_code, info);
- return table[i].instructions_size;
- } else {
- *dis = g_strdup("reserved instruction");
- return -2;
- }
- }
- catch (std::runtime_error & e)
- {
- *dis = g_strdup(e.what());
- return -3; /* runtime error */
+ for (int i = 0; i < table_size; i++) {
+ uint64 op_code = extract_op_code_value(data,
+ table[i].instructions_size);
+ if ((op_code & table[i].mask) == table[i].value) {
+ /* possible match */
+ conditional_function cond = table[i].condition;
+ if ((cond == NULL) || cond(op_code)) {
+ if (table[i].type == pool) {
+ return Disassemble(data, dis, type,
+ table[i].next_table,
+ table[i].next_table_size,
+ info);
+ } else if ((table[i].type == instruction) ||
+ (table[i].type == call_instruction) ||
+ (table[i].type == branch_instruction) ||
+ (table[i].type == return_instruction)) {
+ disassembly_function dis_fn = table[i].disassembly;
+ if (dis_fn == 0) {
+ *dis = g_strdup(
+ "disassembler failure - bad table entry");
+ return -6;
}
+ type = table[i].type;
+ *dis = dis_fn(op_code, info);
+ return table[i].instructions_size;
+ } else {
+ *dis = g_strdup("reserved instruction");
+ return -2;
}
}
}
}
- catch (std::exception & e)
- {
- *dis = g_strdup(e.what());
- return -4; /* runtime error */
- }
-
*dis = g_strdup("failed to disassemble");
return -1; /* failed to disassemble */
}
@@ -22003,6 +21987,12 @@ int print_insn_nanomips(bfd_vma memaddr, struct disassemble_info *info)
(*info->fprintf_func)(info->stream, " ");
}
+ /* Handle runtime errors. */
+ if (sigsetjmp(disassm_info.buf, 0) != 0) {
+ info->insn_type = dis_noninsn;
+ return insn3 ? 6 : insn2 ? 4 : 2;
+ }
+
int length = nanomips_dis(&buf, &disassm_info, insn1, insn2, insn3);
/* FIXME: Should probably use a hash table on the major opcode here. */