lrusecurity_Displayer.cpp 4.33 KB
Newer Older
1
#include <lrupreanalysis/features.h>
2
#include <lrusecurity/features.h>
3 4 5 6 7
#include <elm/sys/Path.h>
#include <elm/sys/System.h>

#include <otawa/proc/BBProcessor.h>
#include <otawa/prog/Process.h>
Valentin Touzeau's avatar
Valentin Touzeau committed
8 9
#include <lruexact/features.h>
//#include "SecCFGOutput.h"
10
using namespace otawa;
11

12
namespace lrusecurity
13 14
{

15
class SecurityDisplayer : public BBProcessor
16 17 18 19
{
public:
	static otawa::p::declare reg;

20
	SecurityDisplayer() :
21 22 23 24 25 26 27 28 29 30 31
		otawa::BBProcessor(reg),
		_path(""),
		_toFile(false),
		_stream(nullptr),
		_line(false)
	{
	}

	virtual void configure(const PropList& props) override
	{
		otawa::BBProcessor::configure(props);
Valentin Touzeau's avatar
Valentin Touzeau committed
32 33 34 35
		if(props.hasProp(lruexact::CLASSIFICATION_PATH))
		  _path = lruexact::CLASSIFICATION_PATH(props);
		if(props.hasProp(lruexact::CLASSIFICATION_TO_FILE))
		  _toFile = lruexact::CLASSIFICATION_TO_FILE(props);
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
	}
protected:

	virtual void setup(WorkSpace *ws) override
	{
		// Check if source is available
		if(ws->isProvided(SOURCE_LINE_FEATURE))
			_line = true;
		if(logFor(LOG_PROC))
			log << "\tsource/line information " << (_line ? "" : "not ") << "available\n";

		if(!_path && _toFile)
			_path = _ << "access_classification.txt";

		if(_path) {
			try {
				_stream = elm::sys::System::createFile(_path);
			}
			catch(elm::sys::SystemException& e) {
				throw ProcessorException(*this, _ << "cannot open \"" << _path << "\"");
			}

			_out.setStream(*_stream);
		}
60
		_out << "ACCESS\t\tKIND\tCATEGORY\t\tBB\t";
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
		if(_line)
			_out << "\tLINE";

		_out << io::endl;
	}

	virtual void processCFG(WorkSpace* ws, CFG* cfg) override
	{
		_out << "FUNCTION " << cfg->label() << io::endl;
		BBProcessor::processCFG(ws, cfg);
	}

	virtual void processBB(WorkSpace* ws, CFG* cfg, Block* b) override
	{
		if(!b->isBasic())
			return;

		BasicBlock* bb = b->toBasic();

		for(Block::EdgeIter edgeIter(bb->ins()); edgeIter; ++edgeIter) {
			const Edge* e = *edgeIter;
82
			const Bag<icache::Access>& bag = otawa::icache::ACCESSES(e);
83 84 85
			processBag(ws, cfg, bag, bb);
		}

86
		const Bag<icache::Access>& bag = otawa::icache::ACCESSES(bb);
87 88 89 90 91 92 93 94 95
		processBag(ws, cfg, bag, bb);
	}

	void processBag(WorkSpace* ws, CFG* cfg, const Bag<icache::Access>& bag, BasicBlock* bb)
	{
		for(int i = 0; i < bag.size(); ++i)
			processAccess(ws, cfg, &bag[i], bb);
	}

96
  void processAccess(WorkSpace* ws, CFG*, const otawa::icache::Access* access, BasicBlock* bb)
97
	{
98 99
	       SecurityCategory cat = SECURITY_CATEGORY(access);
	       if(cat == SecurityCategory::UNSAFE){
100 101
		_out << access->address() << "\t";
		switch(access->kind()){
102 103 104
			case otawa::icache::NONE: _out << "NONE\t"; break;
			case otawa::icache::FETCH: _out << "FETCH\t"; break;
			case otawa::icache::PREFETCH: _out << "PREFETCH\t"; break;
105
		}
106
			_out << "UNSAFE ";
107
			int set = otawa::icat3::LBLOCK(access)->set();
108 109

            int number = 0;
110
			if (bb->hasProp(EXIST_HIT_PREV_IN)) {
111
			  ACSSecurity prev = (*EXIST_HIT_PREV_IN(bb))[set];
112
			  int index = otawa::icat3::LBLOCK(access)->index();
113 114 115 116 117 118 119 120
              number = prev[index].size();
			  for (int i = 0; i < number; i++)
			    _out << prev[index][i] << "\n\t\t\t\t\b";

              // REMONTEE
			  for (int j = 0; j < number; j++)
                _out << "\033[1A";

121
			}
122 123

		_out << "\t\t\tBB " << bb->index() << "\t\t";
124
		printLine(ws, bb->address(), bb->topAddress().offset());
125 126 127 128 129 130

      // DESCENTE
      for (int i = 0; i < number-1; i++)
        _out << "\n//";
      _out << io::endl;
    }
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
	}

	void printLine(WorkSpace* ws, Address begin, Address::offset_t offset)
	{

		// Display line
		if(_line) {
			bool one = false;
			Pair<cstring, int> old = pair(cstring(""), 0);
			for(Address addr = begin; addr.offset() < offset; addr = addr + 1) {
				Option<Pair<cstring, int> > res = ws->process()->getSourceLine(addr);
				if(res) {
					if((*res).fst != old.fst) {
						old = *res;
			 			if(one)
			 				_out << ", ";
			 			else
			 				one = true;
			 			_out << old.fst << ':' << old.snd;
					}
					else if((*res).snd != old.snd) {
						old = *res;
						_out << ',' << old.snd;
					}
				}
			}
		}
	}

	virtual void cleanup(WorkSpace*) override
	{
		if(_stream)
			delete _stream;
	}

	elm::io::Output _out;
	elm::sys::Path _path;
	bool _toFile;
	elm::io::OutStream* _stream;
	bool _line;
	bool _mcAnalysis;
};

174 175 176
p::declare SecurityDisplayer::reg = p::init("lrusecurity::SecurityDisplayer", Version(1, 0, 0))
	.require(SECURITY_CATEGORY_FEATURE)
	.make<SecurityDisplayer>();
177

178
} // namespace lrusecurity
179