aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Leach <mike.leach@linaro.org>2023-11-06 14:34:51 +0000
committerMike Leach <mike.leach@linaro.org>2023-12-18 14:57:53 +0000
commit3401fdceb29d21fe63de0c6bfde7bfbea43d8e01 (patch)
tree7db261462a324350b54439d80486f1807e0cfc5e
parent6d6074553bd59f436ddd801166ebbf1d4a2af50a (diff)
opencsd: etmv4: Handle M class tail chained exceptions
M class exceptions can be tail chained with the address set to a fixed indicator value and not being the preferred return address. Fix this be handling that value and not trying to walk to the address. Signed-off-by: Mike Leach <mike.leach@linaro.org>
-rw-r--r--decoder/include/opencsd/trc_gen_elem_types.h3
-rw-r--r--decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp15
2 files changed, 16 insertions, 2 deletions
diff --git a/decoder/include/opencsd/trc_gen_elem_types.h b/decoder/include/opencsd/trc_gen_elem_types.h
index 99194d118438..0965efcea8e9 100644
--- a/decoder/include/opencsd/trc_gen_elem_types.h
+++ b/decoder/include/opencsd/trc_gen_elem_types.h
@@ -133,7 +133,8 @@ typedef struct _ocsd_generic_trace_elem {
uint32_t extended_data:1; /**< 1 if the packet extended data pointer is valid. Allows packet extensions for custom decoders, or additional data payloads for data trace. */
uint32_t has_ts:1; /**< 1 if the packet has an associated timestamp - e.g. SW/STM trace TS+Payload as a single packet */
uint32_t last_instr_cond:1; /**< 1 if the last instruction was conditional */
- uint32_t excep_ret_addr_br_tgt:1; /**< 1 if exception return address (en_addr) is also the target of a taken branch addr from the previous range. */
+ uint32_t excep_ret_addr_br_tgt:1; /**< 1 if exception return address (en_addr) is also the target of a taken branch addr from the previous range. */
+ uint32_t excep_M_tail_chain:1; /**< 1 if the exception is an M class exception with no pref ret address - tail chained or similar */
};
uint32_t flag_bits;
};
diff --git a/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp b/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp
index 89c45052868c..d82bd5538713 100644
--- a/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp
+++ b/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp
@@ -1389,6 +1389,8 @@ ocsd_err_t TrcPktDecodeEtmV4I::processAtom(const ocsd_atm_val atom)
}
// Exception processor
+#define M_CLASS_TAIL_ADDR 0xFFFFFFFE
+
ocsd_err_t TrcPktDecodeEtmV4I::processException()
{
ocsd_err_t err;
@@ -1401,6 +1403,7 @@ ocsd_err_t TrcPktDecodeEtmV4I::processException()
ocsd_trc_index_t excep_pkt_index;
WP_res_t WPRes = WP_NOT_FOUND;
bool ETE_resetPkt = false;
+ bool bMTailChain = false;
// grab the exception element off the stack
pExceptElem = dynamic_cast<TrcStackElemExcept *>(m_P0_stack.back()); // get the exception element
@@ -1472,8 +1475,12 @@ ocsd_err_t TrcPktDecodeEtmV4I::processException()
if (!ETE_resetPkt)
{
+ /* check for M class tail chain / deferred exceptions */
+ if (m_config->coreProfile() == profile_CortexM)
+ bMTailChain = (excep_ret_addr == M_CLASS_TAIL_ADDR);
+
// if the preferred return address is not the end of the last output range...
- if (m_instr_info.instr_addr != excep_ret_addr)
+ if ((m_instr_info.instr_addr < excep_ret_addr) && !bMTailChain)
{
bool range_out = false;
instr_range_t addr_range;
@@ -1541,7 +1548,13 @@ ocsd_err_t TrcPktDecodeEtmV4I::processException()
// add end address as preferred return address to end addr in element
outElem().en_addr = excep_ret_addr;
+
outElem().excep_ret_addr = 1;
+ if (bMTailChain)
+ {
+ outElem().excep_ret_addr = 0;
+ outElem().excep_M_tail_chain = 1;
+ }
outElem().excep_ret_addr_br_tgt = branch_target;
outElem().exception_number = pExceptElem->getExcepNum();