117f65170SRuslan Bukin /*
217f65170SRuslan Bukin * \file       trc_etmv4_stack_elem.cpp
317f65170SRuslan Bukin * \brief      OpenCSD : ETMv4 decoder
417f65170SRuslan Bukin *
517f65170SRuslan Bukin * \copyright  Copyright (c) 2017, ARM Limited. All Rights Reserved.
617f65170SRuslan Bukin */
717f65170SRuslan Bukin 
817f65170SRuslan Bukin 
917f65170SRuslan Bukin /*
1017f65170SRuslan Bukin * Redistribution and use in source and binary forms, with or without modification,
1117f65170SRuslan Bukin * are permitted provided that the following conditions are met:
1217f65170SRuslan Bukin *
1317f65170SRuslan Bukin * 1. Redistributions of source code must retain the above copyright notice,
1417f65170SRuslan Bukin * this list of conditions and the following disclaimer.
1517f65170SRuslan Bukin *
1617f65170SRuslan Bukin * 2. Redistributions in binary form must reproduce the above copyright notice,
1717f65170SRuslan Bukin * this list of conditions and the following disclaimer in the documentation
1817f65170SRuslan Bukin * and/or other materials provided with the distribution.
1917f65170SRuslan Bukin *
2017f65170SRuslan Bukin * 3. Neither the name of the copyright holder nor the names of its contributors
2117f65170SRuslan Bukin * may be used to endorse or promote products derived from this software without
2217f65170SRuslan Bukin * specific prior written permission.
2317f65170SRuslan Bukin *
2417f65170SRuslan Bukin * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
2517f65170SRuslan Bukin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2617f65170SRuslan Bukin * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2717f65170SRuslan Bukin * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
2817f65170SRuslan Bukin * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2917f65170SRuslan Bukin * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3017f65170SRuslan Bukin * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3117f65170SRuslan Bukin * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3217f65170SRuslan Bukin * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3317f65170SRuslan Bukin * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3417f65170SRuslan Bukin */
3517f65170SRuslan Bukin 
3617f65170SRuslan Bukin #include "opencsd/etmv4/trc_etmv4_stack_elem.h"
3717f65170SRuslan Bukin 
3817f65170SRuslan Bukin /* implementation of P0 element stack in ETM v4 trace*/
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,bool back)39*fc502085SRuslan Bukin TrcStackElem *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, bool back /*= false*/)
4017f65170SRuslan Bukin {
41*fc502085SRuslan Bukin     TrcStackElem *pElem = new (std::nothrow) TrcStackElem(p0_type, isP0, root_pkt, root_index);
42*fc502085SRuslan Bukin     if (pElem)
43*fc502085SRuslan Bukin     {
44*fc502085SRuslan Bukin         if (back)
45*fc502085SRuslan Bukin             push_back(pElem);
46*fc502085SRuslan Bukin         else
47*fc502085SRuslan Bukin             push_front(pElem);
48*fc502085SRuslan Bukin     }
49*fc502085SRuslan Bukin     return pElem;
5017f65170SRuslan Bukin }
5117f65170SRuslan Bukin 
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> & params)5217f65170SRuslan Bukin 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> &params)
5317f65170SRuslan Bukin {
5417f65170SRuslan Bukin     TrcStackElemParam *pElem = new (std::nothrow) TrcStackElemParam(p0_type, isP0, root_pkt, root_index);
5517f65170SRuslan Bukin     if (pElem)
5617f65170SRuslan Bukin     {
5717f65170SRuslan Bukin         int param_idx = 0;
5817f65170SRuslan Bukin         int params_to_fill = params.size();
5917f65170SRuslan Bukin         while ((param_idx < 4) && params_to_fill)
6017f65170SRuslan Bukin         {
6117f65170SRuslan Bukin             pElem->setParam(params[param_idx], param_idx);
6217f65170SRuslan Bukin             param_idx++;
6317f65170SRuslan Bukin             params_to_fill--;
6417f65170SRuslan Bukin         }
6517f65170SRuslan Bukin         push_front(pElem);
6617f65170SRuslan Bukin     }
6717f65170SRuslan Bukin     return pElem;
6817f65170SRuslan Bukin }
6917f65170SRuslan Bukin 
createAtomElem(const ocsd_etmv4_i_pkt_type root_pkt,const ocsd_trc_index_t root_index,const ocsd_pkt_atom & atom)7017f65170SRuslan Bukin TrcStackElemAtom *EtmV4P0Stack::createAtomElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const ocsd_pkt_atom &atom)
7117f65170SRuslan Bukin {
7217f65170SRuslan Bukin     TrcStackElemAtom *pElem = new (std::nothrow) TrcStackElemAtom(root_pkt, root_index);
7317f65170SRuslan Bukin     if (pElem)
7417f65170SRuslan Bukin     {
7517f65170SRuslan Bukin         pElem->setAtom(atom);
7617f65170SRuslan Bukin         push_front(pElem);
7717f65170SRuslan Bukin     }
7817f65170SRuslan Bukin     return pElem;
7917f65170SRuslan Bukin }
8017f65170SRuslan Bukin 
createExceptElem(const ocsd_etmv4_i_pkt_type root_pkt,const ocsd_trc_index_t root_index,const bool bSame,const uint16_t excepNum)8117f65170SRuslan Bukin 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)
8217f65170SRuslan Bukin {
8317f65170SRuslan Bukin     TrcStackElemExcept *pElem = new (std::nothrow) TrcStackElemExcept(root_pkt, root_index);
8417f65170SRuslan Bukin     if (pElem)
8517f65170SRuslan Bukin     {
8617f65170SRuslan Bukin         pElem->setExcepNum(excepNum);
8717f65170SRuslan Bukin         pElem->setPrevSame(bSame);
8817f65170SRuslan Bukin         push_front(pElem);
8917f65170SRuslan Bukin     }
9017f65170SRuslan Bukin     return pElem;
9117f65170SRuslan Bukin }
9217f65170SRuslan Bukin 
createContextElem(const ocsd_etmv4_i_pkt_type root_pkt,const ocsd_trc_index_t root_index,const etmv4_context_t & context,const uint8_t IS,const bool back)9317f65170SRuslan Bukin TrcStackElemCtxt *EtmV4P0Stack::createContextElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_context_t &context, const uint8_t IS, const bool back /*= false*/)
9417f65170SRuslan Bukin {
9517f65170SRuslan Bukin     TrcStackElemCtxt *pElem = new (std::nothrow) TrcStackElemCtxt(root_pkt, root_index);
9617f65170SRuslan Bukin     if (pElem)
9717f65170SRuslan Bukin     {
9817f65170SRuslan Bukin         pElem->setContext(context);
9917f65170SRuslan Bukin         pElem->setIS(IS);
10017f65170SRuslan Bukin         if (back)
10117f65170SRuslan Bukin             push_back(pElem);
10217f65170SRuslan Bukin         else
10317f65170SRuslan Bukin             push_front(pElem);
10417f65170SRuslan Bukin     }
10517f65170SRuslan Bukin     return pElem;
10617f65170SRuslan Bukin 
10717f65170SRuslan Bukin }
10817f65170SRuslan Bukin 
createAddrElem(const ocsd_etmv4_i_pkt_type root_pkt,const ocsd_trc_index_t root_index,const etmv4_addr_val_t & addr_val)10917f65170SRuslan Bukin 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)
11017f65170SRuslan Bukin {
11117f65170SRuslan Bukin     TrcStackElemAddr *pElem = new (std::nothrow) TrcStackElemAddr(root_pkt, root_index);
11217f65170SRuslan Bukin     if (pElem)
11317f65170SRuslan Bukin     {
11417f65170SRuslan Bukin         pElem->setAddr(addr_val);
11517f65170SRuslan Bukin         push_front(pElem);
11617f65170SRuslan Bukin     }
117     return pElem;
118 }
119 
createQElem(const ocsd_etmv4_i_pkt_type root_pkt,const ocsd_trc_index_t root_index,const int count)120 TrcStackQElem *EtmV4P0Stack::createQElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const int count)
121 {
122     TrcStackQElem *pElem = new (std::nothrow) TrcStackQElem(root_pkt, root_index);
123     if (pElem)
124     {
125         pElem->setInstrCount(count);
126         push_front(pElem);
127     }
128     return pElem;
129 }
130 
createMarkerElem(const ocsd_etmv4_i_pkt_type root_pkt,const ocsd_trc_index_t root_index,const trace_marker_payload_t & marker)131 TrcStackElemMarker *EtmV4P0Stack::createMarkerElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const trace_marker_payload_t &marker)
132 {
133     TrcStackElemMarker *pElem = new (std::nothrow) TrcStackElemMarker(root_pkt, root_index);
134     if (pElem)
135     {
136         pElem->setMarker(marker);
137         push_front(pElem);
138     }
139     return pElem;
140 }
141 
createSrcAddrElem(const ocsd_etmv4_i_pkt_type root_pkt,const ocsd_trc_index_t root_index,const etmv4_addr_val_t & addr_val)142 TrcStackElemAddr *EtmV4P0Stack::createSrcAddrElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const etmv4_addr_val_t &addr_val)
143 {
144     TrcStackElemAddr *pElem = new (std::nothrow) TrcStackElemAddr(root_pkt, root_index, true);
145     if (pElem)
146     {
147         pElem->setAddr(addr_val);
148         push_front(pElem);
149     }
150     return pElem;
151 }
152 
createITEElem(const ocsd_etmv4_i_pkt_type root_pkt,const ocsd_trc_index_t root_index,const trace_sw_ite_t & ite)153 TrcStackElemITE *EtmV4P0Stack::createITEElem(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index, const trace_sw_ite_t &ite)
154 {
155     TrcStackElemITE *pElem = new (std::nothrow) TrcStackElemITE(root_pkt, root_index);
156     if (pElem)
157     {
158         pElem->setITE(ite);
159         push_front(pElem);
160     }
161     return pElem;
162 }
163 
164 
165 // iteration functions
from_front_init()166 void EtmV4P0Stack::from_front_init()
167 {
168     m_iter = m_P0_stack.begin();
169 }
170 
from_front_next()171 TrcStackElem *EtmV4P0Stack::from_front_next()
172 {
173     TrcStackElem *pElem = 0;
174     if (m_iter != m_P0_stack.end())
175     {
176         pElem = *m_iter++;
177     }
178     return pElem;
179 }
180 
erase_curr_from_front()181 void EtmV4P0Stack::erase_curr_from_front()
182 {
183     std::deque<TrcStackElem *>::iterator erase_iter;
184     erase_iter = m_iter;
185     erase_iter--;
186     m_P0_stack.erase(erase_iter);
187 
188     // explicitly delete the item here as the caller can no longer reference it.
189     // fixes memory leak from github issue #52
190     delete *erase_iter;
191 }
192 
193 
194 /* End of file trc_etmv4_stack_elem.cpp */
195