aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Leach <mike.leach@linaro.org>2023-11-06 14:44:49 +0000
committerMike Leach <mike.leach@linaro.org>2023-12-18 14:57:54 +0000
commit47c98f1cbe4a119f9bf67177e2c980e5c8915578 (patch)
treed6d910326afca75f7aaf95528923c0e89bb5d8cd
parent3401fdceb29d21fe63de0c6bfde7bfbea43d8e01 (diff)
opencsd: etmv4: Optional limit on number of instructions in range.
Adds an optional limit on the number of instructions that will be allow in a single instruciton range. Limit not used unless an environment variable "OPENCSD_INSTR_RANGE_LIMIT" is set. Use to debug possible decoder runaway if incorrect program image supplied to decoder is suspected. Signed-off-by: Mike Leach <mike.leach@linaro.org>
-rw-r--r--decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h8
-rw-r--r--decoder/include/opencsd/ocsd_if_types.h1
-rw-r--r--decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp23
-rw-r--r--decoder/source/ocsd_error.cpp2
4 files changed, 34 insertions, 0 deletions
diff --git a/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h b/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h
index 7838ece04e57..9b6f5311a883 100644
--- a/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h
+++ b/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h
@@ -43,6 +43,8 @@
#include "common/ocsd_gen_elem_stack.h"
#include "opencsd/etmv4/trc_etmv4_stack_elem.h"
+#define OCSD_ENV_INSTR_RANGE_LIMIT "OPENCSD_INSTR_RANGE_LIMIT"
+
class TrcStackElem;
class TrcStackElemParam;
class TrcStackElemCtxt;
@@ -130,6 +132,12 @@ private:
WP_NACC
} WP_res_t;
+ /* Optional run limit for decoded instruction range.
+ * Throw error if limit exceeded. Set by env var - use for debugging decode runs
+ * which may be running away due to bad data
+ */
+ int m_num_instr_range_limit;
+
typedef struct {
ocsd_vaddr_t st_addr;
ocsd_vaddr_t en_addr;
diff --git a/decoder/include/opencsd/ocsd_if_types.h b/decoder/include/opencsd/ocsd_if_types.h
index 1af74c810fbe..cd96018cbb43 100644
--- a/decoder/include/opencsd/ocsd_if_types.h
+++ b/decoder/include/opencsd/ocsd_if_types.h
@@ -134,6 +134,7 @@ typedef enum _ocsd_err_t {
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 */
+ OCSD_ERR_I_RANGE_LIMIT_OVERRUN, /**< 45 An optional limit on consecutive instructions in range during decode has been exceeded. */
/* end marker*/
OCSD_ERR_LAST
} ocsd_err_t;
diff --git a/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp b/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp
index d82bd5538713..b96301252c4e 100644
--- a/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp
+++ b/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp
@@ -241,6 +241,20 @@ void TrcPktDecodeEtmV4I::initDecoder()
m_CSID = 0;
m_IASize64 = false;
+ // set debug range limit - look for debugging env var
+ char* env_var;
+ long env_val;
+
+ m_num_instr_range_limit = 0;
+ if ((env_var = getenv(OCSD_ENV_INSTR_RANGE_LIMIT)) != NULL)
+ {
+ env_val = strtol(env_var, NULL, 0);
+ /* if valid number set limit */
+ if (env_val > 0)
+ m_num_instr_range_limit = env_val;
+
+ }
+
// elements associated with data trace
#ifdef DATA_TRACE_SUPPORTED
m_p0_key_max = 0;
@@ -1899,6 +1913,15 @@ ocsd_err_t TrcPktDecodeEtmV4I::traceInstrToWP(instr_range_t &range, WP_res_t &WP
// not enough memory accessible.
WPRes = WP_NACC;
}
+
+ if (m_num_instr_range_limit)
+ {
+ if (range.num_instr > m_num_instr_range_limit)
+ {
+ err = OCSD_ERR_I_RANGE_LIMIT_OVERRUN;
+ LogError(ocsdError(OCSD_ERR_SEV_ERROR, err, "Decode Instruction Range Limit Overrun"));
+ }
+ }
}
// update the range decoded address in the output packet.
range.en_addr = m_instr_info.instr_addr;
diff --git a/decoder/source/ocsd_error.cpp b/decoder/source/ocsd_error.cpp
index 952f94684cfe..3aee3724016e 100644
--- a/decoder/source/ocsd_error.cpp
+++ b/decoder/source/ocsd_error.cpp
@@ -91,10 +91,12 @@ static const char *s_errorCodeDescs[][2] = {
{"OCSD_ERR_DCDREG_NAME_REPEAT","Attempted to register a decoder with the same name as another one."},
{"OCSD_ERR_DCDREG_NAME_UNKNOWN","Attempted to find a decoder with a name that is not known in the library."},
{"OCSD_ERR_DCDREG_TYPE_UNKNOWN","Attempted to find a decoder with a type that is not known in the library."},
+ {"OCSD_ERR_DCDREG_TOOMANY","Attempted to register too many custom decoders"},
/* 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."},
+ {"OCSD_ERR_I_RANGE_LIMIT_OVERRUN","An optional limit on consecutive instructions in range during decode has been exceeded."},
/* end marker*/
{"OCSD_ERR_LAST", "No error - error code end marker"}
};