/* * SMPProgram.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 SMPPROGRAM_H #define SMPPROGRAM_H 1 // SMPProgram.h // // This header defines the interfaces needed for analyzing whole programs. #include <string> #include <utility> #include <list> #include <vector> #include <map> #include <set> #include <cstddef> #include "SMPDBInterface.h" #ifdef STARS_IDA_INTERFACE #include <pro.h> #include <ida.hpp> #include <ua.hpp> #endif #include "SMPDataFlowAnalysis.h" #include "SMPInstr.h" #include "SMPBasicBlock.h" #include "SMPFunction.h" using namespace std; class ProfilerInformation; extern ea_t LowestGlobalVarAddress; extern ea_t HighestGlobalVarAddress; extern ea_t LowestCodeAddress; extern ea_t HighestCodeAddress; inline bool IsImmedGlobalAddress(ea_t ImmedValue) { return ((ImmedValue >= LowestGlobalVarAddress) && (ImmedValue <= HighestGlobalVarAddress)); } // NOTE: Change this when we do targets with data (other than switch tables) in code. // Call IsDataAddress() first to weed out data items in the code range. inline bool IsImmedCodeAddress(ea_t ImmedValue) { return ((ImmedValue >= LowestCodeAddress) && (ImmedValue <= HighestCodeAddress)); } #if 0 // Is the address in a data segment? // NOTE: If we do targets with interleaved code and data, we must change the implementation. bool IsDataAddress(ea_t Address); #endif inline bool IsImmedNumeric(ea_t ImmedValue) { return (!(IsImmedGlobalAddress(ImmedValue) || IsImmedCodeAddress(ImmedValue))); } class LessOff { public: bool operator()(const pair<size_t, bool> &Off1, const pair<size_t, bool> &Off2) const { return (Off1.first < Off2.first); } // end operator }; // end class LessOff struct GlobalVar { ea_t addr; size_t size; char name[MAXSMPGLOBALVARSTR]; bool ReadOnly; // came from read-only data segment type bool IndexedAccess; flags_t flags; set<pair<size_t, bool>, LessOff> FieldOffsets; // bool = accessed through index register by any instruction? }; class LtStr { public: bool operator() (const char* c1, const char* c2) const { return strcmp(c1, c2) < 0; } }; // Class encapsulating all that the SMP static analyzer cares to know // about a whole program. class SMPProgram { public: // Constructors SMPProgram(void); // Default constructor ~SMPProgram(void); // Destructor // Get methods inline map<string, ea_t>::iterator FindGlobalName(string Name) { return GlobalNameMap.find(Name); } inline map<string, ea_t>::iterator GetLastGlobalName(void) { return GlobalNameMap.end(); } inline ProfilerInformation *GetProfInfo(void) { return ProfInfo; }; SMPFunction* FindFunction(ea_t FirstAddr); // get function from first addr in function inline size_t GetFuncCount(void) const { return FuncMap.size(); }; // Set methods void ProfGranularityFinished(FILE *AnnotFile, FILE *InfoAnnotFile); // notification from ProfilerInformation bool InsertUnsharedFragment(ea_t TargetAddr); // Add code fragment starting address to set; return false if already in set, true otherwise // Query methods bool IsUnsharedFragment(ea_t InstAddr); // Does InstAddr begin an unshared function fragment? // Printing methods void Dump(void); // debug dump // Analysis methods void AnalyzeData(void); // Analyze static data in the program. void Analyze(ProfilerInformation* pi); // Analyze all functions in the program void EmitDataAnnotations(FILE *AnnotFile, FILE *InfoAnnotFile); // Emit annotations for global data void EmitAnnotations(FILE *AnnotFile, FILE *InfoAnnotFile); // Emit annotations for all functions bool IsChunkUnshared(ea_t ChunkAddr, ea_t FuncHeadStart, ea_t FuncHeadEnd); // Does chunk at ChunkAddr belong exclusively to FuncHead? // If so, return true and add ChunkAddr to ProcessedFragments set. private: // Data bool ProfilerGranularityComplete; // Profiler-based granularity inference complete ProfilerInformation *ProfInfo; FILE *AnnotationFile; // need to store temporarily to pass to EmitDataAnnotations FILE *InfoAnnotationFile; // need to store temporarily to pass to EmitDataAnnotations map<ea_t, SMPFunction *> FuncMap; // all functions in the program map<ea_t, SMPFunction *> TempFuncMap; // Copy of FuncMap that can be reduced as entries are processed list<SMPFunction *> PrioritizedFuncList; // Functions in bottom-up call-graph analysis order map<ea_t, struct GlobalVar> GlobalVarTable; // all global static variables map<string, ea_t> GlobalNameMap; // map global name to address list<pair<ea_t, SMPFunction *> > FuncList; // FuncMap entries prioritized in desired order for analysis set<ea_t> UnsharedFragments; // Code fragments incorporated into their callers; remove from FuncMaps // Methods void InitStaticDataTable(void); // Gather info about global static data locations void ComputeGlobalFieldOffsets(struct GlobalVar &CurrGlobal); FuncType RecurseAndMarkRetAdd(SMPFunction *); void ResetFuncsProcessed(void); // set all funcs to not processed before a whole program analysis void PrioritizeCallGraph(void); // Extract TempFuncMap entries into FuncList in a good order for whole program analyses. }; // end class SMPProgram #endif