Skip to content
Snippets Groups Projects
STARSProgram.cpp 597 KiB
Newer Older
/* STARSProgram.cpp: Base class
 * Copyright 2015 by Zephyr Software LLC 
 */

#include <cstring>
#include <algorithm>
#include <iostream>
#include <sstream>
#include "interfaces/STARSTypes.h"
#include "interfaces/SMPDBInterface.h"
// #include "interfaces/abstract/all.h"
#include "base/SMPDataFlowAnalysis.h"


void STARS_Program_t::MDInitializeCallerSavedRegs(void) {
	this->STARS_MDCallerSavedRegs.clear();
	bool x86_64_ISA_flag = false;
#ifdef __EA64__
	x86_64_ISA_flag = (this->GetSTARS_ISA_Bitwidth() == 64);
#endif
	if (!x86_64_ISA_flag) {
		// 32-bit x86 uses EAX, ECX, EDX as caller-saved.
		this->STARS_MDCallerSavedRegs.push_back(STARS_x86_R_ax);
		this->STARS_MDCallerSavedRegs.push_back(STARS_x86_R_cx);
		this->STARS_MDCallerSavedRegs.push_back(STARS_x86_R_dx);
	}
	else {
		// 64-bit x86 uses EDI, ESI, EDX, ECX, R8 and R9
		//  in that order. After six arguments that fit into
		//  these regs, arguments are passed on the stack.
		// In addition, registers EAX, R10 and R11 are caller-saved
		//  but are not used to pass arguments.
		this->STARS_MDCallerSavedRegs.push_back(STARS_x86_R_ax);
		this->STARS_MDCallerSavedRegs.push_back(STARS_x86_R_cx);
		this->STARS_MDCallerSavedRegs.push_back(STARS_x86_R_dx);
		this->STARS_MDCallerSavedRegs.push_back(STARS_x86_R_si);
		this->STARS_MDCallerSavedRegs.push_back(STARS_x86_R_di);
		this->STARS_MDCallerSavedRegs.push_back(STARS_x86_R_r8);
		this->STARS_MDCallerSavedRegs.push_back(STARS_x86_R_r9);
		this->STARS_MDCallerSavedRegs.push_back(STARS_x86_R_r10);
		this->STARS_MDCallerSavedRegs.push_back(STARS_x86_R_r11);
	}
	return;
} // end of STARS_IDA_Program_t::MDInitializeCallerSavedRegs()

void STARS_Program_t::MDInitializeArgumentRegs(void) {
	bool x86_64_ISA_flag = false;
#ifdef __EA64__
	x86_64_ISA_flag = (this->GetSTARS_ISA_Bitwidth() == 64);
#endif
	if (x86_64_ISA_flag) {
		this->STARS_MDArgumentRegs.push_back(STARS_x86_R_di);
		this->STARS_MDArgumentRegs.push_back(STARS_x86_R_si);
		this->STARS_MDArgumentRegs.push_back(STARS_x86_R_dx);
		this->STARS_MDArgumentRegs.push_back(STARS_x86_R_cx);
		this->STARS_MDArgumentRegs.push_back(STARS_x86_R_r8);
		this->STARS_MDArgumentRegs.push_back(STARS_x86_R_r9);
	}
	else {
		this->STARS_MDArgumentRegs.clear();
	}
	return;
} // end of STARS_IDA_Program_t::MDInitializeArgumentRegs()

void STARS_Program_t::MDInitializeCalleeSavedRegs(void) {
	this->STARS_MDCalleeSavedRegs.clear();
	bool x86_64_ISA_flag = false;
#ifdef __EA64__
	x86_64_ISA_flag = (this->GetSTARS_ISA_Bitwidth() == 64);
#endif
	if (!x86_64_ISA_flag) {
		// 32-bit x86 uses EAX, ECX, EDX as caller-saved, EBX, EBP, ESI, EDI as callee-saved.
		this->STARS_MDCalleeSavedRegs.push_back(STARS_x86_R_bx);
		this->STARS_MDCalleeSavedRegs.push_back(STARS_x86_R_bp);
		this->STARS_MDCalleeSavedRegs.push_back(STARS_x86_R_si);
		this->STARS_MDCalleeSavedRegs.push_back(STARS_x86_R_di);
	}
	else {
		// 64-bit x86 uses EDI, ESI, EDX, ECX, R8 and R9
		//  in that order. After six arguments that fit into
		//  these regs, arguments are passed on the stack.
		// In addition, registers EAX, R10 and R11 are caller-saved
		//  but are not used to pass arguments. The rest, besides RSP,
		//  are callee-saved.
		this->STARS_MDCalleeSavedRegs.push_back(STARS_x86_R_bx);
		this->STARS_MDCalleeSavedRegs.push_back(STARS_x86_R_bp);
		this->STARS_MDCalleeSavedRegs.push_back(STARS_x86_R_r12);
		this->STARS_MDCalleeSavedRegs.push_back(STARS_x86_R_r13);
		this->STARS_MDCalleeSavedRegs.push_back(STARS_x86_R_r14);
		this->STARS_MDCalleeSavedRegs.push_back(STARS_x86_R_r15);
	}
	return;
} // end of STARS_IDA_Program_t::MDInitializeCalleeSavedRegs()

