An issue with the P0 element stack resulted in objects not being destroyed.
The P0 element stack has been refactored from a simple std::deque object to use an explicit class to handle all creation and destruction of objects.
Resulting decoder code has been updated and simplified.
Signed-off-by: Mike Leach mike.leach@linaro.org --- decoder/build/linux/ref_trace_decode_lib/makefile | 3 +- .../ref_trace_decode_lib.vcxproj | 3 +- .../ref_trace_decode_lib.vcxproj.filters | 9 +- decoder/include/etmv4/trc_etmv4_stack_elem.h | 338 +++++++++++++++++++++ decoder/include/etmv4/trc_pkt_decode_etmv4i.h | 7 +- decoder/source/etmv4/trc_etmv4_stack_elem.cpp | 110 +++++++ decoder/source/etmv4/trc_etmv4_stack_elem.h | 227 -------------- decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp | 144 +++------ 8 files changed, 503 insertions(+), 338 deletions(-) create mode 100644 decoder/include/etmv4/trc_etmv4_stack_elem.h create mode 100644 decoder/source/etmv4/trc_etmv4_stack_elem.cpp delete mode 100644 decoder/source/etmv4/trc_etmv4_stack_elem.h
diff --git a/decoder/build/linux/ref_trace_decode_lib/makefile b/decoder/build/linux/ref_trace_decode_lib/makefile index ed947e7..e8fafc4 100644 --- a/decoder/build/linux/ref_trace_decode_lib/makefile +++ b/decoder/build/linux/ref_trace_decode_lib/makefile @@ -67,7 +67,8 @@ ETMV4OBJ= $(BUILD_DIR)/trc_cmp_cfg_etmv4.o \ $(BUILD_DIR)/trc_pkt_proc_etmv4i_impl.o \ $(BUILD_DIR)/trc_pkt_decode_etmv4i.o \ $(BUILD_DIR)/trc_pkt_elem_etmv4i.o \ - $(BUILD_DIR)/trc_pkt_elem_etmv4d.o + $(BUILD_DIR)/trc_pkt_elem_etmv4d.o \ + $(BUILD_DIR)/trc_etmv4_stack_elem.o
PTMOBJ= $(BUILD_DIR)/trc_cmp_cfg_ptm.o \ $(BUILD_DIR)/trc_pkt_elem_ptm.o \ diff --git a/decoder/build/win-vs2015/ref_trace_decode_lib/ref_trace_decode_lib.vcxproj b/decoder/build/win-vs2015/ref_trace_decode_lib/ref_trace_decode_lib.vcxproj index e9f231d..108371a 100644 --- a/decoder/build/win-vs2015/ref_trace_decode_lib/ref_trace_decode_lib.vcxproj +++ b/decoder/build/win-vs2015/ref_trace_decode_lib/ref_trace_decode_lib.vcxproj @@ -345,6 +345,7 @@ <ClInclude Include="..\..\..\include\etmv4\etmv4_decoder.h" /> <ClInclude Include="..\..\..\include\etmv4\trc_cmp_cfg_etmv4.h" /> <ClInclude Include="..\..\..\include\etmv4\trc_dcd_mngr_etmv4i.h" /> + <ClInclude Include="..\..\..\include\etmv4\trc_etmv4_stack_elem.h" /> <ClInclude Include="..\..\..\include\etmv4\trc_pkt_decode_etmv4i.h" /> <ClInclude Include="..\..\..\include\etmv4\trc_pkt_elem_etmv4d.h" /> <ClInclude Include="..\..\..\include\etmv4\trc_pkt_elem_etmv4i.h" /> @@ -396,7 +397,6 @@ <ClInclude Include="..\..\..\include\trc_gen_elem_types.h" /> <ClInclude Include="..\..\..\include\trc_pkt_types.h" /> <ClInclude Include="..\..\..\source\etmv3\trc_pkt_proc_etmv3_impl.h" /> - <ClInclude Include="..\..\..\source\etmv4\trc_etmv4_stack_elem.h" /> <ClInclude Include="..\..\..\source\etmv4\trc_pkt_proc_etmv4d_impl.h" /> <ClInclude Include="..\..\..\source\etmv4\trc_pkt_proc_etmv4i_impl.h" /> <ClInclude Include="..\..\..\source\trc_frame_deformatter_impl.h" /> @@ -408,6 +408,7 @@ <ClCompile Include="..\..\..\source\etmv3\trc_pkt_proc_etmv3.cpp" /> <ClCompile Include="..\..\..\source\etmv3\trc_pkt_proc_etmv3_impl.cpp" /> <ClCompile Include="..\..\..\source\etmv4\trc_cmp_cfg_etmv4.cpp" /> + <ClCompile Include="..\..\..\source\etmv4\trc_etmv4_stack_elem.cpp" /> <ClCompile Include="..\..\..\source\etmv4\trc_pkt_decode_etmv4i.cpp" /> <ClCompile Include="..\..\..\source\etmv4\trc_pkt_elem_etmv4d.cpp" /> <ClCompile Include="..\..\..\source\etmv4\trc_pkt_elem_etmv4i.cpp" /> diff --git a/decoder/build/win-vs2015/ref_trace_decode_lib/ref_trace_decode_lib.vcxproj.filters b/decoder/build/win-vs2015/ref_trace_decode_lib/ref_trace_decode_lib.vcxproj.filters index a3f3558..fcfae51 100644 --- a/decoder/build/win-vs2015/ref_trace_decode_lib/ref_trace_decode_lib.vcxproj.filters +++ b/decoder/build/win-vs2015/ref_trace_decode_lib/ref_trace_decode_lib.vcxproj.filters @@ -191,9 +191,6 @@ <ClInclude Include="..\..\..\include\etmv4\trc_pkt_decode_etmv4i.h"> <Filter>Header Files\etmv4</Filter> </ClInclude> - <ClInclude Include="..\..\..\source\etmv4\trc_etmv4_stack_elem.h"> - <Filter>Header Files\etmv4</Filter> - </ClInclude> <ClInclude Include="..\..\..\include\mem_acc\trc_mem_acc.h"> <Filter>Header Files\mem_acc</Filter> </ClInclude> @@ -356,6 +353,9 @@ <ClInclude Include="..\..\..\include\common\trc_ret_stack.h"> <Filter>Header Files\common</Filter> </ClInclude> + <ClInclude Include="..\..\..\include\etmv4\trc_etmv4_stack_elem.h"> + <Filter>Header Files\etmv4</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ClCompile Include="..\..\..\source\trc_component.cpp"> @@ -481,5 +481,8 @@ <ClCompile Include="..\..\..\source\trc_ret_stack.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="..\..\..\source\etmv4\trc_etmv4_stack_elem.cpp"> + <Filter>Source Files\etmv4</Filter> + </ClCompile> </ItemGroup> </Project> \ No newline at end of file diff --git a/decoder/include/etmv4/trc_etmv4_stack_elem.h b/decoder/include/etmv4/trc_etmv4_stack_elem.h new file mode 100644 index 0000000..be620b4 --- /dev/null +++ b/decoder/include/etmv4/trc_etmv4_stack_elem.h @@ -0,0 +1,338 @@ +/* + * \file trc_etmv4_stack_elem.h + * \brief OpenCSD : + * + * \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved. + */ +/* + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef ARM_TRC_ETMV4_STACK_ELEM_H_INCLUDED +#define ARM_TRC_ETMV4_STACK_ELEM_H_INCLUDED + +#include "etmv4/trc_pkt_types_etmv4.h" + +#include <deque> +#include <vector> + +/* ETMv4 I trace stack elements + Speculation requires that we stack certain elements till they are committed or + cancelled. (P0 elements + other associated parts.) +*/ + +typedef enum _p0_elem_t +{ + P0_UNKNOWN, + P0_ATOM, + P0_ADDR, + P0_CTXT, + P0_TRC_ON, + P0_EXCEP, + P0_EXCEP_RET, + P0_EVENT, + P0_TS, + P0_CC, + P0_TS_CC, + P0_OVERFLOW +} p0_elem_t; + + +/************************************************************/ +/***Trace stack element base class - + record originating packet type and index in buffer*/ + +class TrcStackElem { +public: + TrcStackElem(const p0_elem_t p0_type, const bool isP0, const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index); + virtual ~TrcStackElem() {}; + + const p0_elem_t getP0Type() const { return m_P0_type; }; + const ocsd_etmv4_i_pkt_type getRootPkt() const { return m_root_pkt; }; + const ocsd_trc_index_t getRootIndex() const { return m_root_idx; }; + const bool isP0() const { return m_is_P0; }; + +private: + ocsd_etmv4_i_pkt_type m_root_pkt; + ocsd_trc_index_t m_root_idx; + p0_elem_t m_P0_type; + +protected: + bool m_is_P0; // true if genuine P0 - commit / cancellable, false otherwise + +}; + +inline TrcStackElem::TrcStackElem(p0_elem_t p0_type, const bool isP0, ocsd_etmv4_i_pkt_type root_pkt, ocsd_trc_index_t root_index) : + m_root_pkt(root_pkt), + m_root_idx(root_index), + m_P0_type(p0_type), + m_is_P0(isP0) +{ +} + +/************************************************************/ +/** Address element */ + +class TrcStackElemAddr : public TrcStackElem +{ +protected: + TrcStackElemAddr(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index); + virtual ~TrcStackElemAddr() {}; + + friend class EtmV4P0Stack; + +public: + void setAddr(const etmv4_addr_val_t &addr_val) { m_addr_val = addr_val; }; + const etmv4_addr_val_t &getAddr() const { return m_addr_val; }; + +private: + etmv4_addr_val_t m_addr_val; +}; + +inline TrcStackElemAddr::TrcStackElemAddr(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) : + TrcStackElem(P0_ADDR, false, root_pkt,root_index) +{ + m_addr_val.val = 0; + m_addr_val.isa = 0; +} + +/************************************************************/ +/** Context element */ + +class TrcStackElemCtxt : public TrcStackElem +{ +protected: + TrcStackElemCtxt(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index); + virtual ~TrcStackElemCtxt() {}; + + friend class EtmV4P0Stack; + +public: + void setContext(const etmv4_context_t &ctxt) { m_context = ctxt; }; + const etmv4_context_t &getContext() const { return m_context; }; + +private: + etmv4_context_t m_context; +}; + +inline TrcStackElemCtxt::TrcStackElemCtxt(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) : + TrcStackElem(P0_CTXT, false, root_pkt,root_index) +{ +} + +/************************************************************/ +/** Exception element */ + +class TrcStackElemExcept : public TrcStackElem +{ +protected: + TrcStackElemExcept(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index); + virtual ~TrcStackElemExcept() {}; + + friend class EtmV4P0Stack; + +public: + void setPrevSame(bool bSame) { m_prev_addr_same = bSame; }; + const bool getPrevSame() const { return m_prev_addr_same; }; + + void setExcepNum(const uint16_t num) { m_excep_num = num; }; + const uint16_t getExcepNum() const { return m_excep_num; }; + +private: + bool m_prev_addr_same; + uint16_t m_excep_num; +}; + +inline TrcStackElemExcept::TrcStackElemExcept(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) : + TrcStackElem(P0_EXCEP, true, root_pkt,root_index), + m_prev_addr_same(false) +{ +} + +/************************************************************/ +/** Atom element */ + +class TrcStackElemAtom : public TrcStackElem +{ +protected: + TrcStackElemAtom(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index); + virtual ~TrcStackElemAtom() {}; + + friend class EtmV4P0Stack; + +public: + void setAtom(const ocsd_pkt_atom &atom) { m_atom = atom; }; + + const ocsd_atm_val commitOldest(); + int cancelNewest(const int nCancel); + const bool isEmpty() const { return (m_atom.num == 0); }; + +private: + ocsd_pkt_atom m_atom; +}; + +inline TrcStackElemAtom::TrcStackElemAtom(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) : + TrcStackElem(P0_ATOM, true, root_pkt,root_index) +{ + m_atom.num = 0; +} + +// commit oldest - get value and remove it from pattern +inline const ocsd_atm_val TrcStackElemAtom::commitOldest() +{ + ocsd_atm_val val = (m_atom.En_bits & 0x1) ? ATOM_E : ATOM_N; + m_atom.num--; + m_atom.En_bits >>= 1; + return val; +} + +// cancel newest - just reduce the atom count. +inline int TrcStackElemAtom::cancelNewest(const int nCancel) +{ + int nRemove = (nCancel <= m_atom.num) ? nCancel : m_atom.num; + m_atom.num -= nRemove; + return nRemove; +} + +/************************************************************/ +/** Generic param element */ + +class TrcStackElemParam : public TrcStackElem +{ +protected: + TrcStackElemParam(const p0_elem_t p0_type, const bool isP0, const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index); + virtual ~TrcStackElemParam() {}; + + friend class EtmV4P0Stack; + +public: + void setParam(const uint32_t param, const int nParamNum) { m_param[(nParamNum & 0x3)] = param; }; + const uint32_t &getParam(const int nParamNum) const { return m_param[(nParamNum & 0x3)]; }; + +private: + uint32_t m_param[4]; +}; + +inline TrcStackElemParam::TrcStackElemParam(const p0_elem_t p0_type, const bool isP0, const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) : + TrcStackElem(p0_type, isP0, root_pkt,root_index) +{ +} + +/************************************************************/ +/* P0 element stack that allows push of elements, and deletion of elements when done. +*/ +class EtmV4P0Stack +{ +public: + EtmV4P0Stack() {}; + ~EtmV4P0Stack(); + + void push_front(TrcStackElem *pElem); + void pop_back(); + TrcStackElem *back(); + size_t size(); + + void delete_all(); + void delete_back(); + void delete_popped(); + + // creation functions - create and push if successful. + TrcStackElemParam *createParamElem(const p0_elem_t p0_type, const bool isP0, const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const std::vector<uint32_t> ¶ms); + TrcStackElemParam *createParamElemNoParam(const p0_elem_t p0_type, const bool isP0, const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index); + TrcStackElemAtom *createAtomElem (const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const ocsd_pkt_atom &atom); + TrcStackElemExcept *createExceptElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const bool bSame, const uint16_t excepNum); + TrcStackElemCtxt *createContextElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_context_t &context); + TrcStackElemAddr *createAddrElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_addr_val_t &addr_val); + +private: + std::deque<TrcStackElem *> m_P0_stack; //!< P0 decode element stack + std::vector<TrcStackElem *> m_popped_elem; //!< save list of popped but not deleted elements. + +}; + +inline EtmV4P0Stack::~EtmV4P0Stack() +{ + delete_all(); + delete_popped(); +} + +// put an element on the front of the stack +inline void EtmV4P0Stack::push_front(TrcStackElem *pElem) +{ + m_P0_stack.push_front(pElem); +} + +// pop last element pointer off the stack and stash it for later deletion +inline void EtmV4P0Stack::pop_back() +{ + m_popped_elem.push_back(m_P0_stack.back()); + m_P0_stack.pop_back(); +} + +// pop last element pointer off the stack and delete immediately +inline void EtmV4P0Stack::delete_back() +{ + if (m_P0_stack.size() > 0) + { + TrcStackElem* pElem = m_P0_stack.back(); + delete pElem; + m_P0_stack.pop_back(); + } +} + +// get a pointer to the last element on the stack +inline TrcStackElem *EtmV4P0Stack::back() +{ + return m_P0_stack.back(); +} + +// remove and delete all the elements left on the stack +inline void EtmV4P0Stack::delete_all() +{ + while (m_P0_stack.size() > 0) + delete_back(); + m_P0_stack.clear(); +} + +// delete list of popped elements. +inline void EtmV4P0Stack::delete_popped() +{ + while (m_popped_elem.size() > 0) + { + delete m_popped_elem.back(); + m_popped_elem.pop_back(); + } + m_popped_elem.clear(); +} + +// get current number of elements on the stack +inline size_t EtmV4P0Stack::size() +{ + return m_P0_stack.size(); +} + +#endif // ARM_TRC_ETMV4_STACK_ELEM_H_INCLUDED + +/* End of File trc_etmv4_stack_elem.h */ diff --git a/decoder/include/etmv4/trc_pkt_decode_etmv4i.h b/decoder/include/etmv4/trc_pkt_decode_etmv4i.h index 3621405..6891ffb 100644 --- a/decoder/include/etmv4/trc_pkt_decode_etmv4i.h +++ b/decoder/include/etmv4/trc_pkt_decode_etmv4i.h @@ -40,8 +40,7 @@ #include "etmv4/trc_cmp_cfg_etmv4.h" #include "common/trc_gen_elem.h" #include "common/trc_ret_stack.h" - -#include <deque> +#include "etmv4/trc_etmv4_stack_elem.h"
class TrcStackElem; class TrcStackElemParam; @@ -139,7 +138,7 @@ private: processor_state_t m_curr_state;
//** P0 element stack - std::deque<TrcStackElem *> m_P0_stack; //!< P0 decode element stack + EtmV4P0Stack m_P0_stack; //!< P0 decode element stack
int m_P0_commit; //!< number of elements to commit
@@ -163,7 +162,7 @@ private: ocsd_instr_info m_instr_info; //!< instruction info for code follower - in address is the next to be decoded.
bool m_mem_nacc_pending; //!< need to output a memory access failure packet - ocsd_vaddr_t m_nacc_addr; //!< + ocsd_vaddr_t m_nacc_addr; //!< record unaccessible address
ocsd_pe_context m_pe_context; //!< current context information etmv4_trace_info_t m_trace_info; //!< trace info for this trace run. diff --git a/decoder/source/etmv4/trc_etmv4_stack_elem.cpp b/decoder/source/etmv4/trc_etmv4_stack_elem.cpp new file mode 100644 index 0000000..1a9192c --- /dev/null +++ b/decoder/source/etmv4/trc_etmv4_stack_elem.cpp @@ -0,0 +1,110 @@ +/* +* \file trc_etmv4_stack_elem.cpp +* \brief OpenCSD : ETMv4 decoder +* +* \copyright Copyright (c) 2017, ARM Limited. All Rights Reserved. +*/ + + +/* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* +* 3. Neither the name of the copyright holder nor the names of its contributors +* may be used to endorse or promote products derived from this software without +* specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "etmv4/trc_etmv4_stack_elem.h" + +/* implementation of P0 element stack in ETM v4 trace*/ +TrcStackElemParam *EtmV4P0Stack::createParamElemNoParam(const p0_elem_t p0_type, const bool isP0, const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) +{ + std::vector<uint32_t> params; + params.clear(); + return createParamElem(p0_type, isP0, root_pkt, root_index, params); +} + +TrcStackElemParam *EtmV4P0Stack::createParamElem(const p0_elem_t p0_type, const bool isP0, const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const std::vector<uint32_t> ¶ms) +{ + TrcStackElemParam *pElem = new (std::nothrow) TrcStackElemParam(p0_type, isP0, root_pkt, root_index); + if (pElem) + { + int param_idx = 0; + int params_to_fill = params.size(); + while ((param_idx < 4) && params_to_fill) + { + pElem->setParam(params[param_idx], param_idx); + param_idx++; + params_to_fill--; + } + push_front(pElem); + } + return pElem; +} + +TrcStackElemAtom *EtmV4P0Stack::createAtomElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const ocsd_pkt_atom &atom) +{ + TrcStackElemAtom *pElem = new (std::nothrow) TrcStackElemAtom(root_pkt, root_index); + if (pElem) + { + pElem->setAtom(atom); + push_front(pElem); + } + return pElem; +} + +TrcStackElemExcept *EtmV4P0Stack::createExceptElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const bool bSame, const uint16_t excepNum) +{ + TrcStackElemExcept *pElem = new (std::nothrow) TrcStackElemExcept(root_pkt, root_index); + if (pElem) + { + pElem->setExcepNum(excepNum); + pElem->setPrevSame(bSame); + push_front(pElem); + } + return pElem; +} + +TrcStackElemCtxt *EtmV4P0Stack::createContextElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_context_t &context) +{ + TrcStackElemCtxt *pElem = new (std::nothrow) TrcStackElemCtxt(root_pkt, root_index); + if (pElem) + { + pElem->setContext(context); + push_front(pElem); + } + return pElem; + +} + +TrcStackElemAddr *EtmV4P0Stack::createAddrElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_addr_val_t &addr_val) +{ + TrcStackElemAddr *pElem = new (std::nothrow) TrcStackElemAddr(root_pkt, root_index); + if (pElem) + { + pElem->setAddr(addr_val); + push_front(pElem); + } + return pElem; +} + +/* End of file trc_etmv4_stack_elem.cpp */ diff --git a/decoder/source/etmv4/trc_etmv4_stack_elem.h b/decoder/source/etmv4/trc_etmv4_stack_elem.h deleted file mode 100644 index 5335ba8..0000000 --- a/decoder/source/etmv4/trc_etmv4_stack_elem.h +++ /dev/null @@ -1,227 +0,0 @@ -/* - * \file trc_etmv4_stack_elem.h - * \brief OpenCSD : - * - * \copyright Copyright (c) 2015, ARM Limited. All Rights Reserved. - */ -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors - * may be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef ARM_TRC_ETMV4_STACK_ELEM_H_INCLUDED -#define ARM_TRC_ETMV4_STACK_ELEM_H_INCLUDED - -#include "etmv4/trc_pkt_types_etmv4.h" - -/* ETMv4 I trace stack elements - Speculation requires that we stack certain elements till they are committed or - cancelled. (P0 elements + other associated parts.) -*/ - -typedef enum _p0_elem_t -{ - P0_UNKNOWN, - P0_ATOM, - P0_ADDR, - P0_CTXT, - P0_TRC_ON, - P0_EXCEP, - P0_EXCEP_RET, - P0_EVENT, - P0_TS, - P0_CC, - P0_TS_CC, - P0_OVERFLOW -} p0_elem_t; - - -/************************************************************/ -/***Trace stack element base class - - record originating packet type and index in buffer*/ - -class TrcStackElem { -public: - TrcStackElem(const p0_elem_t p0_type, const bool isP0, const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index); - virtual ~TrcStackElem() {}; - - const p0_elem_t getP0Type() const { return m_P0_type; }; - const ocsd_etmv4_i_pkt_type getRootPkt() const { return m_root_pkt; }; - const ocsd_trc_index_t getRootIndex() const { return m_root_idx; }; - const bool isP0() const { return m_is_P0; }; - -private: - ocsd_etmv4_i_pkt_type m_root_pkt; - ocsd_trc_index_t m_root_idx; - p0_elem_t m_P0_type; - -protected: - bool m_is_P0; // true if genuine P0 - commit / cancellable, false otherwise - -}; - -inline TrcStackElem::TrcStackElem(p0_elem_t p0_type, const bool isP0, ocsd_etmv4_i_pkt_type root_pkt, ocsd_trc_index_t root_index) : - m_root_pkt(root_pkt), - m_root_idx(root_index), - m_P0_type(p0_type), - m_is_P0(isP0) -{ -} - -/************************************************************/ -/** Address element */ - -class TrcStackElemAddr : public TrcStackElem -{ -public: - TrcStackElemAddr(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index); - virtual ~TrcStackElemAddr() {}; - - void setAddr(const etmv4_addr_val_t addr_val) { m_addr_val = addr_val; }; - const etmv4_addr_val_t &getAddr() const { return m_addr_val; }; - -private: - etmv4_addr_val_t m_addr_val; -}; - -inline TrcStackElemAddr::TrcStackElemAddr(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) : - TrcStackElem(P0_ADDR, false, root_pkt,root_index) -{ - m_addr_val.val = 0; - m_addr_val.isa = 0; -} - -/************************************************************/ -/** Context element */ - -class TrcStackElemCtxt : public TrcStackElem -{ -public: - TrcStackElemCtxt(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index); - virtual ~TrcStackElemCtxt() {}; - - void setContext(const etmv4_context_t &ctxt) { m_context = ctxt; }; - const etmv4_context_t &getContext() const { return m_context; }; - -private: - etmv4_context_t m_context; -}; - -inline TrcStackElemCtxt::TrcStackElemCtxt(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) : - TrcStackElem(P0_CTXT, false, root_pkt,root_index) -{ -} - -/************************************************************/ -/** Exception element */ - -class TrcStackElemExcept : public TrcStackElem -{ -public: - TrcStackElemExcept(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index); - virtual ~TrcStackElemExcept() {}; - - void setPrevSame(bool bSame) { m_prev_addr_same = bSame; }; - const bool getPrevSame() const { return m_prev_addr_same; }; - - void setExcepNum(const uint16_t num) { m_excep_num = num; }; - const uint16_t getExcepNum() const { return m_excep_num; }; - -private: - bool m_prev_addr_same; - uint16_t m_excep_num; -}; - -inline TrcStackElemExcept::TrcStackElemExcept(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) : - TrcStackElem(P0_EXCEP, true, root_pkt,root_index), - m_prev_addr_same(false) -{ -} - -/************************************************************/ -/** Atom element */ - -class TrcStackElemAtom : public TrcStackElem -{ -public: - TrcStackElemAtom(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index); - virtual ~TrcStackElemAtom() {}; - - void setAtom(const ocsd_pkt_atom &atom) { m_atom = atom; }; - - const ocsd_atm_val commitOldest(); - int cancelNewest(const int nCancel); - const bool isEmpty() const { return (m_atom.num == 0); }; - -private: - ocsd_pkt_atom m_atom; -}; - -inline TrcStackElemAtom::TrcStackElemAtom(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) : - TrcStackElem(P0_ATOM, true, root_pkt,root_index) -{ - m_atom.num = 0; -} - -// commit oldest - get value and remove it from pattern -inline const ocsd_atm_val TrcStackElemAtom::commitOldest() -{ - ocsd_atm_val val = (m_atom.En_bits & 0x1) ? ATOM_E : ATOM_N; - m_atom.num--; - m_atom.En_bits >>= 1; - return val; -} - -// cancel newest - just reduce the atom count. -inline int TrcStackElemAtom::cancelNewest(const int nCancel) -{ - int nRemove = (nCancel <= m_atom.num) ? nCancel : m_atom.num; - m_atom.num -= nRemove; - return nRemove; -} - -/************************************************************/ -/** Generic param element */ - -class TrcStackElemParam : public TrcStackElem -{ -public: - TrcStackElemParam(const p0_elem_t p0_type, const bool isP0, const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index); - virtual ~TrcStackElemParam() {}; - - void setParam(const uint32_t param, const int nParamNum) { m_param[(nParamNum & 0x3)] = param; }; - const uint32_t &getParam(const int nParamNum) const { return m_param[(nParamNum & 0x3)]; }; - -private: - uint32_t m_param[4]; -}; - -inline TrcStackElemParam::TrcStackElemParam(const p0_elem_t p0_type, const bool isP0, const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) : - TrcStackElem(p0_type, isP0, root_pkt,root_index) -{ -} - -#endif // ARM_TRC_ETMV4_STACK_ELEM_H_INCLUDED - -/* End of File trc_etmv4_stack_elem.h */ diff --git a/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp b/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp index 77a1173..8596b19 100644 --- a/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp +++ b/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp @@ -35,7 +35,6 @@
#include "etmv4/trc_pkt_decode_etmv4i.h"
-#include "trc_etmv4_stack_elem.h" #include "common/trc_gen_elem.h"
@@ -232,7 +231,7 @@ void TrcPktDecodeEtmV4I::resetDecoder() m_except_pending_addr = false; m_mem_nacc_pending = false; m_prev_overflow = false; - m_P0_stack.clear(); + m_P0_stack.delete_all(); m_output_elem.init(); m_excep_proc = EXCEP_POP; m_flush_EOT = false; @@ -260,22 +259,14 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV4I::decodePacket(bool &Complete)
case ETM4_PKT_I_TRACE_ON: { - TrcStackElemParam *pElem = - new (std::nothrow) TrcStackElemParam( P0_TRC_ON, false, m_curr_packet_in->getType(), m_index_curr_pkt); - if(pElem) - m_P0_stack.push_front(pElem); - else + if (m_P0_stack.createParamElemNoParam(P0_TRC_ON, false, m_curr_packet_in->getType(), m_index_curr_pkt) == 0) bAllocErr = true; } break;
case ETM4_PKT_I_OVERFLOW: { - TrcStackElemParam *pElem = - new (std::nothrow) TrcStackElemParam( P0_OVERFLOW, false, m_curr_packet_in->getType(), m_index_curr_pkt); - if(pElem) - m_P0_stack.push_front(pElem); - else + if (m_P0_stack.createParamElemNoParam(P0_OVERFLOW, false, m_curr_packet_in->getType(), m_index_curr_pkt) == 0) bAllocErr = true; } break; @@ -287,47 +278,29 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV4I::decodePacket(bool &Complete) case ETM4_PKT_I_ATOM_F5: case ETM4_PKT_I_ATOM_F6: { - TrcStackElemAtom *pElem = new (std::nothrow) TrcStackElemAtom(m_curr_packet_in->getType(), m_index_curr_pkt); - if(pElem) - { - pElem->setAtom(m_curr_packet_in->getAtom()); - m_P0_stack.push_front(pElem); - m_curr_spec_depth += m_curr_packet_in->getAtom().num; - } - else + if (m_P0_stack.createAtomElem(m_curr_packet_in->getType(), m_index_curr_pkt, m_curr_packet_in->getAtom()) == 0) bAllocErr = true; + else + m_curr_spec_depth += m_curr_packet_in->getAtom().num; } break;
case ETM4_PKT_I_CTXT: { - TrcStackElemCtxt *pElem = new (std::nothrow) TrcStackElemCtxt(m_curr_packet_in->getType(), m_index_curr_pkt); - if(pElem) - { - pElem->setContext(m_curr_packet_in->getContext()); - m_P0_stack.push_front(pElem); - } - else - bAllocErr = true; + if (m_P0_stack.createContextElem(m_curr_packet_in->getType(), m_index_curr_pkt, m_curr_packet_in->getContext()) == 0) + bAllocErr = true; } break;
case ETM4_PKT_I_ADDR_MATCH: { - TrcStackElemAddr *pElem = new (std::nothrow) TrcStackElemAddr(m_curr_packet_in->getType(), m_index_curr_pkt); - if(pElem) - { etmv4_addr_val_t addr;
- // address match - just grab whatever the current value is... addr.val = m_curr_packet_in->getAddrVal(); addr.isa = m_curr_packet_in->getAddrIS(); - pElem->setAddr(addr); - m_P0_stack.push_front(pElem); - } - else - bAllocErr = true; - is_addr = true; + if (m_P0_stack.createAddrElem(m_curr_packet_in->getType(), m_index_curr_pkt, addr) == 0) + bAllocErr = true; + is_addr = true; } break;
@@ -336,13 +309,7 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV4I::decodePacket(bool &Complete) case ETM4_PKT_I_ADDR_CTXT_L_32IS0: case ETM4_PKT_I_ADDR_CTXT_L_32IS1: { - TrcStackElemCtxt *pElem = new (std::nothrow) TrcStackElemCtxt(m_curr_packet_in->getType(), m_index_curr_pkt); - if(pElem) - { - pElem->setContext(m_curr_packet_in->getContext()); - m_P0_stack.push_front(pElem); - } - else + if (m_P0_stack.createContextElem(m_curr_packet_in->getType(), m_index_curr_pkt, m_curr_packet_in->getContext()) == 0) bAllocErr = true; } case ETM4_PKT_I_ADDR_L_32IS0: @@ -352,17 +319,11 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV4I::decodePacket(bool &Complete) case ETM4_PKT_I_ADDR_S_IS0: case ETM4_PKT_I_ADDR_S_IS1: { - TrcStackElemAddr *pElem = new (std::nothrow) TrcStackElemAddr(m_curr_packet_in->getType(), m_index_curr_pkt); - if(pElem) - { - etmv4_addr_val_t addr; + etmv4_addr_val_t addr;
- addr.val = m_curr_packet_in->getAddrVal(); - addr.isa = m_curr_packet_in->getAddrIS(); - pElem->setAddr(addr); - m_P0_stack.push_front(pElem); - } - else + addr.val = m_curr_packet_in->getAddrVal(); + addr.isa = m_curr_packet_in->getAddrIS(); + if (m_P0_stack.createAddrElem(m_curr_packet_in->getType(), m_index_curr_pkt, addr) == 0) bAllocErr = true; is_addr = true; } @@ -371,45 +332,33 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV4I::decodePacket(bool &Complete) // Exceptions case ETM4_PKT_I_EXCEPT: { - TrcStackElemExcept *pElem = new (std::nothrow) TrcStackElemExcept(m_curr_packet_in->getType(), m_index_curr_pkt); - if(pElem) + if (m_P0_stack.createExceptElem(m_curr_packet_in->getType(), m_index_curr_pkt, + (m_curr_packet_in->exception_info.addr_interp == 0x2), + m_curr_packet_in->exception_info.exceptionType) == 0) + bAllocErr = true; + else { - pElem->setPrevSame(m_curr_packet_in->exception_info.addr_interp == 0x2); - m_P0_stack.push_front(pElem); m_except_pending_addr = true; // wait for following packets before marking for commit. is_except = true; - pElem->setExcepNum(m_curr_packet_in->exception_info.exceptionType); } - else - bAllocErr = true; - } - break; + } + break;
case ETM4_PKT_I_EXCEPT_RTN: { // P0 element if V7M profile. bool bV7MProfile = (m_config->archVersion() == ARCH_V7) && (m_config->coreProfile() == profile_CortexM); - TrcStackElemParam *pElem = - new (std::nothrow) TrcStackElemParam(P0_EXCEP_RET, bV7MProfile, m_curr_packet_in->getType(), m_index_curr_pkt); - if(pElem) - m_P0_stack.push_front(pElem); - else + if (m_P0_stack.createParamElemNoParam(P0_EXCEP_RET, bV7MProfile, m_curr_packet_in->getType(), m_index_curr_pkt) == 0) bAllocErr = true; - } break;
// event trace case ETM4_PKT_I_EVENT: { - TrcStackElemParam *pElem = - new (std::nothrow) TrcStackElemParam( P0_EVENT, false, m_curr_packet_in->getType(), m_index_curr_pkt); - if(pElem) - { - pElem->setParam(m_curr_packet_in->event_val,0); - m_P0_stack.push_front(pElem); - } - else + std::vector<uint32_t> params; + params[0] = (uint32_t)m_curr_packet_in->event_val; + if (m_P0_stack.createParamElem(P0_EVENT, false, m_curr_packet_in->getType(), m_index_curr_pkt, params) == 0) bAllocErr = true;
} @@ -420,14 +369,9 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV4I::decodePacket(bool &Complete) case ETM4_PKT_I_CCNT_F2: case ETM4_PKT_I_CCNT_F3: { - TrcStackElemParam *pElem = - new (std::nothrow) TrcStackElemParam( P0_CC, false, m_curr_packet_in->getType(), m_index_curr_pkt); - if(pElem) - { - pElem->setParam(m_curr_packet_in->getCC(),0); - m_P0_stack.push_front(pElem); - } - else + std::vector<uint32_t> params; + params[0] = m_curr_packet_in->getCC(); + if (m_P0_stack.createParamElem(P0_EVENT, false, m_curr_packet_in->getType(), m_index_curr_pkt, params) == 0) bAllocErr = true;
} @@ -437,18 +381,13 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV4I::decodePacket(bool &Complete) case ETM4_PKT_I_TIMESTAMP: { bool bTSwithCC = m_config->enabledCCI(); - TrcStackElemParam *pElem = - new (std::nothrow) TrcStackElemParam( bTSwithCC ? P0_TS_CC : P0_TS, false, m_curr_packet_in->getType(), m_index_curr_pkt); - if(pElem) - { - uint64_t ts = m_curr_packet_in->getTS(); - pElem->setParam((uint32_t)(ts & 0xFFFFFFFF),0); - pElem->setParam((uint32_t)((ts>>32) & 0xFFFFFFFF),1); - if(bTSwithCC) - pElem->setParam(m_curr_packet_in->getCC(),2); - m_P0_stack.push_front(pElem); - } - else + uint64_t ts = m_curr_packet_in->getTS(); + std::vector<uint32_t> params; + params[0] = (uint32_t)(ts & 0xFFFFFFFF); + params[1] = (uint32_t)((ts >> 32) & 0xFFFFFFFF); + if (bTSwithCC) + params[2] = m_curr_packet_in->getCC(); + if (m_P0_stack.createParamElem(P0_EVENT, false, m_curr_packet_in->getType(), m_index_curr_pkt, params) == 0) bAllocErr = true;
} @@ -687,7 +626,7 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV4I::commitElements(bool &Complete) }
if(bPopElem) - m_P0_stack.pop_back(); // remove element from stack; + m_P0_stack.delete_back(); // remove element from stack;
// if response not continue, then break out of the loop. if(!OCSD_DATA_RESP_IS_CONT(resp)) @@ -751,7 +690,7 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV4I::flushEOT() // scan for outstanding events, TS and CC, before any outstanding // P0 commit elements. pElem = m_P0_stack.back(); - m_P0_stack.pop_back(); + switch(pElem->getP0Type()) { // clear stack and stop @@ -761,7 +700,7 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV4I::flushEOT() case P0_EXCEP: case P0_EXCEP_RET: case P0_OVERFLOW: - m_P0_stack.clear(); + m_P0_stack.delete_all(); break;
//skip @@ -802,7 +741,7 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV4I::flushEOT() } break; } - + m_P0_stack.delete_back(); }
if(OCSD_DATA_RESP_IS_CONT(resp) && (m_P0_stack.size() == 0)) @@ -984,6 +923,7 @@ ocsd_datapath_resp_t TrcPktDecodeEtmV4I::processException() else m_excep_proc = EXCEP_RANGE; } + m_P0_stack.delete_popped(); }
// output a range element