Upgrade OpenCSD to v0.12.1

Test: None
Change-Id: I8ab300dd684e2bec09d7a38c1a27b247ce4d0a3b
diff --git a/METADATA b/METADATA
index 34a61a7..12e6c73 100644
--- a/METADATA
+++ b/METADATA
@@ -9,10 +9,10 @@
     type: GIT
     value: "https://github.com/Linaro/OpenCSD.git"
   }
-  version: "v0.12.0"
+  version: "v0.12.1"
   last_upgrade_date {
     year: 2019
-    month: 7
-    day: 31
+    month: 10
+    day: 29
   }
 }
diff --git a/README.md b/README.md
index c3f238f..7a1c493 100644
--- a/README.md
+++ b/README.md
@@ -27,7 +27,7 @@
 CoreSight Trace Component Support.
 ----------------------------------
 
-_Current Version 0.12.0_
+_Current Version 0.12.1_
 
 ### Current support:
 
@@ -165,6 +165,11 @@
                     __Update__: Docs: Update to reflect new exception flag. Update test program example to reflect latest output.
                     __Bugfix__: ETM v4: Valid trace info packet was not handled correctly (0x01, 0x00).
                     __Bugfix__: ETM v4: Error messaging on commit stack overflow.
+- _Version 0.12.1_: __Update__: build: remove -g option from release build.
+                    __Update__: tests: Snapshots can now use generic arch+profile names rather than core names, e.g. ARMv8-A
+                    __Bugfix__: Instruction decode - v8.3 B[L]A{A|B}[Z] instructions mis-identified.
+                    __Bugfix__: Transition from A64 to A32 can be mis-decoded if the trace implementation represents the transition 
+                    as an individual address packet followed by a context packet. 
 
 
 Licence Information
diff --git a/decoder/build/linux/makefile b/decoder/build/linux/makefile
index 6032c2c..9edf328 100644
--- a/decoder/build/linux/makefile
+++ b/decoder/build/linux/makefile
@@ -81,8 +81,8 @@
 CXXFLAGS += -g -O0 -DDEBUG
 BUILD_VARIANT=dbg
 else
-CFLAGS += -g -O2 -DNDEBUG
-CXXFLAGS += -g -O2 -DNDEBUG
+CFLAGS += -O2 -DNDEBUG
+CXXFLAGS += -O2 -DNDEBUG
 BUILD_VARIANT=rel
 endif
 
diff --git a/decoder/docs/doxygen_config.dox b/decoder/docs/doxygen_config.dox
index 0ca0cf7..b4db933 100644
--- a/decoder/docs/doxygen_config.dox
+++ b/decoder/docs/doxygen_config.dox
@@ -38,7 +38,7 @@
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 0.10.0
+PROJECT_NUMBER         = 0.12.1
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
diff --git a/decoder/docs/test_progs.md b/decoder/docs/test_progs.md
index 2719455..c02d02e 100644
--- a/decoder/docs/test_progs.md
+++ b/decoder/docs/test_progs.md
@@ -20,6 +20,9 @@
 These programs are both built at the same time as the library for the same set of platforms.
 See [build_libs.md](@ref build_lib) for build details.
 
+_Note:_ The programs above use the library's [core name mapper helper class] (@ref CoreArchProfileMap) to map 
+the name of the core into a profile / architecture pair that the library can use. 
+The snapshot definition must use one of the names recognised by this class or an error will occur.
 
 Trace "Snapshot" directory.
 ----------------------------
diff --git a/decoder/include/common/trc_core_arch_map.h b/decoder/include/common/trc_core_arch_map.h
index 5a24149..b72b4b4 100644
--- a/decoder/include/common/trc_core_arch_map.h
+++ b/decoder/include/common/trc_core_arch_map.h
@@ -39,6 +39,23 @@
 #include <string>
 #include "opencsd/ocsd_if_types.h"
 