bool STARS_Program_t::OpenFiles(void) {
	bool success = this->OpenSecondaryFilesOnly();
	if (success) {
		this->STARS_AnnotFile = SMP_fopen(this->AnnotFileName.c_str(), "w");
		if (NULL == this->STARS_AnnotFile) {
			SMP_msg("FATAL ERROR: Cannot open annotations file %s\n", this->AnnotFileName.c_str());
			(void)SMP_fclose(this->STARS_XrefsFile);
			(void)SMP_fclose(this->STARS_CallReturnFile);
			(void)SMP_fclose(this->STARS_UninitVarFile);
			(void)SMP_fclose(this->ZST_AlarmFile);
			(void)SMP_fclose(this->STARS_InfoAnnotFile);
			if (global_STARS_program->ShouldSTARSTranslateToSPARKAda()) {
				(void)SMP_fclose(this->ZST_SPARKHeaderFile);
				(void)SMP_fclose(this->ZST_SPARKSourceFile);
			}
			success = false;
		}
	}

	return success;
} // end of STARS_Program_t::OpenFiles()

bool STARS_Program_t::OpenMainAnnotationFile(void) {
	bool success = true;
	this->STARS_AnnotFile = SMP_fopen(this->AnnotFileName.c_str(), "w");
	if (NULL == this->STARS_AnnotFile) {
		SMP_msg("FATAL ERROR: Cannot open annotations file %s\n", this->AnnotFileName.c_str());
		success = false;
	}
	return success;
} // end of STARS_Program_t::OpenMainAnnotationFile()


