From 3a7f96b5d0de7ec3a72a936ef817b8fb80b5e6ba Mon Sep 17 00:00:00 2001
From: Jason Hiser <jdhiser@gmail.com>
Date: Mon, 22 Jul 2019 14:24:33 -0400
Subject: [PATCH] Prelim support for zafl/zunracer edge instrumentation

---
 SMPStaticAnalyzer                             |   2 +-
 irdb-libs/libIRDB-deep/src/deep.cpp           |  14 ++
 irdb-libs/libIRDB-deep/src/deep.hpp           |  12 +-
 irdb-libs/libMEDSannotation/SConscript        |   1 +
 .../include/MEDS_LoopAnnotation.hpp           |  67 +++++++++
 .../src/MEDS_AnnotationParser.cpp             |   2 +
 .../src/MEDS_LoopAnnotation.cpp               | 133 ++++++++++++++++++
 irdb-sdk                                      |   2 +-
 8 files changed, 227 insertions(+), 6 deletions(-)
 create mode 100644 irdb-libs/libMEDSannotation/include/MEDS_LoopAnnotation.hpp
 create mode 100644 irdb-libs/libMEDSannotation/src/MEDS_LoopAnnotation.cpp

diff --git a/SMPStaticAnalyzer b/SMPStaticAnalyzer
index 732a3a9b2..26497da37 160000
--- a/SMPStaticAnalyzer
+++ b/SMPStaticAnalyzer
@@ -1 +1 @@
-Subproject commit 732a3a9b2c8d17f6f9f25048f921c3f36b6a071d
+Subproject commit 26497da37ca82c270e44546d729d66ca0b83a4fa
diff --git a/irdb-libs/libIRDB-deep/src/deep.cpp b/irdb-libs/libIRDB-deep/src/deep.cpp
index 1bfad4ea9..5efbd3457 100644
--- a/irdb-libs/libIRDB-deep/src/deep.cpp
+++ b/irdb-libs/libIRDB-deep/src/deep.cpp
@@ -142,6 +142,18 @@ unique_ptr<IRDB_SDK::RangeSentinelSet_t> StarsDeepAnalysis_t::getRangeSentinels(
 	return ret;
 }
 