+/** @class CoreArchProfileMap
+ *
+ *  @brief Map core / arch name to profile for decoder.
+ *
+ *  Helper class for library clients to map core or architecture version names onto 
+ *  a profile / arch version pair suitable for use with the decode library.
+ * 
+ *  Valid core names are:-
+ *   - Cortex-Axx : where xx = 5,7,12,15,17,32,35,53,55,57,65,72,73,75,76,77;
+ *   - Cortex-Rxx : where xx = 5,7,8,52;
+ *   - Cortex-Mxx : where xx = 0,0+,3,4,23,33;
+ *
+ *  Valid architecture profile names are:-
+ *   - ARMv7-A, ARMv7-R, ARMv7-M;
+ *   - ARMv8-A, ARMv8.3A, ARMv8-R, ARMv8-M;
+ *  
+ */
 class CoreArchProfileMap
 {
 public:
@@ -50,16 +67,31 @@
 private:
 
     std::map<std::string, ocsd_arch_profile_t> core_profiles;
+    std::map<std::string, ocsd_arch_profile_t> arch_profiles;
 };
 
 inline ocsd_arch_profile_t CoreArchProfileMap::getArchProfile(const std::string &coreName)
 {
     ocsd_arch_profile_t ap = { ARCH_UNKNOWN, profile_Unknown };
+    bool bFound = false;
 
     std::map<std::string, ocsd_arch_profile_t>::const_iterator it;
+
+    /* match against the core name map. */
     it = core_profiles.find(coreName);
-    if(it != core_profiles.end())
+    if (it != core_profiles.end())
+    {
         ap = it->second;
+        bFound = true;
+    }
+
+    /* scan architecture profiles on no core name match */
+    if (!bFound)
+    {
+        it = arch_profiles.find(coreName);
+        if (it != arch_profiles.end())
+            ap = it->second;
+    }
     return ap;
 }
 
diff --git a/decoder/include/opencsd/etmv4/trc_etmv4_stack_elem.h b/decoder/include/opencsd/etmv4/trc_etmv4_stack_elem.h
index 1599654..1f5911c 100644
--- a/decoder/include/opencsd/etmv4/trc_etmv4_stack_elem.h
+++ b/decoder/include/opencsd/etmv4/trc_etmv4_stack_elem.h
@@ -133,9 +133,12 @@
 public:
     void setContext(const  etmv4_context_t &ctxt) { m_context = ctxt; };
     const  etmv4_context_t &getContext() const  { return m_context; }; 
+    void setIS(const uint8_t IS) { m_IS = IS; };
+    const uint8_t getIS() const { return m_IS; };
 
 private:
      etmv4_context_t m_context;
+     uint8_t m_IS;  //!< IS value at time of generation of packet.
 };
 
 inline TrcStackElemCtxt::TrcStackElemCtxt(const ocsd_etmv4_i_pkt_type root_pkt, const ocsd_trc_index_t root_index) :
@@ -265,7 +268,7 @@
     TrcStackElem *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);
     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);
+    TrcStackElemCtxt *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);
     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:
diff --git a/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h b/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h
index 1c06e5d..c73c97e 100644
--- a/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h
+++ b/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h
@@ -88,6 +88,12 @@
      
 private:
     void SetInstrInfoInAddrISA(const ocsd_vaddr_t addr_val, const uint8_t isa); 
+    const ocsd_isa calcISA(const bool SF, const uint8_t IS) const
+    {
+        if (SF)
+            return ocsd_isa_aarch64;
+        return (IS == 0) ? ocsd_isa_arm : ocsd_isa_thumb2;
+    }
 
     ocsd_err_t traceInstrToWP(bool &bWPFound, const bool traceToAddrNext = false, const ocsd_vaddr_t nextAddrMatch = 0);      //!< follow instructions from the current address to a WP. true if good, false if memory cannot be accessed.
 
@@ -105,6 +111,7 @@
     uint32_t m_vmid_id;                 // most recent VMID
     bool m_is_secure;                   // true if Secure
     bool m_is_64bit;                    // true if 64 bit
+    uint8_t m_last_IS;                  // last instruction set value from address packet.
 
     // cycle counts 
     int m_cc_threshold;
diff --git a/decoder/include/opencsd/ocsd_if_version.h b/decoder/include/opencsd/ocsd_if_version.h
index 70c8df4..31e4ffc 100644
--- a/decoder/include/opencsd/ocsd_if_version.h
+++ b/decoder/include/opencsd/ocsd_if_version.h
@@ -44,7 +44,7 @@
 @{*/
 #define OCSD_VER_MAJOR 0x0 /**< Library Major Version */
 #define OCSD_VER_MINOR 0xC /**< Library Minor Version */
-#define OCSD_VER_PATCH 0x0 /**< Library Patch Version */
+#define OCSD_VER_PATCH 0x1 /**< Library Patch Version */
 
 /** Library version number - MMMMnnpp format.
     MMMM = major version, 
@@ -53,7 +53,7 @@
 */
 #define OCSD_VER_NUM ((OCSD_VER_MAJOR << 16) | (OCSD_VER_MINOR << 8) | OCSD_VER_PATCH) 
 
-#define OCSD_VER_STRING "0.12.0"    /**< Library Version string */
+#define OCSD_VER_STRING "0.12.1"    /**< Library Version string */
 #define OCSD_LIB_NAME "OpenCSD Library"  /**< Library name string */
 #define OCSD_LIB_SHORT_NAME "OCSD"    /**< Library Short name string */
 /** @}*/
diff --git a/decoder/source/etmv4/trc_etmv4_stack_elem.cpp b/decoder/source/etmv4/trc_etmv4_stack_elem.cpp
index 8916c7d..0abdc31 100644
--- a/decoder/source/etmv4/trc_etmv4_stack_elem.cpp
+++ b/decoder/source/etmv4/trc_etmv4_stack_elem.cpp
@@ -90,12 +90,13 @@
     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 *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)
 {
     TrcStackElemCtxt *pElem = new (std::nothrow) TrcStackElemCtxt(root_pkt, root_index);
     if (pElem)
     {
         pElem->setContext(context);
+        pElem->setIS(IS);
         push_front(pElem);
     }
     return pElem;
diff --git a/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp b/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp
index 2eb6cbc..700d2a1 100644
--- a/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp
+++ b/decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp
@@ -236,6 +236,7 @@
     m_output_elem.init();
     m_excep_info.proc = EXCEP_POP;
     m_flush_EOT = false;
+    m_last_IS = 0;
 }
 
 // this function can output an immediate generic element if this covers the complete packet decode, 