bool STARS_Program_t::OpenSecondaryFilesOnly(void) {
	// Open the output files except for the main annotation file.
	assert(0 < this->RootFileName.size());  // SetRootFileName() must be called previously.

	string ZSTAlarmFileName(this->GetRootFileName());
	string AlarmFileSuffix(".alarms");
	ZSTAlarmFileName += AlarmFileSuffix;
	string XrefsFileName(this->GetRootFileName());
	string XrefsFileSuffix(".STARSxrefs");
	XrefsFileName += XrefsFileSuffix;
	string CallRetFileName(this->GetRootFileName());
	string CallRetFileSuffix(".STARScallreturn");
	CallRetFileName += CallRetFileSuffix;
	string UninitVarFileName(this->GetRootFileName());
	string UninitVarFileSuffix(".STARSuninit");
	UninitVarFileName += UninitVarFileSuffix;
	string LoopsFileName(this->GetRootFileName());
	string LoopsFileSuffix(".STARSloops");
	LoopsFileName += LoopsFileSuffix;

	string SPARKSourceFileName("");
	string SPARKHeaderFileName("");
	if (global_STARS_program->ShouldSTARSTranslateToSPARKAda()) {
		// Extract "foo" from "foo.exe" to get the Ada package name
		istringstream StreamRootName(this->RootFileName);
		(void)std::getline(StreamRootName, this->PackageName, '.');
		if (this->PackageName.empty()) {
			SMP_msg("ERROR: Could not extract an Ada package name from the root of file name %s\n", this->RootFileName.c_str());
			return false;
		}
		// Convert dashes to underscores in the package name to suit Ada standards.
		replace(this->PackageName.begin(), this->PackageName.end(), '-', '_');
		SPARKSourceFileName += this->PackageName;
		string SPARKSourceFileSuffix(".ZSTSPARK.adb");
		SPARKSourceFileName += SPARKSourceFileSuffix;
		SPARKHeaderFileName += this->PackageName;
		string SPARKHeaderFileSuffix(".ZSTSPARK.ads");
		SPARKHeaderFileName += SPARKHeaderFileSuffix;
	}

	this->STARS_XrefsFile = SMP_fopen(XrefsFileName.c_str(), "w");
	if (NULL == this->STARS_XrefsFile) {
		SMP_msg("FATAL ERROR: Cannot open STARS code xrefs file %s\n", XrefsFileName.c_str());
		return false;
	}

	this->STARS_CallReturnFile = SMP_fopen(CallRetFileName.c_str(), "w");
	if (NULL == this->STARS_CallReturnFile) {
		SMP_msg("FATAL ERROR: Cannot open STARS calls and returns info file %s\n", CallRetFileName.c_str());
		(void)SMP_fclose(this->STARS_XrefsFile);
		return false;
	}

	this->STARS_UninitVarFile = SMP_fopen(UninitVarFileName.c_str(), "w");
	if (NULL == this->STARS_UninitVarFile) {
		SMP_msg("FATAL ERROR: Cannot open STARS uninitialized vars info file %s\n", UninitVarFileName.c_str());
		(void)SMP_fclose(this->STARS_XrefsFile);
		(void)SMP_fclose(this->STARS_CallReturnFile);
		return false;
	}

	this->ZST_AlarmFile = SMP_fopen(ZSTAlarmFileName.c_str(), "w");
	if (NULL == this->ZST_AlarmFile) {
		SMP_msg("FATAL ERROR: Cannot open security alarms file %s\n", ZSTAlarmFileName.c_str());
		(void)SMP_fclose(this->STARS_XrefsFile);
		(void)SMP_fclose(this->STARS_CallReturnFile);
		(void)SMP_fclose(this->STARS_UninitVarFile);
		return false;
	}

	this->STARS_InfoAnnotFile = SMP_fopen(this->InfoAnnotFileName.c_str(), "w");
	if (NULL == this->STARS_InfoAnnotFile) {
		SMP_msg("FATAL ERROR: Cannot open annotations file %s\n", this->InfoAnnotFileName.c_str());
		(void)SMP_fclose(this->STARS_XrefsFile);
		(void)SMP_fclose(this->STARS_CallReturnFile);
		(void)SMP_fclose(this->STARS_UninitVarFile);
		(void)SMP_fclose(this->ZST_AlarmFile);
	this->STARS_LoopsAnnotFile = SMP_fopen(LoopsFileName.c_str(), "w");
	if (NULL == this->STARS_LoopsAnnotFile) {
		SMP_msg("FATAL ERROR: Cannot open loops annotations file %s\n", LoopsFileName.c_str());
		(void)SMP_fclose(this->STARS_XrefsFile);
		(void)SMP_fclose(this->STARS_CallReturnFile);
		(void)SMP_fclose(this->STARS_UninitVarFile);
		(void)SMP_fclose(this->ZST_AlarmFile);
		(void)SMP_fclose(this->STARS_InfoAnnotFile);
		return false;
	}

	if (global_STARS_program->ShouldSTARSTranslateToSPARKAda()) {
		this->ZST_SPARKSourceFile = SMP_fopen(SPARKSourceFileName.c_str(), "w");
		if (NULL == this->ZST_SPARKSourceFile) {
			SMP_msg("FATAL ERROR: Cannot open SPARK-Ada source output file %s\n", SPARKSourceFileName.c_str());
			(void)SMP_fclose(this->STARS_XrefsFile);
			(void)SMP_fclose(this->STARS_CallReturnFile);
			(void)SMP_fclose(this->STARS_UninitVarFile);
			(void)SMP_fclose(this->ZST_AlarmFile);
			(void)SMP_fclose(this->STARS_InfoAnnotFile);
			(void)SMP_fclose(this->STARS_LoopsAnnotFile);
			return false;
		}
		this->ZST_SPARKHeaderFile = SMP_fopen(SPARKHeaderFileName.c_str(), "w");
		if (NULL == this->ZST_SPARKHeaderFile) {
			SMP_msg("FATAL ERROR: Cannot open SPARK-Ada header output file %s\n", SPARKHeaderFileName.c_str());
			(void)SMP_fclose(this->STARS_XrefsFile);
			(void)SMP_fclose(this->STARS_CallReturnFile);
			(void)SMP_fclose(this->STARS_UninitVarFile);
			(void)SMP_fclose(this->ZST_AlarmFile);
			(void)SMP_fclose(this->STARS_InfoAnnotFile);
			(void)SMP_fclose(this->STARS_LoopsAnnotFile);
			(void)SMP_fclose(this->ZST_SPARKSourceFile);
			return false;
		}

} // end of STARS_Program_t::OpenSecondaryFilesOnly()

void STARS_Program_t::CloseFiles(void) {
	(void) SMP_fclose(this->STARS_AnnotFile);
	(void) SMP_fclose(this->STARS_InfoAnnotFile);

	if (global_STARS_program->ShouldSTARSTranslateToSPARKAda()) {
		(void)SMP_fclose(this->ZST_SPARKSourceFile);
		(void)SMP_fclose(this->ZST_SPARKHeaderFile);
	}
	(void) SMP_fclose(this->ZST_AlarmFile);
	(void) SMP_fclose(this->STARS_CallReturnFile);
	(void) SMP_fclose(this->STARS_XrefsFile);
	(void) SMP_fclose(this->STARS_UninitVarFile);
	(void) SMP_fclose(this->GetLoopsAnnotFile());
	return;
} // end of STARS_Program_t::CloseFiles()

// Apply new mode to the AnnotFile.
bool STARS_Program_t::ReopenAnnotFile(const char *mode) {
	FILE *TempHandle = freopen(NULL, mode, this->GetAnnotFile());
	bool success = (NULL != TempHandle);
	if  (success) {
		this->STARS_AnnotFile = TempHandle;
	}
	return success;
}

void STARS_Program_t::InitData(void) {
clc5q's avatar
clc5q committed
	this->IDAProDriver = false;  // default; set to true explicitly from IDA Pro code.
clc5q's avatar
clc5q committed
	this->CurrentFileNumber = 0;
	this->ZST_AlarmFile = NULL;
	this->STARS_CallReturnFile = NULL;
	this->STARS_XrefsFile = NULL;

	this->MDInitializeArgumentRegs();
	this->MDInitializeCallerSavedRegs(); 
	this->MDInitializeCalleeSavedRegs();
	// Initialize global counters for statistics-gathering purposes.
	STARS_SPARK_IndentCount = 1;
	UnusedStructCount = 0;
	UnusedIntCount = 0;
	DeadMetadataCount = 0;
	LiveMetadataCount = 0;
	ResolvedIndirectJumpCount = 0;
	UnresolvedIndirectJumpCount = 0;
	ConstantDEFCount = 0;
	AlwaysTakenBranchCount = 0;
	NeverTakenBranchCount = 0;
	SubwordRegCount = 0;
	SubwordMemCount = 0;
	SubwordAddressRegCount = 0;
	SPARKOperandCount = 0;
#if SMP_COUNT_MEMORY_ALLOCATIONS
	SMPInstCount = 0;
	SMPBlockCount = 0;
	SMPDefUseChainCount = 0;
	SMPFuncCount = 0;
	SMPGlobalVarCount = 0;
	SMPLocalVarCount = 0;
	SMPInstBytes = 0;
	SMPDefUseChainBytes = 0;
#endif
#if SMP_MEASURE_NUMERIC_ANNOTATIONS
	NumericAnnotationsCount12 = 0;
	NumericAnnotationsCount3 = 0;
	TruncationAnnotationsCount = 0;
	SignednessWithoutTruncationCount = 0;
	LeaInstOverflowCount = 0;
	WidthDoublingTruncationCount = 0;
	BenignOverflowInstCount = 0;
	BenignOverflowDefCount = 0;
	SuppressStackPtrOverflowCount = 0;
	SuppressLiveFlagsOverflowCount = 0;
	LiveMultiplyBitsCount = 0;
	BenignTruncationCount = 0;
	SuppressTruncationRegPiecesAllUsed = 0;
	SuppressSignednessOnTruncation = 0;
#endif
#if STARS_SCCP_GATHER_STATISTICS
	SCCPFuncsWithArgWriteCount = 0;
	SCCPFuncsWithConstantArgWriteCount = 0;
	SCCPOutgoingArgWriteCount = 0;
	SCCPConstantOutgoingArgWriteCount = 0;
#endif
	STARS_MaxBlockCount = 0;
	STARS_LoopInductionVarIDSuccesses = 0;
	STARS_LoopInductionVarIDFailures = 0;
	STARS_LoopIterationExprSuccesses = 0;
	STARS_LoopIterationExprFailures = 0;

	(void) memset(this->OptCount, 0, sizeof(this->OptCount));
	(void) memset(this->AnnotationCount, 0, sizeof(this->AnnotationCount));
	this->STARS_PerformReducedAnalysis = false;
	this->STARS_PerformLevel2ReducedAnalysis = false;
	this->STARS_PerformFuncPtrShadowing = false;
	this->STARS_PerformArgShadowing = false;
	this->STARS_PerformCFGImprovement = false;
	this->STARS_PerformDeepLoopAnalyses = false;
	this->STARS_PerformConstantPropagation = false;
	this->STARS_TranslateToSPARKAda = false;
	this->ShadowID = 1;
	this->ExprSerialNumber = 0;
	this->STARS_TotalCodeSize = 0;

	this->InitOptCategory();
	this->InitStackAlteration();
	this->InitDFACategory();
	this->InitTypeCategory();
	this->InitSMPDefsFlags();
	this->InitSMPUsesFlags();
	this->InitLibFuncFGInfoMaps();
	InitIntegerErrorCallSinkMap();
	InitUnsignedArgPositionMap();
	InitTaintWarningArgPositionMap();
	InitPointerArgPositionMap();
	InitLibraryFuncNames();

	return;
} // end of STARS_Program_t::InitData()

// Initialize the DeadregsDebugBitset based on environment var STARS_DEADREGS_ONLY.
//  Initialize the DeadregsDebugLimit based on environment var STARS_DEADREGS_DEBUG_LIMIT.
void STARS_Program_t::InitDebuggingDeadregs(void) {
	char DeadregsLimitString[STARS_MAXSTR];
	if (global_stars_interface->STARS_getenv("STARS_DEADREGS_DEBUG_LIMIT", DeadregsLimitString)) {
		const char *TempPtr = (const char *)&DeadregsLimitString[0];
		this->DeadregsDebugLimit = (uint32_t)strtoul(TempPtr, nullptr, 0);
		SMP_msg("DEBUG: DEADREGS: Annotation counter limit is %lu from string %s\n", this->DeadregsDebugLimit, TempPtr);
		this->DeadregsDebugLimit = UINT32_MAX - 1;
	}

	this->DeadregsAnnotCounter = 0;

	char DeadregsOnlyString[STARS_MAXSTR];
	if (global_stars_interface->STARS_getenv("STARS_DEADREGS_ONLY", DeadregsOnlyString)) {
		if (strstr(DeadregsOnlyString, "RAX") || strstr(DeadregsOnlyString, "EAX")) {
			this->DeadregsDebugBitset.set((size_t) STARS_x86_R_ax);
		}
		if (strstr(DeadregsOnlyString, "RCX") || strstr(DeadregsOnlyString, "ECX")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_cx);
		}
		if (strstr(DeadregsOnlyString, "RDX") || strstr(DeadregsOnlyString, "EDX")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_dx);
		}
		if (strstr(DeadregsOnlyString, "RBX") || strstr(DeadregsOnlyString, "EBX")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_bx);
		}
		if (strstr(DeadregsOnlyString, "RSP") || strstr(DeadregsOnlyString, "ESP")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_sp);
		}
		if (strstr(DeadregsOnlyString, "RBP") || strstr(DeadregsOnlyString, "EBP")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_bp);
		}
		if (strstr(DeadregsOnlyString, "RSI") || strstr(DeadregsOnlyString, "ESI")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_si);
		}
		if (strstr(DeadregsOnlyString, "RDI") || strstr(DeadregsOnlyString, "EDI")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_di);
		}
		if (strstr(DeadregsOnlyString, "R8")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_r8);
		}
		if (strstr(DeadregsOnlyString, "R9")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_r9);
		}
		if (strstr(DeadregsOnlyString, "R10")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_r10);
		}
		if (strstr(DeadregsOnlyString, "R11")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_r11);
		}
		if (strstr(DeadregsOnlyString, "R12")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_r12);
		}
		if (strstr(DeadregsOnlyString, "R13")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_r13);
		}
		if (strstr(DeadregsOnlyString, "R14")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_r14);
		}
		if (strstr(DeadregsOnlyString, "R15")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_r15);
		}
		if (strstr(DeadregsOnlyString, "EFLAGS")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_efl);
		}
		if (strstr(DeadregsOnlyString, "XMM0")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_xmm0);
		}
		if (strstr(DeadregsOnlyString, "XMM1")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_xmm1);
		}
		if (strstr(DeadregsOnlyString, "XMM2")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_xmm2);
		}
		if (strstr(DeadregsOnlyString, "XMM3")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_xmm3);
		}
		if (strstr(DeadregsOnlyString, "XMM4")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_xmm4);
		}
		if (strstr(DeadregsOnlyString, "XMM5")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_xmm5);
		}
		if (strstr(DeadregsOnlyString, "XMM6")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_xmm6);
		}
		if (strstr(DeadregsOnlyString, "XMM7")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_xmm7);
		}
		if (strstr(DeadregsOnlyString, "XMM8")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_xmm8);
		}
		if (strstr(DeadregsOnlyString, "XMM9")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_xmm9);
		}
		if (strstr(DeadregsOnlyString, "XMM10")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_xmm10);
		}
		if (strstr(DeadregsOnlyString, "XMM11")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_xmm11);
		}
		if (strstr(DeadregsOnlyString, "XMM12")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_xmm12);
		}
		if (strstr(DeadregsOnlyString, "XMM13")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_xmm13);
		}
		if (strstr(DeadregsOnlyString, "XMM14")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_xmm14);
		}
		if (strstr(DeadregsOnlyString, "XMM15")) {
			this->DeadregsDebugBitset.set((size_t)STARS_x86_R_xmm15);
		}
	}
	return;
} // end of STARS_Program_t::InitDebuggingDeadregs()

