/*
 * SMPStaticAnalyzer.h - <see below>.
 *
 * Copyright (c) 2000, 2001, 2010 - University of Virginia 
 *
 * This file is part of the Memory Error Detection System (MEDS) infrastructure.
 * 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 the University 
 * of Virginia.
 *
 * 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: University of Virginia
 * e-mail: jwd@virginia.com
 * URL   : http://www.cs.virginia.edu/
 *
 * Additional copyrights 2010, 2011 by Zephyr Software LLC
 * e-mail: {clc,jwd}@zephyr-software.com
 * URL   : http://www.zephyr-software.com/
 *
 */

#ifndef SMPSTATICANALYZER_H
#define SMPSTATICANALYZER_H 1

using namespace std;

#include <string>

#define LAST_OPT_CATEGORY  10
#define LAST_TYPE_CATEGORY 15

// Record optimization category by opcode.
extern int OptCategory[NN_last + 1];

// Keep statistics on how many instructions we saw in each optimization
//  category, and how many optimizing annotations were emitted for
//  each category.
extern int OptCount[LAST_OPT_CATEGORY + 1];
extern int AnnotationCount[LAST_OPT_CATEGORY + 1];

// Record which opcodes change the stack pointer, and by how many
//  bytes up (reduction in stack size for stacks that grow downward)
//  or down (increase in stack size for stacks that grow downward).
extern sval_t StackAlteration[NN_last + 1];

// Unique data referent number to use in data annotations.
extern unsigned long DataReferentID;

// Counters for analyzing memory use for allocated but unused capacity in vectors.
extern unsigned long UnusedStructCount; // various structs 
extern unsigned long UnusedIntCount; // int, ea_t, ptr, other 4-byte objects

// Counters for measuring SCCP success in finding constant DEFs.
extern unsigned long ConstantDEFCount;
extern unsigned long AlwaysTakenBranchCount;
extern unsigned long NeverTakenBranchCount;

// Counters for numeric error annotations cases.
#define SMP_MEASURE_NUMERIC_ANNOTATIONS 0
#if SMP_MEASURE_NUMERIC_ANNOTATIONS
extern unsigned long NumericAnnotationsCount12; // cases 1 and 2
extern unsigned long NumericAnnotationsCount3;  // case 3
extern unsigned long TruncationAnnotationsCount; // case 4
extern unsigned long SignednessWithoutTruncationCount; // case 5
extern unsigned long LeaInstOverflowCount; // case 6
extern unsigned long WidthDoublingTruncationCount; // case 7
extern unsigned long BenignOverflowInstCount;
extern unsigned long BenignOverflowDefCount;
extern unsigned long SuppressStackPtrOverflowCount;
extern unsigned long SuppressLiveFlagsOverflowCount;
extern unsigned long LiveMultiplyBitsCount;
extern unsigned long BenignTruncationCount;
extern unsigned long SuppressTruncationRegPiecesAllUsed;
extern unsigned long SuppressSignednessOnTruncation;
#endif

#define SMP_COUNT_MEMORY_ALLOCATIONS 0
#if SMP_COUNT_MEMORY_ALLOCATIONS
// Counters for analyzing memory use for allocated and used objects.
extern unsigned long SMPInstCount;
extern unsigned long SMPBlockCount;
extern unsigned long SMPDefUseChainCount;
extern unsigned long SMPFuncCount;
extern unsigned long SMPGlobalVarCount;
extern unsigned long SMPLocalVarCount;
extern unsigned long SMPInstBytes;
extern unsigned long SMPDefUseChainBytes;
#define SMP_DU_ADDR_SIZE sizeof(ea_t)
#endif

#define STARS_SCCP_GATHER_STATISTICS 1
#if STARS_SCCP_GATHER_STATISTICS
// Counters for analyzing Sparse Conditional Constant Propagation effectiveness.
extern unsigned long SCCPFuncsWithArgWriteCount;
extern unsigned long SCCPFuncsWithConstantArgWriteCount;
extern unsigned long SCCPOutgoingArgWriteCount;
extern unsigned long SCCPConstantOutgoingArgWriteCount;
#endif

// Is the binary a 32-bit, 64-bit, etc. instruction set architecture
extern size_t STARS_ISA_Bitwidth;
extern size_t STARS_ISA_Bytewidth;
extern char STARS_ISA_dtyp;

// Use shrink to fit C++ STL idiom to reduce memory wastage?
#define SMP_SHRINK_TO_FIT 1

// Should we convert the x86 LOCK prefix byte to a no-op to avoid
//  IDA Pro problems with instructions that jump past the LOCK
//  prefix and look like they are jumping into the middle of an
//  instruction?
#define STARS_REMOVE_LOCK_PREFIX 0

// The types of data objects based on their first operand flags.
extern const char *DataTypes[];

// Initialized operand used to copy-initialize other operands.
extern op_t InitOp;

// File to print security alert messages to, e.g. foo.exe.alarms.
extern FILE *ZST_AlarmFile;

// Security policies for the Zephyr Security Toolkit.
enum ZST_Policy {
	ZST_DISALLOW = 0,
	ZST_WHITELIST = 1,
	ZST_BLACKLIST = 2,
	ZST_ALLOWALL = 3
};

// What type of system call, for Zephyr Security Toolkit monitoring.
enum ZST_SysCallType {
	ZST_UNMONITORED_CALL,
	ZST_HIGHPRIVILEGE_CALL,
	ZST_FILE_CALL,
	ZST_NETWORK_CALL
};

// File for code xref targets (helps ILR, makes IRDB more complete)
extern FILE *STARS_XrefsFile;

class DisAsmString;

extern DisAsmString DisAsmText;

// strings for printing ZST_SysCallType
extern const char *CallTypeNames[4];

// Bit masks for extracting bits from a STARSBitSet unsigned char.
extern const unsigned char STARSBitMasks[8];

// Given a function name, return its Zephyr Security Toolkit call type.
ZST_SysCallType GetCallTypeFromFuncName(string SysCallName);

// Get the user-specified security policy for the given call type.
ZST_Policy GetPolicyFromCallType(ZST_SysCallType CallType);

// Given a call type and called function name, is it on the location whitelist
//  for that call type?
bool IsLocationWhitelisted(ZST_SysCallType CallType, string LocationName);

// Given a call type and called function name, is it on the location blacklist
//  for that call type?
bool IsLocationBlacklisted(ZST_SysCallType CallType, string LocationName);

// 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 IsNumericSafeSystemCall(string CallName);

// Utility functions to print code xrefs to STARS_XrefsFile
void PrintCodeToCodeXref(ea_t FromAddr, ea_t ToAddr, size_t InstrSize);
void PrintDataToCodeXref(ea_t FromDataAddr, ea_t ToCodeAddr, size_t InstrSize);

#endif