From 3401fdceb29d21fe63de0c6bfde7bfbea43d8e01 Mon Sep 17 00:00:00 2001 From: Mike Leach Date: Mon, 6 Nov 2023 14:34:51 +0000 Subject: 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 --- decoder/include/opencsd/trc_gen_elem_types.h | 3 ++- decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp | 15 ++++++++++++++- 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(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(); -- cgit v1.2.3