bool STARS_Program_t::IsRegAllowedInDeadregsAnnots(const std::size_t RegNum) const {
	assert(RegNum < this->DeadregsDebugBitset.size());
	return this->DeadregsDebugBitset[RegNum];
};

// These two constants should agree with their counterparts in ZST-policy.c.
#define ZST_MAX_FILE_NAME_LEN 1024
#define ZST_MAX_CALL_NAME_LEN 64

// Convert a call type string from the policy file, such as "FILECALLS", to the
//  corresponding ZST_SysCallType, such as ZST_FILE_CALL.
ZST_SysCallType STARS_Program_t::ConvertStringToCallType(char *Str2) {
	ZST_SysCallType ReturnVal;
	if (0 == strcmp("PRIVILEGECALLS", Str2)) {
		ReturnVal = ZST_HIGHPRIVILEGE_CALL;
	}
	else if (0 == strcmp("FILECALLS", Str2)) {
		ReturnVal = ZST_FILE_CALL;
	}
	else if (0 == strcmp("NETWORKCALLS", Str2)) {
		ReturnVal = ZST_NETWORK_CALL;
	}
	else {
		ReturnVal = ZST_UNMONITORED_CALL;
	}
	return ReturnVal;
} // end of STARS_Program_t::ConvertStringToCallType()

