Upgrade OpenCSD to v0.14.2 am: b13c2dbf79 am: 6ba5c92fc4

Original change: https://android-review.googlesource.com/c/platform/external/OpenCSD/+/1340176

Change-Id: I88b567bf4140422b9167170ac48c273cdd7b3572
diff --git a/METADATA b/METADATA
index 7f44ac2..98fd3bc 100644
--- a/METADATA
+++ b/METADATA
@@ -9,11 +9,11 @@
     type: GIT
     value: "https://github.com/Linaro/OpenCSD.git"
   }
-  version: "v0.14.1"
+  version: "v0.14.2"
   license_type: RESTRICTED
   last_upgrade_date {
     year: 2020
-    month: 4
-    day: 27
+    month: 6
+    day: 17
   }
 }
diff --git a/README.md b/README.md
index c557523..b8b13d5 100644
--- a/README.md
+++ b/README.md
@@ -27,7 +27,7 @@
 CoreSight Trace Component Support.
 ----------------------------------
 
-_Current Version 0.14.1_
+_Current Version 0.14.2_
 
 ### Current support:
 
@@ -204,6 +204,13 @@
     - __Update__: ETMv4 - Add support for Q elements.
     - __Bugfix__: build: fix logic issue for && operator. (github issue #23, sumitted by yabinc)
 
+- _Version 0.14.2_: 
+    - __Update__: Architecture versioning. Set enum tag values to make conversion to numeric version easier.
+    - __Update__: I-decode: remove global temporary decode state data and replace with local instance data
+                  to make library more easily usable in multi-threaded programs.
+    - __Bugfix__: I-decode: Some Thumb instructions not correctly reported as implied returns.
+                  (github issue #24, submitted by kongy).
+
 
 Licence Information
 ===================
diff --git a/decoder/docs/doxygen_config.dox b/decoder/docs/doxygen_config.dox
index 101c59e..3913d3a 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.14.1
+PROJECT_NUMBER         = 0.14.2
 
 # 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/include/i_dec/trc_i_decode.h b/decoder/include/i_dec/trc_i_decode.h
index 0285f41..d519a3a 100644
--- a/decoder/include/i_dec/trc_i_decode.h
+++ b/decoder/include/i_dec/trc_i_decode.h
@@ -46,10 +46,9 @@
     virtual ocsd_err_t DecodeInstruction(ocsd_instr_info *instr_info);
 
 private:
-    ocsd_err_t DecodeA32(ocsd_instr_info *instr_info);
-    ocsd_err_t DecodeA64(ocsd_instr_info *instr_info);
-    ocsd_err_t DecodeT32(ocsd_instr_info *instr_info);
-    void SetArchVersion(ocsd_instr_info *instr_info);
+    ocsd_err_t DecodeA32(ocsd_instr_info *instr_info, struct decode_info *info);
+    ocsd_err_t DecodeA64(ocsd_instr_info *instr_info, struct decode_info *info);
+    ocsd_err_t DecodeT32(ocsd_instr_info *instr_info, struct decode_info *info);
 };
 
 #endif // ARM_TRC_I_DECODE_H_INCLUDED
diff --git a/decoder/include/i_dec/trc_idec_arminst.h b/decoder/include/i_dec/trc_idec_arminst.h
index 8697f68..911b0cf 100644
--- a/decoder/include/i_dec/trc_idec_arminst.h
+++ b/decoder/include/i_dec/trc_idec_arminst.h
@@ -42,6 +42,12 @@
 #include "opencsd/ocsd_if_types.h"
 #include <cstdint>
 
+/* supplementary decode information */
+struct decode_info {
+    uint16_t arch_version;
+    ocsd_instr_subtype instr_sub_type;
+};
+
 /*
 For Thumb2, test if a halfword is the first half of a 32-bit instruction,
 as opposed to a complete 16-bit instruction.
@@ -63,19 +69,19 @@
 instructions such as SVC, HVC and SMC.
 (Performance event 0x0C includes these.)
 */
-int inst_ARM_is_branch(uint32_t inst);
-int inst_Thumb_is_branch(uint32_t inst);
-int inst_A64_is_branch(uint32_t inst);
+int inst_ARM_is_branch(uint32_t inst, struct decode_info *info);
+int inst_Thumb_is_branch(uint32_t inst, struct decode_info *info);
+int inst_A64_is_branch(uint32_t inst, struct decode_info *info);
 
 /*
 Test whether an instruction is a direct (aka immediate) branch.
 Performance event 0x0D counts these.
 */
 int inst_ARM_is_direct_branch(uint32_t inst);
-int inst_Thumb_is_direct_branch(uint32_t inst);
-int inst_Thumb_is_direct_branch_link(uint32_t inst, uint8_t *is_link, uint8_t *is_cond);
-int inst_A64_is_direct_branch(uint32_t inst);
-int inst_A64_is_direct_branch_link(uint32_t inst, uint8_t *is_link);
+int inst_Thumb_is_direct_branch(uint32_t inst, struct decode_info *info);
+int inst_Thumb_is_direct_branch_link(uint32_t inst, uint8_t *is_link, uint8_t *is_cond, struct decode_info *info);
+int inst_A64_is_direct_branch(uint32_t inst, struct decode_info *info);
+int inst_A64_is_direct_branch_link(uint32_t inst, uint8_t *is_link, struct decode_info *info);
 
 /*
 Get branch destination for a direct branch.
@@ -84,15 +90,15 @@
 int inst_Thumb_branch_destination(uint32_t addr, uint32_t inst, uint32_t *pnpc);
 int inst_A64_branch_destination(uint64_t addr, uint32_t inst, uint64_t *pnpc);
 
-int inst_ARM_is_indirect_branch(uint32_t inst);
-int inst_Thumb_is_indirect_branch_link(uint32_t inst, uint8_t *is_link);
-int inst_Thumb_is_indirect_branch(uint32_t inst);
-int inst_A64_is_indirect_branch_link(uint32_t inst, uint8_t *is_link);
-int inst_A64_is_indirect_branch(uint32_t inst);
+int inst_ARM_is_indirect_branch(uint32_t inst, struct decode_info *info);
+int inst_Thumb_is_indirect_branch_link(uint32_t inst, uint8_t *is_link, struct decode_info *info);
+int inst_Thumb_is_indirect_branch(uint32_t inst, struct decode_info *info);
+int inst_A64_is_indirect_branch_link(uint32_t inst, uint8_t *is_link, struct decode_info *info);
+int inst_A64_is_indirect_branch(uint32_t inst, struct decode_info *info);
 
-int inst_ARM_is_branch_and_link(uint32_t inst);
-int inst_Thumb_is_branch_and_link(uint32_t inst);
-int inst_A64_is_branch_and_link(uint32_t inst);
+int inst_ARM_is_branch_and_link(uint32_t inst, struct decode_info *info);
+int inst_Thumb_is_branch_and_link(uint32_t inst, struct decode_info *info);
+int inst_A64_is_branch_and_link(uint32_t inst, struct decode_info *info);
 
 int inst_ARM_is_conditional(uint32_t inst);
 int inst_Thumb_is_conditional(uint32_t inst);
@@ -128,14 +134,6 @@
 int inst_Thumb_is_UDF(uint32_t inst);
 int inst_A64_is_UDF(uint32_t inst);
 
-
-/* access sub-type information */
-ocsd_instr_subtype get_instr_subtype();
-void clear_instr_subtype();
-
-/* set arch version info. */
-void set_arch_version(uint16_t version);
-
 #endif // ARM_TRC_IDEC_ARMINST_H_INCLUDED
 
 /* End of File trc_idec_arminst.h */
diff --git a/decoder/include/mem_acc/trc_mem_acc_bufptr.h b/decoder/include/mem_acc/trc_mem_acc_bufptr.h
index bd9ea8e..b6208a7 100644
--- a/decoder/include/mem_acc/trc_mem_acc_bufptr.h
+++ b/decoder/include/mem_acc/trc_mem_acc_bufptr.h
@@ -68,7 +68,6 @@
 
 private:
     const uint8_t *m_p_buffer;  /**< pointer to the memory buffer  */
-    const uint32_t m_size;  /**< size of the memory buffer. */
 };
 
 #endif // ARM_TRC_MEM_ACC_BUFPTR_H_INCLUDED
