Vous avez reçu un message "Your GitLab account has been locked ..." ? Pas d'inquiétude : lisez cet article https://docs.gricad-pages.univ-grenoble-alpes.fr/help/unlock/

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

#include <otawa/proc/BBProcessor.h>
#include <otawa/prog/Process.h>

9
 using namespace otawa;
10

11
namespace lrusecurity
12
13
{

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

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

	virtual void configure(const PropList& props) override
	{
		otawa::BBProcessor::configure(props);
31
32
33
34
		if(props.hasProp(lrupreanalysis::CLASSIFICATION_PATH))
		  _path = lrupreanalysis::CLASSIFICATION_PATH(props);
		if(props.hasProp(lrupreanalysis::CLASSIFICATION_TO_FILE))
		  _toFile = lrupreanalysis::CLASSIFICATION_TO_FILE(props);
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
	}
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);
		}
		_out << "ACCESS\t\tKIND\tCATEGORY\tBB\t";
		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;
81
			const Bag<icache::Access>& bag = otawa::icache::ACCESSES(e);
82
83
84
			processBag(ws, cfg, bag, bb);
		}

85
		const Bag<icache::Access>& bag = otawa::icache::ACCESSES(bb);
86
87
88
89
90
91
92
93
94
		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);
	}

95
  void processAccess(WorkSpace* ws, CFG*, const otawa::icache::Access* access, BasicBlock* bb)
96
	{
97
98
	       SecurityCategory cat = SECURITY_CATEGORY(access);
	       if(cat == SecurityCategory::UNSAFE){
99
100
		_out << access->address() << "\t";
		switch(access->kind()){
101
102
103
			case otawa::icache::NONE: _out << "NONE\t"; break;
			case otawa::icache::FETCH: _out << "FETCH\t"; break;
			case otawa::icache::PREFETCH: _out << "PREFETCH\t"; break;
104
		}
105
			_out << "UNSAFE ";
106
			int set = otawa::icat3::LBLOCK(access)->set();
107
			if (bb->hasProp(EXIST_HIT_PREV_IN)) {
108
			  ACSSecurity prev = (*EXIST_HIT_PREV_IN(bb))[set];
109
			  for (int i = 0; i < prev.size(); ++i)
110
			    _out << prev[i];
111
			}
112
113
		
	        
114
       		  _out << "\t\t";
115
116
		_out << "BB " << bb->index() << "\t\t";
		printLine(ws, bb->address(), bb->topAddress().offset());
117
		_out << io::endl;}
118
119
120
121
122
123
124
125
126
127
128
129
130
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
	}

	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;
};

161
162
163
p::declare SecurityDisplayer::reg = p::init("lrusecurity::SecurityDisplayer", Version(1, 0, 0))
	.require(SECURITY_CATEGORY_FEATURE)
	.make<SecurityDisplayer>();
164

165
} // namespace lrusecurity
166