// Convert a policy string from the policy file, such as "DISALLOW", to
//  the corresponding ZST_Policy value, such as ZST_DISALLOW.
ZST_Policy STARS_Program_t::ConvertStringToPolicy(char *Str3) {
	ZST_Policy ReturnVal;
	if (0 == strcmp("DISALLOW", Str3)) {
		ReturnVal = ZST_DISALLOW;
	}
	else if (0 == strcmp("WHITELIST", Str3)) {
		ReturnVal = ZST_WHITELIST;
	}
	else if (0 == strcmp("BLACKLIST", Str3)) {
		ReturnVal = ZST_BLACKLIST;
	}
	else { // error handling precedes calls to this function
		ReturnVal = ZST_ALLOWALL;
	}
	return ReturnVal;
} // end of STARS_Program_t::ConvertStringToPolicy()

// Given a function name, return its Zephyr Security Toolkit call type.
ZST_SysCallType STARS_Program_t::GetCallTypeFromFuncName(string SysCallName) const {
	ZST_SysCallType ReturnVal;
	map<string, ZST_SysCallType>::const_iterator FindIter = this->ZST_FuncTypeMap.find(SysCallName);
	if (FindIter == this->ZST_FuncTypeMap.end()) { // not found; might not even be system call
		ReturnVal = ZST_UNMONITORED_CALL;
	}
	else {
		ReturnVal = FindIter->second;
	}
	return ReturnVal;
} // end of GetCallTypeFromFuncName()

// Get the user-specified security policy for the given call type.
ZST_Policy STARS_Program_t::GetPolicyFromCallType(ZST_SysCallType CallType) const {
	ZST_Policy ReturnVal;
	map<ZST_SysCallType, ZST_Policy>::const_iterator FindIter = ZST_TypePolicyMap.find(CallType);
	if (FindIter == ZST_TypePolicyMap.end()) {
		// Policy not found; default to ALLOW_ALL
		ReturnVal = ZST_ALLOWALL;
	}
	else {
		ReturnVal = FindIter->second;
	}
	return ReturnVal;
} // end of STARS_Program_t::GetPolicyFromCallType()

