diff options
author | Mike Leach <mike.leach@linaro.org> | 2023-11-06 14:44:49 +0000 |
---|---|---|
committer | Mike Leach <mike.leach@linaro.org> | 2023-12-18 14:57:54 +0000 |
commit | 47c98f1cbe4a119f9bf67177e2c980e5c8915578 (patch) | |
tree | d6d910326afca75f7aaf95528923c0e89bb5d8cd | |
parent | 3401fdceb29d21fe63de0c6bfde7bfbea43d8e01 (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.h | 8 | ||||
-rw-r--r-- | decoder/include/opencsd/ocsd_if_types.h | 1 | ||||
-rw-r--r-- | decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp | 23 | ||||
-rw-r--r-- | decoder/source/ocsd_error.cpp | 2 |
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"} }; |