@@ -289,7 +290,7 @@
 
     case ETM4_PKT_I_CTXT:
         {
-            if (m_P0_stack.createContextElem(m_curr_packet_in->getType(), m_index_curr_pkt, m_curr_packet_in->getContext()) == 0)
+            if (m_P0_stack.createContextElem(m_curr_packet_in->getType(), m_index_curr_pkt, m_curr_packet_in->getContext(), m_last_IS) == 0)
                 bAllocErr = true;
         }
         break;
@@ -299,7 +300,8 @@
             etmv4_addr_val_t addr;
 
             addr.val = m_curr_packet_in->getAddrVal();
-            addr.isa = m_curr_packet_in->getAddrIS();
+            addr.isa = m_last_IS = 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;
@@ -311,7 +313,8 @@
     case ETM4_PKT_I_ADDR_CTXT_L_32IS0:
     case ETM4_PKT_I_ADDR_CTXT_L_32IS1:    
         {
-            if (m_P0_stack.createContextElem(m_curr_packet_in->getType(), m_index_curr_pkt, m_curr_packet_in->getContext()) == 0)
+            m_last_IS = m_curr_packet_in->getAddrIS();
+            if (m_P0_stack.createContextElem(m_curr_packet_in->getType(), m_index_curr_pkt, m_curr_packet_in->getContext(),m_last_IS) == 0)
                 bAllocErr = true;
         }
     case ETM4_PKT_I_ADDR_L_32IS0:
@@ -324,7 +327,8 @@
             etmv4_addr_val_t addr;
 
             addr.val = m_curr_packet_in->getAddrVal();
-            addr.isa = m_curr_packet_in->getAddrIS();
+            addr.isa = m_last_IS = 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;
@@ -1051,10 +1055,7 @@
 void TrcPktDecodeEtmV4I::SetInstrInfoInAddrISA(const ocsd_vaddr_t addr_val, const uint8_t isa)
 {
     m_instr_info.instr_addr = addr_val;
-    if(m_is_64bit)
-        m_instr_info.isa = ocsd_isa_aarch64;
-    else
-        m_instr_info.isa = (isa == 0) ? ocsd_isa_arm : ocsd_isa_thumb2;
+    m_instr_info.isa = calcISA(m_is_64bit, isa);
 }
 
 // trace an instruction range to a waypoint - and set next address to restart from.
@@ -1128,6 +1129,9 @@
         m_output_elem.context.vmid_valid = 1;
         m_vmid_id = m_output_elem.context.vmid = ctxt.VMID;
     }
+
+    // need to update ISA in case context follows address.
+    m_output_elem.isa = m_instr_info.isa = calcISA(m_is_64bit, pCtxtElem->getIS());
     m_need_ctxt = false;
 }
 