// Given a call type and called function name, is it on the location whitelist
//  for that call type?
// NOTE: HANDLE CASE IN WHICH WHITELISTED LOCATION IS A PREFIX, TERMINATING in a slash.
bool STARS_Program_t::IsLocationWhitelisted(ZST_SysCallType CallType, string LocationName) const {
	set<string>::const_iterator FindIter;
	bool ReturnVal;

	if (CallType == ZST_FILE_CALL) {
		FindIter = ZST_FileLocWhitelist.find(LocationName);
		ReturnVal = (FindIter != ZST_FileLocWhitelist.end());
	}
	else if (CallType == ZST_NETWORK_CALL) {
		FindIter = ZST_NetworkLocWhitelist.find(LocationName);
		ReturnVal = (FindIter != ZST_NetworkLocWhitelist.end());
	}
	else { // should not be here
		ReturnVal = false;
	}
	return ReturnVal;
} // end of STARS_Program_t::IsLocationWhitelisted()

// Given a call type and called function name, is it on the location blacklist
//  for that call type?
// NOTE: HANDLE CASE IN WHICH BLACKLISTED LOCATION IS A PREFIX, TERMINATING in a slash.
bool STARS_Program_t::IsLocationBlacklisted(ZST_SysCallType CallType, string LocationName) const {
	set<string>::const_iterator FindIter;
	bool ReturnVal;

	if (CallType == ZST_FILE_CALL) {
		FindIter = ZST_FileLocBlacklist.find(LocationName);
		ReturnVal = (FindIter != ZST_FileLocBlacklist.end());
	}
	else if (CallType == ZST_NETWORK_CALL) {
		FindIter = ZST_NetworkLocBlacklist.find(LocationName);
		ReturnVal = (FindIter != ZST_NetworkLocBlacklist.end());
	}
	else { // should not be here
		ReturnVal = false;
	}
	return ReturnVal;
} // end of STARS_Program_t::IsLocationBlacklisted()

// Given a called function name, does it produce only benign numeric errors when
//  its returned values are used in arithmetic? (i.e. it is a trusted input)
bool STARS_Program_t::IsNumericSafeSystemCall(string CallName) const {
	set<string>::const_iterator FindIter = ZST_SystemCallNumericWhitelist.find(CallName);
	bool ReturnVal = (FindIter != ZST_SystemCallNumericWhitelist.end());
	return ReturnVal;
}
bool STARS_Program_t::IsCalleeSavedReg(STARS_regnum_t RegNum) const {
	std::list<STARS_regnum_t>::const_iterator CalleeSavedIter = this->STARS_MDCalleeSavedRegs.cbegin();
	while (CalleeSavedIter != this->STARS_MDCalleeSavedRegs.cend()) {
		if (*CalleeSavedIter == RegNum) {
			found = true;
			break;
		}
		++CalleeSavedIter;
	}
	return found;
}

bool STARS_Program_t::IsCallerSavedReg(STARS_regnum_t RegNum) const {
	std::list<STARS_regnum_t>::const_iterator CallerSavedIter = this->STARS_MDCallerSavedRegs.cbegin();
	while (CallerSavedIter != this->STARS_MDCallerSavedRegs.cend()) {
		if (*CallerSavedIter == RegNum) {
			found = true;
			break;
		}
		else if (*CallerSavedIter > RegNum) {
			break; // passed it in sorted list; return false
		}
		++CallerSavedIter;
	}
	return found;
}

// return true and set ArgPos if RegNum is an InArg
bool STARS_Program_t::GetArgRegPosition(STARS_regnum_t RegNum, std::size_t &ArgPos) const {
	bool found = false;
	std::list<STARS_regnum_t>::const_iterator ArgRegsIter = this->STARS_MDArgumentRegs.cbegin();
	ArgPos = 0;
	while (ArgRegsIter != this->STARS_MDArgumentRegs.cend()) {
		if (*ArgRegsIter == RegNum) {
			found = true;
			break;
		}
		++ArgRegsIter;
		++ArgPos;
	}
	return found;
}

bool STARS_Program_t::IsArgumentReg(STARS_regnum_t RegNum) const {
	bool found = false;
	std::list<STARS_regnum_t>::const_iterator ArgRegsIter = this->STARS_MDArgumentRegs.cbegin();
	while (ArgRegsIter != this->STARS_MDArgumentRegs.cend()) {
		if (*ArgRegsIter == RegNum) {
			found = true;
			break;
		}
		++ArgRegsIter;
	}
	return found;
}

bool STARS_Program_t::AreInstIDsInSameFunction(const STARS_ea_t InstID1, const STARS_ea_t InstID2) const {
	STARS_Function_t *Func1 = SMP_get_func(InstID1);
	STARS_Function_t *Func2 = SMP_get_func(InstID2);
	return ((NULL != Func1) && (NULL != Func2) && (Func1->get_startEA() == Func2->get_startEA()));
}