diff --git a/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h b/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h
index 826554e..419cd82 100644
--- a/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h
+++ b/decoder/include/opencsd/etmv4/trc_pkt_decode_etmv4i.h
@@ -211,7 +211,6 @@
 
     ocsd_instr_info m_instr_info;  //!< instruction info for code follower - in address is the next to be decoded.
 
-    ocsd_pe_context m_pe_context;  //!< current context information
     etmv4_trace_info_t m_trace_info; //!< trace info for this trace run.
 
     bool m_prev_overflow;
diff --git a/decoder/include/opencsd/ocsd_if_types.h b/decoder/include/opencsd/ocsd_if_types.h
index 1c0e631..23087ee 100644
--- a/decoder/include/opencsd/ocsd_if_types.h
+++ b/decoder/include/opencsd/ocsd_if_types.h
@@ -273,11 +273,11 @@
 
 /** Core Architecture Version */
 typedef enum _ocsd_arch_version {
-    ARCH_UNKNOWN,   /**< unknown architecture */
-    ARCH_CUSTOM,    /**< None ARM, custom architecture */
-    ARCH_V7,        /**< V7 architecture */
-    ARCH_V8,        /**< V8 architecture */
-    ARCH_V8r3,      /**< V8.3 architecture */
+    ARCH_UNKNOWN = 0x0000,   /**< unknown architecture */
+    ARCH_CUSTOM = 0x0001,    /**< None ARM, custom architecture */
+    ARCH_V7 = 0x0700,        /**< V7 architecture */
+    ARCH_V8 = 0x0800,        /**< V8 architecture */
+    ARCH_V8r3 = 0x0803,      /**< V8.3 architecture */
 } ocsd_arch_version_t;
 
 // macros for arch version comparisons.