diff --git a/decoder/source/i_dec/trc_idec_arminst.cpp b/decoder/source/i_dec/trc_idec_arminst.cpp
index 09964a1..eb52ec8 100644
--- a/decoder/source/i_dec/trc_idec_arminst.cpp
+++ b/decoder/source/i_dec/trc_idec_arminst.cpp
@@ -311,13 +311,13 @@
         instr_sub_type = OCSD_S_INSTR_V8_ERET;
     } else if (arch_version >= 0x0803) {
         /* new pointer auth instr for v8.3 arch */   
-        if ((inst & 0xffdff800) == 0xd61f0800) {
+        if ((inst & 0xffdff800) == 0xd71f0800) {
             /* BRAA, BRAB, BLRAA, BLRBB */
             if (inst & 0x00200000) {
                 *is_link = 1;
                 instr_sub_type = OCSD_S_INSTR_BR_LINK;
             }
-        } else if ((inst & 0xffdff81F) == 0xd71f081F) {
+        } else if ((inst & 0xffdff81F) == 0xd61f081F) {
             /* BRAAZ, BRABZ, BLRAAZ, BLRBBZ */
             if (inst & 0x00200000) {
                 *is_link = 1;
diff --git a/decoder/source/trc_core_arch_map.cpp b/decoder/source/trc_core_arch_map.cpp
index 70a25ee..a26f79d 100644
--- a/decoder/source/trc_core_arch_map.cpp
+++ b/decoder/source/trc_core_arch_map.cpp
@@ -34,10 +34,12 @@
 
 #include "common/trc_core_arch_map.h"
 
-static struct _ap_map_elements {
+typedef struct _ap_map_elements {
     const char *name;
     ocsd_arch_profile_t ap;
-} ap_map_array[] = 
+} ap_map_elem_t;
+
+static ap_map_elem_t ap_map_array[] = 
 {
     { "Cortex-A77", { ARCH_V8r3, profile_CortexA } },
     { "Cortex-A76", { ARCH_V8r3, profile_CortexA } },
@@ -70,12 +72,28 @@
     { "Cortex-M4", { ARCH_V7, profile_CortexM } }
 };   
 
+static ap_map_elem_t arch_map_array[] = 
+{
+    { "ARMv7-A", { ARCH_V7, profile_CortexA } },
+    { "ARMv7-R", { ARCH_V7, profile_CortexR } },
+    { "ARMv7-M", { ARCH_V7, profile_CortexM } },
+    { "ARMv8-A", { ARCH_V8, profile_CortexA } },
+    { "ARMv8.3-A", { ARCH_V8r3, profile_CortexA } },
+    { "ARMv8-R", { ARCH_V8, profile_CortexR } },
+    { "ARMv8-M", { ARCH_V8, profile_CortexM } },
+};
+
 CoreArchProfileMap::CoreArchProfileMap()
 {
-    for(unsigned i = 0; i < sizeof(ap_map_array)/sizeof(_ap_map_elements); i++)
+    unsigned i;
+    for (i = 0; i < sizeof(ap_map_array) / sizeof(_ap_map_elements); i++)
     {
         core_profiles[ap_map_array[i].name] = ap_map_array[i].ap;
     }
+    for (i = 0; i < sizeof(arch_map_array) / sizeof(_ap_map_elements); i++)
+    {
+        arch_profiles[arch_map_array[i].name] = arch_map_array[i].ap;
+    }
 }
 
 /* End of File trc_core_arch_map.cpp */
diff --git a/decoder/tests/run_capi_test.bash b/decoder/tests/run_capi_test.bash
new file mode 100755
index 0000000..bac5da4
--- /dev/null
+++ b/decoder/tests/run_capi_test.bash
@@ -0,0 +1,54 @@
+#!/bin/bash
+#################################################################################
+# Copyright 2018 ARM. 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. 
+# 
+#################################################################################
+# OpenCSD library: Test script.
+#
+# Test script to run packet lister on each of the snapshots retained with the repository.
+# No attempt is made to compare output results to previous versions,  (output formatting
+# may change due to bugfix / enhancements) or assess the validity  of the trace output.
+#
+#################################################################################
+
+OUT_DIR=./results
+SNAPSHOT_DIR=./snapshots
+BIN_DIR=./bin/linux64/rel
+
+echo "Running trc_pkt_lister on snapshot directories."
+
+mkdir -p ${OUT_DIR}
+
+# === test the decode set ===
+export LD_LIBRARY_PATH=${BIN_DIR}/.
+
+
+# === test the C-API lib ===
+echo "Testing C-API"
+${BIN_DIR}/c_api_pkt_print_test -ss_path ${SNAPSHOT_DIR} -decode
+mv ./c_api_test.log ./${OUT_DIR}/c_api_test.ppl
diff --git a/decoder/tests/run_pkt_decode_tests.bash b/decoder/tests/run_pkt_decode_tests.bash
index 56b1cbf..ba23923 100755
--- a/decoder/tests/run_pkt_decode_tests.bash
+++ b/decoder/tests/run_pkt_decode_tests.bash
@@ -76,3 +76,8 @@
 echo "Testing a55-test-tpiu..."
 ${BIN_DIR}/trc_pkt_lister -ss_dir "${SNAPSHOT_DIR}/a55-test-tpiu" -dstream_format -o_raw_packed -o_raw_unpacked -logfilename "${OUT_DIR}/a55-test-tpiu.ppl"
 echo "Done : Return $?"
+
+# === test the C-API lib ===
+echo "Testing C-API library"
+${BIN_DIR}/c_api_pkt_print_test -ss_path ${SNAPSHOT_DIR} -decode
+mv ./c_api_test.log ./${OUT_DIR}/c_api_test.ppl