void STARS_Program_t::PrintTypeCode(IBType TypeCode){
	if (ZST_RETURN == TypeCode) {
		SMP_fprintf(this->GetXrefsFile(), "RETURNTARGET\n");
	}
	else if (ZST_SWITCHTABLE == TypeCode) {
		SMP_fprintf(this->GetXrefsFile(), "SWITCHTABLE\n");
	}
	else if (ZST_INDIRCALL == TypeCode) {
		SMP_fprintf(this->GetXrefsFile(), "INDIRCALL\n");
	}
	else if (ZST_COMPUTEDGOTO == TypeCode) {
		SMP_fprintf(this->GetXrefsFile(), "COMPUTEDGOTOHEURISTIC\n");
	}
	else if (ZST_CODEADDRESSTAKEN == TypeCode) {
		SMP_fprintf(this->GetXrefsFile(), "CODEADDRESSTAKEN\n");
	}
	else if (ZST_UNREACHABLEBLOCK == TypeCode) {
		SMP_fprintf(this->GetXrefsFile(), "UNREACHABLEBLOCK\n");
	}
	else {
		SMP_fprintf(this->GetXrefsFile(), "UNKNOWN\n");
	}
	return;
}

// Utility functions to print code xrefs to STARS_XrefsFile
void STARS_Program_t::PrintAddressInCode(STARS_ea_t FromAddr, STARS_ea_t ToAddr, std::size_t InstrSize, bool is_to_code)
{
	if(is_to_code)
		SMP_fprintf(this->GetXrefsFile(), "%18llx %6zu INSTR XREF TAKES_ADDRESS_OF CODE %18llx\n",
			(unsigned long long) FromAddr, InstrSize, (unsigned long long) ToAddr);
	else
		SMP_fprintf(this->GetXrefsFile(), "%18llx %6zu INSTR XREF TAKES_ADDRESS_OF DATA %18llx\n",
			(unsigned long long) FromAddr, InstrSize, (unsigned long long) ToAddr);

}