diff --git a/decoder/include/opencsd/ocsd_if_version.h b/decoder/include/opencsd/ocsd_if_version.h
index 609a4e1..38baa02 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 0xE /**< Library Minor Version */
-#define OCSD_VER_PATCH 0x1 /**< Library Patch Version */
+#define OCSD_VER_PATCH 0x2 /**< 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.14.1"    /**< Library Version string */
+#define OCSD_VER_STRING "0.14.2"    /**< 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/i_dec/trc_i_decode.cpp b/decoder/source/i_dec/trc_i_decode.cpp
index ab93284..614fc1d 100644
--- a/decoder/source/i_dec/trc_i_decode.cpp
+++ b/decoder/source/i_dec/trc_i_decode.cpp
@@ -39,21 +39,23 @@
 ocsd_err_t TrcIDecode::DecodeInstruction(ocsd_instr_info *instr_info)
 {
     ocsd_err_t err = OCSD_OK;
-    clear_instr_subtype();
-    SetArchVersion(instr_info);
+    struct decode_info info;
+
+    info.instr_sub_type = OCSD_S_INSTR_NONE;
+    info.arch_version = (uint16_t)(instr_info->pe_type.arch);
 
     switch(instr_info->isa)
     {
     case ocsd_isa_arm:
-        err = DecodeA32(instr_info);
+        err = DecodeA32(instr_info, &info);
         break;
 
     case ocsd_isa_thumb2:
-        err = DecodeT32(instr_info);
+        err = DecodeT32(instr_info, &info);
         break;
 
     case ocsd_isa_aarch64:
-        err = DecodeA64(instr_info);
+        err = DecodeA64(instr_info, &info);
         break;
 
     case ocsd_isa_tee:    
@@ -63,27 +65,11 @@
         err = OCSD_ERR_UNSUPPORTED_ISA;
         break;
     }
-    instr_info->sub_type = get_instr_subtype();
+    instr_info->sub_type = info.instr_sub_type;
     return err;
 }
 
-void TrcIDecode::SetArchVersion(ocsd_instr_info *instr_info)
-{
-    uint16_t arch = 0x0700;
-
-    switch (instr_info->pe_type.arch)
-    {
-    case ARCH_V8: arch = 0x0800; break;
-    case ARCH_V8r3: arch = 0x0803; break;
-    case ARCH_V7:
-    default:
-        break;
-    }
-    set_arch_version(arch);
-}
-
-
-ocsd_err_t TrcIDecode::DecodeA32(ocsd_instr_info *instr_info)
+ocsd_err_t TrcIDecode::DecodeA32(ocsd_instr_info *instr_info, struct decode_info *info)
 {
     uint32_t branchAddr = 0;
     arm_barrier_t barrier;
@@ -93,10 +79,10 @@
     instr_info->next_isa = instr_info->isa; // assume same ISA 
     instr_info->is_link = 0;
 
-    if(inst_ARM_is_indirect_branch(instr_info->opcode))
+    if(inst_ARM_is_indirect_branch(instr_info->opcode, info))
     {
         instr_info->type = OCSD_INSTR_BR_INDIRECT;
-        instr_info->is_link = inst_ARM_is_branch_and_link(instr_info->opcode);
+        instr_info->is_link = inst_ARM_is_branch_and_link(instr_info->opcode, info);
     }
     else if(inst_ARM_is_direct_branch(instr_info->opcode))
     {
@@ -108,7 +94,7 @@
             branchAddr &= ~0x1;
         }
         instr_info->branch_addr = (ocsd_vaddr_t)branchAddr;
-        instr_info->is_link = inst_ARM_is_branch_and_link(instr_info->opcode);
+        instr_info->is_link = inst_ARM_is_branch_and_link(instr_info->opcode, info);
     }
     else if((barrier = inst_ARM_barrier(instr_info->opcode)) != ARM_BARRIER_NONE)
     {
@@ -137,7 +123,7 @@
     return OCSD_OK;
 }
 