+unique_ptr<IRDB_SDK::LoopNest_t> StarsDeepAnalysis_t::getLoopNest(const IRDB_SDK::Function_t* f) const
+{
+	auto ret = unique_ptr<IRDB_SDK::LoopNest_t>();
+	return ret;
+}
+
+unique_ptr<IRDB_SDK::LoopNest_t> StarsDeepAnalysis_t::getLoopNest(const IRDB_SDK::ControlFlowGraph_t* cfg) const 
+{
+	auto ret = unique_ptr<IRDB_SDK::LoopNest_t>();
+	return ret;
+}
+
 
 unique_ptr<IRDB_SDK::DeepAnalysis_t> IRDB_SDK::DeepAnalysis_t::factory(FileIR_t* firp, const AnalysisEngine_t& ae, const vector<string>& options)
 {
@@ -165,3 +177,5 @@ unique_ptr<IRDB_SDK::DeepAnalysis_t> IRDB_SDK::DeepAnalysis_t::factory(FileIR_t*
 }
 
 
+
+
diff --git a/irdb-libs/libIRDB-deep/src/deep.hpp b/irdb-libs/libIRDB-deep/src/deep.hpp
index c06bcb343..bba46a9ee 100644
--- a/irdb-libs/libIRDB-deep/src/deep.hpp
+++ b/irdb-libs/libIRDB-deep/src/deep.hpp
@@ -22,10 +22,14 @@ namespace libIRDB
 
 			StarsDeepAnalysis_t(IRDB_SDK::FileIR_t* firp, const vector<string>& options={});
 
-			unique_ptr<IRDB_SDK::FunctionSet_t         > getLeafFunctions()      const ;
-			unique_ptr<IRDB_SDK::DeadRegisterMap_t     > getDeadRegisters()      const ;
-			unique_ptr<IRDB_SDK::StaticGlobalStartMap_t> getStaticGlobalRanges() const ;
-			unique_ptr<IRDB_SDK::RangeSentinelSet_t    > getRangeSentinels()     const ;
+			virtual unique_ptr<IRDB_SDK::FunctionSet_t         > getLeafFunctions()      const override;
+			virtual unique_ptr<IRDB_SDK::DeadRegisterMap_t     > getDeadRegisters()      const override;
+			virtual unique_ptr<IRDB_SDK::StaticGlobalStartMap_t> getStaticGlobalRanges() const override;
+			virtual unique_ptr<IRDB_SDK::RangeSentinelSet_t    > getRangeSentinels()     const override;
+
+			virtual unique_ptr<IRDB_SDK::LoopNest_t> getLoopNest(const IRDB_SDK::Function_t* f)           const override;
+                        virtual unique_ptr<IRDB_SDK::LoopNest_t> getLoopNest(const IRDB_SDK::ControlFlowGraph_t* cfg) const override;
+
 
 		private:
 			STARS::IRDB_Interface_t stars_analysis_engine;
diff --git a/irdb-libs/libMEDSannotation/SConscript b/irdb-libs/libMEDSannotation/SConscript
index cb89f07ae..6548d22ee 100644
--- a/irdb-libs/libMEDSannotation/SConscript
+++ b/irdb-libs/libMEDSannotation/SConscript
@@ -12,6 +12,7 @@ files=  '''
 	src/MEDS_FPTRShadowAnnotation.cpp
 	src/MEDS_DeadRegAnnotation.cpp
 	src/MEDS_FRSafeAnnotation.cpp
+	src/MEDS_LoopAnnotation.cpp
 	src/MEDS_FuncPrototypeAnnotation.cpp
 	src/MEDS_InstructionCheckAnnotation.cpp
 	src/MEDS_MemoryRangeAnnotation.cpp
diff --git a/irdb-libs/libMEDSannotation/include/MEDS_LoopAnnotation.hpp b/irdb-libs/libMEDSannotation/include/MEDS_LoopAnnotation.hpp
new file mode 100644
index 000000000..f72630926
--- /dev/null
+++ b/irdb-libs/libMEDSannotation/include/MEDS_LoopAnnotation.hpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2014 - Zephyr Software LLC
+ *
+ * This file may be used and modified for non-commercial purposes as long as
+ * all copyright, permission, and nonwarranty notices are preserved.
+ * Redistribution is prohibited without prior written consent from Zephyr
+ * Software.
+ *
+ * Please contact the authors for restrictions applying to commercial use.
+ *
+ * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author: Zephyr Software
+ * e-mail: jwd@zephyr-software.com
+ * URL   : http://www.zephyr-software.com/
+ *
+ */
+
+#ifndef _MEDS_LOOPANNOTATION_H_
+#define _MEDS_LOOPANNOTATION_H_
+
+#include <string>
+#include "VirtualOffset.hpp"
+#include "MEDS_Register.hpp"
+#include <set>
+#include "MEDS_AnnotationBase.hpp"
+
+
+namespace MEDS_Annotation 
+{
+
+using namespace std;
+using namespace MEDS_Annotation;
+
+//
+// Class to handle one MEDS (integer vulnerability) annotation
+//
+class MEDS_LoopAnnotation : public MEDS_AnnotationBase
+{
+	public:
+		MEDS_LoopAnnotation() : 
+			loop_no(0), 
+			preheader(0), 
+			header(0)
+			{};
+		MEDS_LoopAnnotation(const string &p_rawLine);
+		virtual ~MEDS_LoopAnnotation(){}
+
+		virtual const string toString() const { return "loop annot "; }
+
+	private:
+		void init();
+		void parse();
+
+		string m_rawInputLine;
+
+		uint64_t loop_no;
+		IRDB_SDK::VirtualOffset_t preheader;
+		IRDB_SDK::VirtualOffset_t header;
+		set<IRDB_SDK::VirtualOffset_t> all_blocks;
+		set<uint64_t> sub_loops;
+};
+
+}
+#endif
diff --git a/irdb-libs/libMEDSannotation/src/MEDS_AnnotationParser.cpp b/irdb-libs/libMEDSannotation/src/MEDS_AnnotationParser.cpp
index 85e85a2e4..cbe3c4735 100644
--- a/irdb-libs/libMEDSannotation/src/MEDS_AnnotationParser.cpp
+++ b/irdb-libs/libMEDSannotation/src/MEDS_AnnotationParser.cpp
@@ -28,6 +28,7 @@
 #include "MEDS_SafeFuncAnnotation.hpp"
 #include "MEDS_ProblemFuncAnnotation.hpp"
 #include "MEDS_FRSafeAnnotation.hpp"
+#include "MEDS_LoopAnnotation.hpp"
 #include "MEDS_FPTRShadowAnnotation.hpp"
 #include "MEDS_DeadRegAnnotation.hpp"
 #include "MEDS_TakesAddressAnnotation.hpp"
@@ -101,6 +102,7 @@ void MEDS_AnnotationParser::parseFile(istream &p_inputStream)
 		if(add_if_valid<MEDS_SafeFuncAnnotation>         (line)) continue;
 		if(add_if_valid<MEDS_ProblemFuncAnnotation>      (line)) continue;
 		if(add_if_valid<MEDS_FRSafeAnnotation>           (line)) continue;
+		if(add_if_valid<MEDS_LoopAnnotation>             (line)) continue;
 		if(add_if_valid<MEDS_FuncExitAnnotation>         (line)) continue;
 		if(add_if_valid<MEDS_TakesAddressAnnotation>     (line)) continue;
 		if(add_if_valid<MEDS_IBAnnotation>               (line)) continue;
diff --git a/irdb-libs/libMEDSannotation/src/MEDS_LoopAnnotation.cpp b/irdb-libs/libMEDSannotation/src/MEDS_LoopAnnotation.cpp
new file mode 100644
index 000000000..c13f378ec
--- /dev/null
+++ b/irdb-libs/libMEDSannotation/src/MEDS_LoopAnnotation.cpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2014 - Zephyr Software LLC
+ *
+ * This file may be used and modified for non-commercial purposes as long as
+ * all copyright, permission, and nonwarranty notices are preserved.
+ * Redistribution is prohibited without prior written consent from Zephyr
+ * Software.
+ *
+ * Please contact the authors for restrictions applying to commercial use.
+ *
+ * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author: Zephyr Software
+ * e-mail: jwd@zephyr-software.com
+ * URL   : http://www.zephyr-software.com/
+ *
+ */
+
+#include <stdlib.h>
+
+#include <iostream>
+#include <cstdio>
+#include <string>
+#include <string.h>
+
+#include "MEDS_LoopAnnotation.hpp"
+
+using namespace std;
+using namespace MEDS_Annotation;
+
+
+
+
+
+MEDS_LoopAnnotation::MEDS_LoopAnnotation(const string &p_rawLine)
+{
+	init();
+	m_rawInputLine=p_rawLine;
+	parse();
+}
+
+void MEDS_LoopAnnotation::init()
+{
+}
+
+
+template<typename int_type>
+static int_type readInt(const string& line, const string& name, const bool is_hex)
+{
+	const auto pos   = line.find(name);
+	assert(pos != string::npos);
+	const auto in    = line.substr(pos+name.length());
+	auto addr_string = string();
+	auto ret         = int_type();
+
+	stringstream iss;
+	if(is_hex)
+		iss << hex;
+	iss<<in;
+	iss >> ret;
+
+	if(iss.fail())
+		assert(0);
+
+	return ret;
+}
+
+template<typename int_type>
+static set<int_type> readAddrSet(const string& line, const string& name, const bool is_hex)
+{
+	const auto pos   = line.find(name);
+	assert(pos != string::npos);
+	const auto in    = line.substr(pos+name.length());
+	auto addr_string = string();
+	auto ret         = set<int_type>();
+
+        stringstream ss(in);	 // cannot use auto here.
+
+        while ( ss>>addr_string )
+        {
+                if( addr_string=="ZZ")
+                        return ret;
+
+		auto addr = IRDB_SDK::VirtualOffset_t();
+		stringstream iss; // cannot use auto here
+		if(is_hex)
+			iss << hex;
+		iss << addr_string; 	
+		iss >> addr;
+		assert(!iss.fail());
+
+                ret.insert(addr);
+        }
+
+        assert(0);
+        abort();        // needed for avoiding errors
+}
+
+
+/*
+	Example format (as of July 2019 ) -- subject to change
+5f 37 LOOP 0 FIRSTINST 80575fe PREHEADER ffffffffffffffff BLOCKLIST 80575fe 805760c 8057621 ZZ INNERLOOPS ZZ
+5f 37 LOOP 1 FIRSTINST 8057637 PREHEADER 8057632          BLOCKLIST 8057637 8057645 805765a ZZ INNERLOOPS ZZ
+5f 37 LOOP 2 FIRSTINST 80575ce PREHEADER 80575c7          BLOCKLIST 80575ce 80575de 80575e4 80575f2 8057626 8057632 805765f 80575fe 805760a 805760c 8057618 8057621 8057637 8057643 8057645 8057651 805765a 8057664 ZZ INNERLOOPS 0 1 ZZ
+
+*/
+void MEDS_LoopAnnotation::parse()
+{
+
+	const auto loop_pos = m_rawInputLine.find(" LOOP ");
+        if ( loop_pos == string::npos )
+	{
+		/* look for loop annotations only */
+		return;
+	}
+
+        // get offset
+        m_virtualOffset = VirtualOffset(m_rawInputLine);
+
+
+	loop_no    = readInt<decltype(loop_no  )>(m_rawInputLine, " LOOP ",      false);
+	header     = readInt<decltype(header   )>(m_rawInputLine, " FIRSTINST ", true);
+	preheader  = readInt<decltype(preheader)>(m_rawInputLine, " PREHEADER ", true);
+
+	all_blocks = readAddrSet<IRDB_SDK::VirtualOffset_t>(m_rawInputLine, " BLOCKLIST ", true);
+	sub_loops  = readAddrSet<uint64_t                 >(m_rawInputLine, " BLOCKLIST ", false);
+
+	setValid();	// no additional info recorded for right now.
+}
+
+
diff --git a/irdb-sdk b/irdb-sdk
index 51477757f..21c2c99f8 160000
--- a/irdb-sdk
+++ b/irdb-sdk
@@ -1 +1 @@
-Subproject commit 51477757faf6117452a9965d524481652a0a1651
+Subproject commit 21c2c99f8d6f0a37fadd91b0cc3877df5a4ab735
-- 
GitLab