// Utility functions to print code xrefs to STARS_XrefsFile
clc5q's avatar
clc5q committed
bool STARS_Program_t::PrintCodeToCodeXref(STARS_ea_t FromAddr, STARS_ea_t ToAddr, std::size_t InstrSize, IBType TypeCode) {
	bool success = false;
	if (IsAddressInCodeRange(ToAddr)) {
clc5q's avatar
clc5q committed
		success = true;
		SMP_fprintf(this->GetXrefsFile(), "%18llx %6zu INSTR XREF IBT FROMIB %18llx ",
			(unsigned long long) ToAddr, InstrSize, (unsigned long long) FromAddr);
		this->PrintTypeCode(TypeCode);
clc5q's avatar
clc5q committed
	return success;
// Utility functions to print code xrefs to STARS_XrefsFile
clc5q's avatar
clc5q committed
bool STARS_Program_t::PrintReturnInstXref(STARS_ea_t RetInstAddr, STARS_ea_t TargetAddr, std::size_t InstrSize, bool TailCallTargetAddr) {
	bool success = false;
clc5q's avatar
clc5q committed
	if (IsAddressInCodeRange(TargetAddr)) {
clc5q's avatar
clc5q committed
		success = true;
clc5q's avatar
clc5q committed
		FILE *XrefsFile = this->GetXrefsFile();
		SMP_fprintf(XrefsFile, "%18llx %6zu INSTR XREF IBT FROMIB %18llx ",
			(unsigned long long) TargetAddr, InstrSize, (unsigned long long) RetInstAddr);
clc5q's avatar
clc5q committed
		if (!TailCallTargetAddr) {
			SMP_fprintf(XrefsFile, "RETURNTARGET\n");
		}
		else {
			SMP_fprintf(XrefsFile, "TAILCALLRETURNTARGET\n");
		}
clc5q's avatar
clc5q committed
	return success;
void STARS_Program_t::PrintDataToCodeXref(STARS_ea_t FromDataAddr, STARS_ea_t ToCodeAddr, std::size_t InstrSize) {
	if (IsAddressInCodeRange(ToCodeAddr)) {
		SMP_fprintf(this->GetXrefsFile(), "%18llx %6zu INSTR XREF IBT FROMDATA %18llx \n",
			(unsigned long long) ToCodeAddr, InstrSize, (unsigned long long) FromDataAddr);
	}
void STARS_Program_t::PrintUnknownCodeXref(STARS_ea_t ToAddr, std::size_t InstrSize, IBType TypeCode) {
	SMP_fprintf(this->GetXrefsFile(), "%18llx %6zu INSTR XREF IBT FROMUNKNOWN ",
		(unsigned long long) ToAddr, InstrSize);
	this->PrintTypeCode(TypeCode);
// Utility functions to signify code xrefs are complete in STARS_XrefsFile for FromAddr
clc5q's avatar
clc5q committed
void STARS_Program_t::PrintCodeToCodeXrefComplete(STARS_ea_t FromAddr, std::size_t InstrSize, std::size_t IBTCount, IBType TypeCode) {
	if (IsAddressInCodeRange(FromAddr)) {
clc5q's avatar
clc5q committed
		SMP_fprintf(this->GetXrefsFile(), "%18llx %6zu INSTR XREF FROMIB COMPLETE %6zu ",
			(unsigned long long) FromAddr, InstrSize, IBTCount);
		this->PrintTypeCode(TypeCode);
// Read the foo.exe.policy file to initialize our security policies for system calls.
void STARS_Program_t::ZST_InitPolicies(void) {
	string ZSTPolicyFileName(this->GetRootFileName());
	string PolicyFileSuffix(".policy");
	ZSTPolicyFileName += PolicyFileSuffix;
	FILE *PolicyFile = SMP_fopen(ZSTPolicyFileName.c_str(), "r");
	char Str1[ZST_MAX_CALL_NAME_LEN], Str2[ZST_MAX_CALL_NAME_LEN], Str3[ZST_MAX_FILE_NAME_LEN];

	string SafeSystemCall1("gettimeofday");
	this->ZST_SystemCallNumericWhitelist.insert(SafeSystemCall1);

	if (NULL != PolicyFile) {
		while (!SMP_feof(PolicyFile)) {
			int ItemsRead = SMP_fscanf(PolicyFile, "%63s %63s %1023s", Str1, Str2, Str3);
			if (3 != ItemsRead) {
				SMP_msg("ERROR: Line in %s had %d items instead of the required 3; line ignored.\n", ZSTPolicyFileName.c_str(), ItemsRead);
			}
			else {
				string ThirdStr(Str3);
				pair<set<string>::iterator, bool> SetInsertResult;
				if (0 == strcmp(Str1, "SECURITYPOLICY")) {
					ZST_SysCallType TempCallType = ConvertStringToCallType(Str2);
					ZST_Policy TempPolicy = ConvertStringToPolicy(Str3);
					pair<map<ZST_SysCallType, ZST_Policy>::iterator, bool> InsertResult;
					pair<ZST_SysCallType, ZST_Policy> TempPair(TempCallType, TempPolicy);
					InsertResult = this->ZST_TypePolicyMap.insert(TempPair);
					if (!(InsertResult.second)) {
						SMP_msg("ERROR: Could not insert security policy %s for %s. Possible duplicate or conflicting policies.\n",
							Str3, Str2);
					}
				}
				else if (0 == strcmp(Str1, "FILELOCATION")) {
					if (0 == strcmp(Str2, "WHITELIST")) {
						SetInsertResult = this->ZST_FileLocWhitelist.insert(ThirdStr);
						if (!(SetInsertResult.second)) {
							SMP_msg("WARNING: Duplicate file whitelist location %s ignored.\n", Str3);
						}
					}
					else if (0 == strcmp(Str2, "BLACKLIST")) {
						SetInsertResult = this->ZST_FileLocBlacklist.insert(ThirdStr);
						if (!(SetInsertResult.second)) {
							SMP_msg("WARNING: Duplicate file blacklist location %s ignored.\n", Str3);
						}
					}
					else {
						SMP_msg("ERROR: Unknown second field value in policy line: %s %s %s ; ignored\n", Str1, Str2, Str3);
					}
				}
				else if (0 == strcmp(Str1, "NETWORKLOCATION")) {
					if (0 == strcmp(Str2, "WHITELIST")) {
						SetInsertResult = this->ZST_NetworkLocWhitelist.insert(ThirdStr);
						if (!(SetInsertResult.second)) {
							SMP_msg("WARNING: Duplicate network whitelist location %s ignored.\n", Str3);
						}
					}
					else if (0 == strcmp(Str2, "BLACKLIST")) {
						SetInsertResult = this->ZST_NetworkLocBlacklist.insert(ThirdStr);
						if (!(SetInsertResult.second)) {
							SMP_msg("WARNING: Duplicate network blacklist location %s ignored.\n", Str3);
						}
					}
					else {
						SMP_msg("ERROR: Unknown second field value in policy line: %s %s %s ; ignored\n", Str1, Str2, Str3);
					}
				}
				else {
					SMP_msg("ERROR: Unknown first field value in policy line: %s %s %s ; ignored\n", Str1, Str2, Str3);
				}
			}
		}
		if (0 == SMP_fclose(PolicyFile)) {
			SMP_msg("Policy file %s successfully closed; all policies recorded.\n", ZSTPolicyFileName.c_str());
		}
		else {
			SMP_msg("ERROR: fclose failed on policy file %s. However, policies should be in effect.\n", ZSTPolicyFileName.c_str());
		}
		// Now, initialize the system call name maps.
		pair<map<string, ZST_SysCallType>::iterator, bool> FuncInsertResult;
		// Do all the high privilege calls first.
		string SysFuncName("putenv");
		pair<string, ZST_SysCallType> FuncNamePolicyPair(SysFuncName, ZST_HIGHPRIVILEGE_CALL);
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("setenv");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("setegid");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("seteuid");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("setgid");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("setpgid");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("setregid");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("setreuid");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("setuid");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("execl");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("execv");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("execle");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("execve");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("execlp");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("execvp");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("system");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);

		// Now do all the file operation calls.
		FuncNamePolicyPair.second = ZST_FILE_CALL;
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("chdir");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("chmod");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("chown");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("creat");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("creat64");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("fopen");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("freopen");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("open");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("open64");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("mknod");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("remove");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("rmdir");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("unlink");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);

		// Finally, handle all the network connection calls.
		FuncNamePolicyPair.second = ZST_NETWORK_CALL;
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("socket");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("socketpair");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("pipe");
		FuncInsertResult = this->ZST_FuncTypeMap.insert(FuncNamePolicyPair);
		assert(FuncInsertResult.second);
		FuncNamePolicyPair.first.clear();
		FuncNamePolicyPair.first.append("bind");