diff options
author | Mike Leach <mike.leach@linaro.org> | 2023-11-06 14:34:51 +0000 |
---|---|---|
committer | Mike Leach <mike.leach@linaro.org> | 2023-12-18 14:57:53 +0000 |
commit | 3401fdceb29d21fe63de0c6bfde7bfbea43d8e01 (patch) | |
tree | 7db261462a324350b54439d80486f1807e0cfc5e | |
parent | 6d6074553bd59f436ddd801166ebbf1d4a2af50a (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.h | 3 | ||||
-rw-r--r-- | 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<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(); |