-ocsd_err_t TrcIDecode::DecodeA64(ocsd_instr_info *instr_info)
+ocsd_err_t TrcIDecode::DecodeA64(ocsd_instr_info *instr_info, struct decode_info *info)
 {
     uint64_t branchAddr = 0;
     arm_barrier_t barrier;
@@ -147,12 +133,12 @@
     instr_info->next_isa = instr_info->isa; // assume same ISA 
     instr_info->is_link = 0;
     
-    if(inst_A64_is_indirect_branch_link(instr_info->opcode, &instr_info->is_link))
+    if(inst_A64_is_indirect_branch_link(instr_info->opcode, &instr_info->is_link, info))
     {
         instr_info->type = OCSD_INSTR_BR_INDIRECT;
 //        instr_info->is_link = inst_A64_is_branch_and_link(instr_info->opcode);
     }
-    else if(inst_A64_is_direct_branch_link(instr_info->opcode, &instr_info->is_link))
+    else if(inst_A64_is_direct_branch_link(instr_info->opcode, &instr_info->is_link, info))
     {
         inst_A64_branch_destination(instr_info->instr_addr,instr_info->opcode,&branchAddr);
         instr_info->type = OCSD_INSTR_BR;
@@ -187,7 +173,7 @@
     return OCSD_OK;
 }
 
-ocsd_err_t TrcIDecode::DecodeT32(ocsd_instr_info *instr_info)
+ocsd_err_t TrcIDecode::DecodeT32(ocsd_instr_info *instr_info, struct decode_info *info)
 {
     uint32_t branchAddr = 0;
     arm_barrier_t barrier;
@@ -206,7 +192,7 @@
     instr_info->is_conditional = 0;
 
 
-    if(inst_Thumb_is_direct_branch_link(instr_info->opcode,&instr_info->is_link, &instr_info->is_conditional))
+    if(inst_Thumb_is_direct_branch_link(instr_info->opcode,&instr_info->is_link, &instr_info->is_conditional, info))
     {
         inst_Thumb_branch_destination((uint32_t)instr_info->instr_addr,instr_info->opcode,&branchAddr);
         instr_info->type = OCSD_INSTR_BR;
@@ -214,7 +200,7 @@
         if((branchAddr & 0x1) == 0)
             instr_info->next_isa = ocsd_isa_arm;
     }
-    else if (inst_Thumb_is_indirect_branch_link(instr_info->opcode, &instr_info->is_link))
+    else if (inst_Thumb_is_indirect_branch_link(instr_info->opcode, &instr_info->is_link, info))
     {
         instr_info->type = OCSD_INSTR_BR_INDIRECT;
     }
@@ -246,5 +232,4 @@
     return OCSD_OK;
 }
 
-
 /* End of File trc_i_decode.cpp */
diff --git a/decoder/source/i_dec/trc_idec_arminst.cpp b/decoder/source/i_dec/trc_idec_arminst.cpp
index eb52ec8..3652e84 100644
--- a/decoder/source/i_dec/trc_idec_arminst.cpp
+++ b/decoder/source/i_dec/trc_idec_arminst.cpp
@@ -42,27 +42,6 @@
 #include <stddef.h>  /* for NULL */
 #include <assert.h>
 
-
-static ocsd_instr_subtype instr_sub_type = OCSD_S_INSTR_NONE;
-
-/* need to spot the architecture version for certain instructions */
-static uint16_t arch_version = 0x70;
-
-ocsd_instr_subtype get_instr_subtype()
-{
-    return instr_sub_type;
-}
-
-void clear_instr_subtype()
-{
-    instr_sub_type = OCSD_S_INSTR_NONE;
-}
-
-void set_arch_version(uint16_t version)
-{
-    arch_version = version;
-}
-
 int inst_ARM_is_direct_branch(uint32_t inst)
 {
     int is_direct_branch = 1;
@@ -91,7 +70,7 @@
     return 0;
 }
 
-int inst_ARM_is_indirect_branch(uint32_t inst)
+int inst_ARM_is_indirect_branch(uint32_t inst, struct decode_info *info)
 {
     int is_indirect_branch = 1;
     if ((inst & 0xf0000000) == 0xf0000000) {
@@ -104,23 +83,23 @@
     } else if ((inst & 0x0ff000d0) == 0x01200010) {
         /* BLX (register), BX */
         if ((inst & 0xFF) == 0x1E)
-            instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* BX LR */
+            info->instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* BX LR */
     } else if ((inst & 0x0ff000f0) == 0x01200020) {
         /* BXJ: in v8 this behaves like BX */
     } else if ((inst & 0x0e108000) == 0x08108000) {
         /* POP {...,pc} or LDMxx {...,pc} */
         if ((inst & 0x0FFFA000) == 0x08BD8000) /* LDMIA SP!,{...,pc} */
-            instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET;
+            info->instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET;
     } else if ((inst & 0x0e50f000) == 0x0410f000) {
         /* LDR PC,imm... inc. POP {PC} */
         if ( (inst & 0x01ff0000) == 0x009D0000)
-            instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* LDR PC, [SP], #imm */
+            info->instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* LDR PC, [SP], #imm */
     } else if ((inst & 0x0e50f010) == 0x0610f000) {
         /* LDR PC,reg */
     } else if ((inst & 0x0fe0f000) == 0x01a0f000) {
         /* MOV PC,rx */
         if ((inst & 0x00100FFF) == 0x00E) /* ensure the S=0, LSL #0 variant - i.e plain MOV */
-            instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* MOV PC, R14 */
+            info->instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* MOV PC, R14 */
     } else if ((inst & 0x0f900080) == 0x01000000) {
         /* "Miscellaneous instructions" - in DP space */
         is_indirect_branch = 0;
@@ -144,13 +123,13 @@
     return is_indirect_branch;
 }
 
-int inst_Thumb_is_direct_branch(uint32_t inst)
+int inst_Thumb_is_direct_branch(uint32_t inst, struct decode_info *info)
 {
     uint8_t link, cond;
-    return inst_Thumb_is_direct_branch_link(inst, &link, &cond);
+    return inst_Thumb_is_direct_branch_link(inst, &link, &cond, info);
 }
 
-int inst_Thumb_is_direct_branch_link(uint32_t inst, uint8_t *is_link, uint8_t *is_cond)
+int inst_Thumb_is_direct_branch_link(uint32_t inst, uint8_t *is_link, uint8_t *is_cond, struct decode_info *info)
 {
     int is_direct_branch = 1;
 
@@ -166,12 +145,12 @@
         /* B (encoding T4); BL (encoding T1) */
         if (inst & 0x00004000) {
             *is_link = 1;
-            instr_sub_type = OCSD_S_INSTR_BR_LINK;
+            info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
         }
     } else if ((inst & 0xf800d001) == 0xf000c000) {
         /* BLX (imm) (encoding T2) */
         *is_link = 1;
-        instr_sub_type = OCSD_S_INSTR_BR_LINK;
+        info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
     } else if ((inst & 0xf5000000) == 0xb1000000) {
         /* CB(NZ) */
         *is_cond = 1;
@@ -197,13 +176,13 @@
     return is_wfiwfe;
 }
 
-int inst_Thumb_is_indirect_branch(uint32_t inst)
+int inst_Thumb_is_indirect_branch(uint32_t inst, struct decode_info *info)
 {
     uint8_t link;
-    return inst_Thumb_is_indirect_branch_link(inst, &link);
+    return inst_Thumb_is_indirect_branch_link(inst, &link, info);
 }
 
-int inst_Thumb_is_indirect_branch_link(uint32_t inst, uint8_t *is_link)
+int inst_Thumb_is_indirect_branch_link(uint32_t inst, uint8_t *is_link, struct decode_info *info)
 {
     /* See e.g. PFT Table 2-3 and Table 2-5 */
     int is_branch = 1;
@@ -212,20 +191,20 @@
         /* BX, BLX (reg) [v8M includes BXNS, BLXNS] */
         if (inst & 0x00800000) {
             *is_link = 1;
-            instr_sub_type = OCSD_S_INSTR_BR_LINK;
+            info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
         }
         else if ((inst & 0x00780000) == 0x00700000) {
-            instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET;  /* BX LR */
+            info->instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET;  /* BX LR */
         }
     } else if ((inst & 0xfff0d000) == 0xf3c08000) {
         /* BXJ: in v8 this behaves like BX */
     } else if ((inst & 0xff000000) == 0xbd000000) {
         /* POP {pc} */
-        instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET;
+        info->instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET;
     } else if ((inst & 0xfd870000) == 0x44870000) {
         /* MOV PC,reg or ADD PC,reg */
-        if ((inst & 0xffff0000) == 0x46f700000)
-            instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* MOV PC,LR */
+        if ((inst & 0xffff0000) == 0x46f70000)
+            info->instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* MOV PC,LR */
     } else if ((inst & 0xfff0ffe0) == 0xe8d0f000) {
         /* TBB/TBH */
     } else if ((inst & 0xffd00000) == 0xe8100000) {
@@ -241,26 +220,26 @@
     } else if ((inst & 0xfff0f800) == 0xf850f800) {
         /* LDR PC,imm (T4) */
         if((inst & 0x000f0f00) == 0x000d0b00)
-            instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* LDR PC, [SP], #imm*/
+            info->instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* LDR PC, [SP], #imm*/
     } else if ((inst & 0xfff0ffc0) == 0xf850f000) {
         /* LDR PC,reg (T2) */
     } else if ((inst & 0xfe508000) == 0xe8108000) {
         /* LDM PC */
         if ((inst & 0x0FFF0000) == 0x08BD0000) /* LDMIA [SP]!, */
-            instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* POP {...,pc} */
+            info->instr_sub_type = OCSD_S_INSTR_V7_IMPLIED_RET; /* POP {...,pc} */
     } else {
         is_branch = 0;
     }
     return is_branch;
 }
 
-int inst_A64_is_direct_branch(uint32_t inst)
+int inst_A64_is_direct_branch(uint32_t inst, struct decode_info *info)
 {
     uint8_t link = 0;
-    return inst_A64_is_direct_branch_link(inst, &link);
+    return inst_A64_is_direct_branch_link(inst, &link, info);
 }
 
-int inst_A64_is_direct_branch_link(uint32_t inst, uint8_t *is_link)
+int inst_A64_is_direct_branch_link(uint32_t inst, uint8_t *is_link, struct decode_info *info)
 {
     int is_direct_branch = 1;
     if ((inst & 0x7c000000) == 0x34000000) {
@@ -271,7 +250,7 @@
         /* B, BL imm */
         if (inst & 0x80000000) {
             *is_link = 1;
-            instr_sub_type = OCSD_S_INSTR_BR_LINK;
+            info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
         }
     } else {
         is_direct_branch = 0;
@@ -287,13 +266,13 @@
     return 0;
 }
 
-int inst_A64_is_indirect_branch(uint32_t inst)
+int inst_A64_is_indirect_branch(uint32_t inst, struct decode_info *info)
 {
     uint8_t link = 0;
-    return inst_A64_is_indirect_branch_link(inst, &link);
+    return inst_A64_is_indirect_branch_link(inst, &link, info);
 }
 
-int inst_A64_is_indirect_branch_link(uint32_t inst, uint8_t *is_link)
+int inst_A64_is_indirect_branch_link(uint32_t inst, uint8_t *is_link, struct decode_info *info)
 {
     int is_indirect_branch = 1;
 
@@ -301,34 +280,34 @@
         /* BR, BLR */
         if (inst & 0x00200000) {
             *is_link = 1;
-            instr_sub_type = OCSD_S_INSTR_BR_LINK;
+            info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
         }
     } else if ((inst & 0xfffffc1f) == 0xd65f0000) {
-        instr_sub_type = OCSD_S_INSTR_V8_RET;
+        info->instr_sub_type = OCSD_S_INSTR_V8_RET;
         /* RET */
     } else if ((inst & 0xffffffff) == 0xd69f03e0) {
         /* ERET */
-        instr_sub_type = OCSD_S_INSTR_V8_ERET;
-    } else if (arch_version >= 0x0803) {
+        info->instr_sub_type = OCSD_S_INSTR_V8_ERET;
+    } else if (info->arch_version >= 0x0803) {
         /* new pointer auth instr for v8.3 arch */   
         if ((inst & 0xffdff800) == 0xd71f0800) {
             /* BRAA, BRAB, BLRAA, BLRBB */
             if (inst & 0x00200000) {
                 *is_link = 1;
-                instr_sub_type = OCSD_S_INSTR_BR_LINK;
+                info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
             }
         } else if ((inst & 0xffdff81F) == 0xd61f081F) {
             /* BRAAZ, BRABZ, BLRAAZ, BLRBBZ */
             if (inst & 0x00200000) {
                 *is_link = 1;
-                instr_sub_type = OCSD_S_INSTR_BR_LINK;
+                info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
             }
         } else if ((inst & 0xfffffbff) == 0xd69f0bff) {
             /* ERETAA, ERETAB */
-            instr_sub_type = OCSD_S_INSTR_V8_ERET;
+            info->instr_sub_type = OCSD_S_INSTR_V8_ERET;
         } else if ((inst & 0xfffffbff) == 0xd65f0bff) {
             /* RETAA, RETAB */
-            instr_sub_type = OCSD_S_INSTR_V8_RET;
+            info->instr_sub_type = OCSD_S_INSTR_V8_RET;
         } else {
             is_indirect_branch = 0;
         }
@@ -441,39 +420,39 @@
     return is_direct_branch;
 }
 
-int inst_ARM_is_branch(uint32_t inst)
+int inst_ARM_is_branch(uint32_t inst, struct decode_info *info)
 {
-    return inst_ARM_is_indirect_branch(inst) ||
+    return inst_ARM_is_indirect_branch(inst, info) ||
            inst_ARM_is_direct_branch(inst);
 }
 
-int inst_Thumb_is_branch(uint32_t inst)
+int inst_Thumb_is_branch(uint32_t inst, struct decode_info *info)
 {
-    return inst_Thumb_is_indirect_branch(inst) ||
-           inst_Thumb_is_direct_branch(inst);
+    return inst_Thumb_is_indirect_branch(inst, info) ||
+           inst_Thumb_is_direct_branch(inst, info);
 }
 
-int inst_A64_is_branch(uint32_t inst)
+int inst_A64_is_branch(uint32_t inst, struct decode_info *info)
 {
-    return inst_A64_is_indirect_branch(inst) ||
-           inst_A64_is_direct_branch(inst);
+    return inst_A64_is_indirect_branch(inst, info) ||
+           inst_A64_is_direct_branch(inst, info);
 }
 
-int inst_ARM_is_branch_and_link(uint32_t inst)
+int inst_ARM_is_branch_and_link(uint32_t inst, struct decode_info *info)
 {
     int is_branch = 1;
     if ((inst & 0xf0000000) == 0xf0000000) {
         if ((inst & 0xfe000000) == 0xfa000000){
-            instr_sub_type = OCSD_S_INSTR_BR_LINK;
+            info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
             /* BLX (imm) */
         } else {
             is_branch = 0;
         }
     } else if ((inst & 0x0f000000) == 0x0b000000) {
-        instr_sub_type = OCSD_S_INSTR_BR_LINK;
+        info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
         /* BL */
     } else if ((inst & 0x0ff000f0) == 0x01200030) {
-        instr_sub_type = OCSD_S_INSTR_BR_LINK;
+        info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
         /* BLX (reg) */
     } else {
         is_branch = 0;
@@ -481,14 +460,14 @@
     return is_branch;
 }
 
-int inst_Thumb_is_branch_and_link(uint32_t inst)
+int inst_Thumb_is_branch_and_link(uint32_t inst, struct decode_info *info)
 {
     int is_branch = 1;
     if ((inst & 0xff800000) == 0x47800000) {
-        instr_sub_type = OCSD_S_INSTR_BR_LINK;
+        info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
         /* BLX (reg) */
     } else if ((inst & 0xf800c000) == 0xf000c000) {
-        instr_sub_type = OCSD_S_INSTR_BR_LINK;
+        info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
         /* BL, BLX (imm) */
     } else {
         is_branch = 0;
@@ -496,23 +475,23 @@
     return is_branch;
 }
 
-int inst_A64_is_branch_and_link(uint32_t inst)
+int inst_A64_is_branch_and_link(uint32_t inst, struct decode_info *info)
 {
     int is_branch = 1;
     if ((inst & 0xfffffc1f) == 0xd63f0000) {
         /* BLR */
-        instr_sub_type = OCSD_S_INSTR_BR_LINK;
+        info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
     } else if ((inst & 0xfc000000) == 0x94000000) {
         /* BL */
-        instr_sub_type = OCSD_S_INSTR_BR_LINK;
-    }  else if (arch_version >= 0x0803) {
+        info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
+    }  else if (info->arch_version >= 0x0803) {
         /* new pointer auth instr for v8.3 arch */
         if ((inst & 0xfffff800) == 0xd73f0800) {
             /* BLRAA, BLRBB */
-            instr_sub_type = OCSD_S_INSTR_BR_LINK;
+            info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
         } else if ((inst & 0xfffff81F) == 0xd63f081F) {
             /* BLRAAZ, BLRBBZ */
-            instr_sub_type = OCSD_S_INSTR_BR_LINK;
+            info->instr_sub_type = OCSD_S_INSTR_BR_LINK;
         } else {
             is_branch = 0;
         }
diff --git a/decoder/source/mem_acc/trc_mem_acc_bufptr.cpp b/decoder/source/mem_acc/trc_mem_acc_bufptr.cpp
index 25c7363..7ecd3b0 100644
--- a/decoder/source/mem_acc/trc_mem_acc_bufptr.cpp
+++ b/decoder/source/mem_acc/trc_mem_acc_bufptr.cpp
@@ -37,8 +37,7 @@
 
 TrcMemAccBufPtr::TrcMemAccBufPtr(const ocsd_vaddr_t s_address, const uint8_t *p_buffer, const uint32_t size) : 
     TrcMemAccessorBase(MEMACC_BUFPTR, s_address, s_address+size-1),
-    m_p_buffer(p_buffer),
-    m_size(size)
+    m_p_buffer(p_buffer)
 {
 }
 
diff --git a/decoder/source/ocsd_error.cpp b/decoder/source/ocsd_error.cpp
index 251964b..74e9e49 100644
--- a/decoder/source/ocsd_error.cpp
+++ b/decoder/source/ocsd_error.cpp
@@ -207,7 +207,7 @@
 
 void ocsdError::appendErrorDetails(std::string &errStr, const ocsdError &error)
 {
-    int numerrstr = ((sizeof(s_errorCodeDescs) / sizeof(const char *)) / 2);
+    int numerrstr = sizeof(s_errorCodeDescs) / sizeof(s_errorCodeDescs[0]);
     int code = (int)error.getErrorCode();
     ocsd_trc_index_t idx = error.getErrorIndex();
     uint8_t chan_ID = error.getErrorChanID();
diff --git a/decoder/source/trc_gen_elem.cpp b/decoder/source/trc_gen_elem.cpp
index 544f906..e177420 100644
--- a/decoder/source/trc_gen_elem.cpp
+++ b/decoder/source/trc_gen_elem.cpp
@@ -109,7 +109,7 @@
 void OcsdTraceElement::toString(std::string &str) const
 {
     std::ostringstream oss;
-    int num_str = ((sizeof(s_elem_descs) / sizeof(const char *)) / 2);
+    int num_str = sizeof(s_elem_descs) / sizeof(s_elem_descs[0]);
     int typeIdx = (int)this->elem_type;
     if(typeIdx < num_str)
     {
diff --git a/decoder/tests/run_pkt_decode_tests.bash b/decoder/tests/run_pkt_decode_tests.bash
index c9b4aee..09f642b 100755
--- a/decoder/tests/run_pkt_decode_tests.bash
+++ b/decoder/tests/run_pkt_decode_tests.bash
@@ -35,10 +35,20 @@
 # may change due to bugfix / enhancements) or assess the validity  of the trace output.
 #
 #################################################################################
+# Usage options:-
+# * default: run tests on binary + libs in ./bin/linux64/rel
+# run_pkt_decode_tests.bash
+#
+# * use installed opencsd libraries & program
+# run_pkt_decode_tests.bash use-installed
+#
+# * use supplied path for binary + libs (must have trailing /)
+# run_pkt_decode_tests.bash <custom>/<path>/
+#
 
 OUT_DIR=./results
 SNAPSHOT_DIR=./snapshots
-BIN_DIR=./bin/linux64/rel
+BIN_DIR=./bin/linux64/rel/
 
 # directories for tests using full decode
 declare -a test_dirs_decode=( "juno-ret-stck"
@@ -62,28 +72,41 @@
 
 mkdir -p ${OUT_DIR}
 
-# === test the decode set ===
-export LD_LIBRARY_PATH=${BIN_DIR}/.
+if [ "$1" == "use-installed" ]; then
+    BIN_DIR=""
+elif [ "$1" != "" ]; then
+    BIN_DIR=$1
+fi
 
+echo "Tests using BIN_DIR = ${BIN_DIR}"
+
+if [ "${BIN_DIR}" != "" ]; then
+    export LD_LIBRARY_PATH=${BIN_DIR}.
+    echo "LD_LIBRARY_PATH set to ${BIN_DIR}"
+fi
+
+# === test the decode set ===
 for test_dir in "${test_dirs_decode[@]}"
 do
     echo "Testing $test_dir..."
-    ${BIN_DIR}/trc_pkt_lister -ss_dir "${SNAPSHOT_DIR}/$test_dir" -decode -logfilename "${OUT_DIR}/$test_dir.ppl"
+    ${BIN_DIR}trc_pkt_lister -ss_dir "${SNAPSHOT_DIR}/$test_dir" -decode -logfilename "${OUT_DIR}/$test_dir.ppl"
     echo "Done : Return $?"
 done
 
 # === test a packet only example ===
 echo "Testing init-short-addr..."
-${BIN_DIR}/trc_pkt_lister -ss_dir "${SNAPSHOT_DIR}/init-short-addr" -pkt_mon -logfilename "${OUT_DIR}/init-short-addr.ppl"
+${BIN_DIR}trc_pkt_lister -ss_dir "${SNAPSHOT_DIR}/init-short-addr" -pkt_mon -logfilename "${OUT_DIR}/init-short-addr.ppl"
 
 # === test the TPIU deformatter ===
 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"
+${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 > /dev/null
-echo "Done : Return $?"
-echo "moving result file."
-mv ./c_api_test.log ./${OUT_DIR}/c_api_test.ppl
+# === test the C-API lib - this test prog is not installed ===
+if [ "$1" != "use-installed" ]; then
+    echo "Testing C-API library"
+    ${BIN_DIR}c_api_pkt_print_test -ss_path ${SNAPSHOT_DIR} -decode > /dev/null
+    echo "Done : Return $?"
+    echo "moving result file."
+    mv ./c_api_test.log ./${OUT_DIR}/c_api_test.ppl
+fi