aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Leach <mike.leach@linaro.org>2023-11-06 14:27:30 +0000
committerMike Leach <mike.leach@linaro.org>2023-12-18 14:57:53 +0000
commit6d6074553bd59f436ddd801166ebbf1d4a2af50a (patch)
tree7bf58cd3555cf45194515295e79e29d55f912d42
parent420d9157f8cbd04c070a46187678d0af5c43b40b (diff)
downloadOpenCSD-6d6074553bd59f436ddd801166ebbf1d4a2af50a.tar.gz
opencsd: aarch64 instruction decode - error if opcode in illegal range
AArch64 instructions have an illegal opcode range when top 16 bits or 0x0000 Return error if one of these opcodes is seen. Help debug issues when incorrect memory is provided to the decoder. Signed-off-by: Mike Leach <mike.leach@linaro.org>
-rw-r--r--decoder/include/i_dec/trc_i_decode.h20
-rw-r--r--decoder/include/opencsd/ocsd_if_types.h2
-rw-r--r--decoder/source/i_dec/trc_i_decode.cpp20
-rw-r--r--decoder/source/ocsd_dcd_tree.cpp3
-rw-r--r--decoder/source/ocsd_error.cpp2
5 files changed, 43 insertions, 4 deletions
diff --git a/decoder/include/i_dec/trc_i_decode.h b/decoder/include/i_dec/trc_i_decode.h
index d519a3a..1f6d2b6 100644
--- a/decoder/include/i_dec/trc_i_decode.h
+++ b/decoder/include/i_dec/trc_i_decode.h
@@ -37,20 +37,34 @@
#include "interfaces/trc_instr_decode_i.h"
#include "opencsd/ocsd_if_types.h"
-class TrcIDecode : public IInstrDecode
+/** Throw error if AA64 opcode top 2 bytes == 0x0000. This range is invalid in AA64 */
+#define OCSD_ENV_ERR_ON_AA64_BAD_OPCODE "OPENCSD_ERR_ON_AA64_BAD_OPCODE"
+
+class TrcIDecode : public IInstrDecode
{
public:
- TrcIDecode() {};
+ TrcIDecode();
virtual ~TrcIDecode() {};
- virtual ocsd_err_t DecodeInstruction(ocsd_instr_info *instr_info);
+ virtual ocsd_err_t DecodeInstruction(ocsd_instr_info* instr_info);
+
+ /* control AA64 checking for invalid opcode */
+ void setAA64_errOnBadOpcode(bool bSet);
+ void envSetAA64_errOnBadOpcode();
private:
ocsd_err_t DecodeA32(ocsd_instr_info *instr_info, struct decode_info *info);
ocsd_err_t DecodeA64(ocsd_instr_info *instr_info, struct decode_info *info);
ocsd_err_t DecodeT32(ocsd_instr_info *instr_info, struct decode_info *info);
+
+ bool aa64_err_bad_opcode; //< error if aa64 opcode is in invalid range (top 2 bytes = 0x0000).
};
+inline void TrcIDecode::setAA64_errOnBadOpcode(bool bSet)
+{
+ aa64_err_bad_opcode = bSet;
+}
+
#endif // ARM_TRC_I_DECODE_H_INCLUDED
/* End of File trc_i_decode.h */
diff --git a/decoder/include/opencsd/ocsd_if_types.h b/decoder/include/opencsd/ocsd_if_types.h
index 7e8b354..1af74c8 100644
--- a/decoder/include/opencsd/ocsd_if_types.h
+++ b/decoder/include/opencsd/ocsd_if_types.h
@@ -132,6 +132,8 @@ typedef enum _ocsd_err_t {
OCSD_ERR_DCDREG_TOOMANY, /**< 42 attempted to register too many custom decoders */
/* decoder config */
OCSD_ERR_DCD_INTERFACE_UNUSED, /**< 43 Attempt to connect or use and interface not supported by this decoder. */
+ /* additional errors */
+ OCSD_ERR_INVALID_OPCODE, /**< 44 Opcode found while decoding program memory is illegal */
/* end marker*/
OCSD_ERR_LAST
} ocsd_err_t;
diff --git a/decoder/source/i_dec/trc_i_decode.cpp b/decoder/source/i_dec/trc_i_decode.cpp
index 0e05895..11b70a3 100644
--- a/decoder/source/i_dec/trc_i_decode.cpp
+++ b/decoder/source/i_dec/trc_i_decode.cpp
@@ -36,6 +36,22 @@
#include "i_dec/trc_i_decode.h"
#include "i_dec/trc_idec_arminst.h"
+#include <cstdlib>
+
+TrcIDecode::TrcIDecode() :
+ aa64_err_bad_opcode(false)
+{
+}
+
+void TrcIDecode::envSetAA64_errOnBadOpcode()
+{
+ char* env_var = NULL;
+
+ if ((env_var = getenv(OCSD_ENV_ERR_ON_AA64_BAD_OPCODE)) != NULL)
+ setAA64_errOnBadOpcode(true);
+}
+
+
ocsd_err_t TrcIDecode::DecodeInstruction(ocsd_instr_info *instr_info)
{
ocsd_err_t err = OCSD_OK;
@@ -133,6 +149,10 @@ ocsd_err_t TrcIDecode::DecodeA64(ocsd_instr_info *instr_info, struct decode_info
instr_info->next_isa = instr_info->isa; // assume same ISA
instr_info->is_link = 0;
+ // check for invalid opcode - top 16 bits cannot be 0x0000.
+ if (aa64_err_bad_opcode && !(instr_info->opcode & 0xFFFF0000))
+ return OCSD_ERR_INVALID_OPCODE;
+
if(inst_A64_is_indirect_branch_link(instr_info->opcode, &instr_info->is_link, info))
{
instr_info->type = OCSD_INSTR_BR_INDIRECT;
diff --git a/decoder/source/ocsd_dcd_tree.cpp b/decoder/source/ocsd_dcd_tree.cpp
index 49ceb92..2d3a683 100644
--- a/decoder/source/ocsd_dcd_tree.cpp
+++ b/decoder/source/ocsd_dcd_tree.cpp
@@ -51,13 +51,14 @@ DecodeTree *DecodeTree::CreateDecodeTree(const ocsd_dcd_tree_src_t src_type, uin
if(dcd_tree->initialise(src_type, formatterCfgFlags))
{
s_trace_dcd_trees.push_back(dcd_tree);
+ s_instruction_decoder.envSetAA64_errOnBadOpcode();
}
else
{
delete dcd_tree;
dcd_tree = 0;
}
- }
+ }
return dcd_tree;
}
diff --git a/decoder/source/ocsd_error.cpp b/decoder/source/ocsd_error.cpp
index ee01064..952f946 100644
--- a/decoder/source/ocsd_error.cpp
+++ b/decoder/source/ocsd_error.cpp
@@ -93,6 +93,8 @@ static const char *s_errorCodeDescs[][2] = {
{"OCSD_ERR_DCDREG_TYPE_UNKNOWN","Attempted to find a decoder with a type that is not known in the library."},
/* decoder config */
{"OCSD_ERR_DCD_INTERFACE_UNUSED","Attempt to connect or use and interface not supported by this decoder."},
+ /* additional errors */
+ {"OCSD_ERR_INVALID_OPCODE","Illegal Opode found while decoding program memory."},
/* end marker*/
{"OCSD_ERR_LAST", "No error - error code end marker"}
};