1 | /* |
2 | * Copyright (c) 2015-2018, Intel Corporation |
3 | * |
4 | * Redistribution and use in source and binary forms, with or without |
5 | * modification, are permitted provided that the following conditions are met: |
6 | * |
7 | * * Redistributions of source code must retain the above copyright notice, |
8 | * this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of Intel Corporation nor the names of its contributors |
13 | * may be used to endorse or promote products derived from this software |
14 | * without specific prior written permission. |
15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
26 | * POSSIBILITY OF SUCH DAMAGE. |
27 | */ |
28 | |
29 | /** \file |
30 | * \brief ReportManager: tracks Report structures, exhaustion and |
31 | * dedupe keys. |
32 | */ |
33 | |
34 | #ifndef REPORT_MANAGER_H |
35 | #define REPORT_MANAGER_H |
36 | |
37 | #include "ue2common.h" |
38 | #include "util/compile_error.h" |
39 | #include "util/noncopyable.h" |
40 | #include "util/report.h" |
41 | #include "parser/logical_combination.h" |
42 | |
43 | #include <map> |
44 | #include <set> |
45 | #include <unordered_map> |
46 | #include <vector> |
47 | |
48 | namespace ue2 { |
49 | |
50 | struct Grey; |
51 | class RoseBuild; |
52 | class ExpressionInfo; |
53 | |
54 | struct external_report_info { |
55 | external_report_info(bool h, u32 fpi) |
56 | : highlander(h), first_pattern_index(fpi) { } |
57 | const bool highlander; |
58 | const u32 first_pattern_index; |
59 | }; |
60 | |
61 | /** \brief Tracks Report structures, exhaustion and dedupe keys. */ |
62 | class ReportManager : noncopyable { |
63 | public: |
64 | explicit ReportManager(const Grey &g); |
65 | |
66 | /** \brief Fetch the ID associated with the given Report. */ |
67 | u32 getInternalId(const Report &r); |
68 | |
69 | /** \brief Fetch the Report associated with \a id. */ |
70 | const Report &getReport(u32 id) const; |
71 | |
72 | /** \brief Total number of reports. */ |
73 | size_t numReports() const; |
74 | |
75 | /** \brief Return an unused exhaustion key (the next available one). */ |
76 | u32 getUnassociatedExhaustibleKey(void); |
77 | |
78 | /** \brief Total number of dedupe keys. */ |
79 | u32 numDkeys() const; |
80 | |
81 | /** \brief Total number of exhaustion keys. */ |
82 | u32 numEkeys() const; |
83 | |
84 | /** \brief Total number of logical keys. */ |
85 | u32 numLogicalKeys() const; |
86 | |
87 | /** \brief Total number of logical operators. */ |
88 | u32 numLogicalOps() const; |
89 | |
90 | /** \brief Total number of combination keys. */ |
91 | u32 numCkeys() const; |
92 | |
93 | /** \brief True if the pattern set can exhaust (i.e. all patterns are |
94 | * highlander). */ |
95 | bool patternSetCanExhaust() const; |
96 | |
97 | void assignDkeys(const RoseBuild *rose); |
98 | |
99 | std::vector<ReportID> getDkeyToReportTable() const; |
100 | |
101 | /** \brief Return a const reference to the table of Report |
102 | * structures. */ |
103 | const std::vector<Report> &reports() const { return reportIds; } |
104 | |
105 | /** |
106 | * Get a simple internal report corresponding to the expression. An ekey |
107 | * will be setup if required. |
108 | * |
109 | * Note: this function may throw a CompileError if constraints on external |
110 | * match id are violated (mixed highlander status for example). |
111 | */ |
112 | Report getBasicInternalReport(const ExpressionInfo &expr, s32 adj = 0); |
113 | |
114 | /** \brief Register an external report and validate that we are not |
115 | * violating highlander constraints (which will cause an exception to be |
116 | * thrown). */ |
117 | void registerExtReport(ReportID id, const external_report_info &ext); |
118 | |
119 | /** \brief Fetch the ekey associated with the given expression index, |
120 | * assigning one if necessary. */ |
121 | u32 getExhaustibleKey(u32 expressionIndex); |
122 | |
123 | /** \brief Get lkey's corresponding ckeys. */ |
124 | const std::set<u32> &getRelateCKeys(u32 lkey); |
125 | |
126 | /** \brief Renumber lkey for logical operations, after parsed |
127 | * all logical expressions. */ |
128 | void logicalKeyRenumber(); |
129 | |
130 | /** \brief Used in Rose for writing bytecode. */ |
131 | const std::vector<LogicalOp> &getLogicalTree() const; |
132 | |
133 | /** \brief Used in Rose for writing bytecode. */ |
134 | const std::vector<CombInfo> &getCombInfoMap() const; |
135 | |
136 | /** \brief Fetch the dedupe key associated with the given report. Returns |
137 | * ~0U if no dkey is needed. */ |
138 | u32 getDkey(const Report &r) const; |
139 | |
140 | /** \brief Register a Rose program offset with the given report. */ |
141 | void setProgramOffset(ReportID id, u32 programOffset); |
142 | |
143 | /** \brief Fetch the program offset for a given report. It is a fatal error |
144 | * for this to be called with a report for which no program offset has been |
145 | * set. */ |
146 | u32 getProgramOffset(ReportID id) const; |
147 | |
148 | /** \brief Parsed logical combination structure. */ |
149 | ParsedLogical pl; |
150 | |
151 | private: |
152 | /** \brief Grey box ref, for checking resource limits. */ |
153 | const Grey &grey; |
154 | |
155 | /** \brief Report structures, indexed by ID. */ |
156 | std::vector<Report> reportIds; |
157 | |
158 | /** \brief Mapping from Report to ID (inverse of \ref reportIds |
159 | * vector). */ |
160 | std::unordered_map<Report, size_t> reportIdToInternalMap; |
161 | |
162 | /** \brief Mapping from ReportID to dedupe key. */ |
163 | std::unordered_map<ReportID, u32> reportIdToDedupeKey; |
164 | |
165 | /** \brief Mapping from ReportID to Rose program offset in bytecode. */ |
166 | std::unordered_map<ReportID, u32> reportIdToProgramOffset; |
167 | |
168 | /** \brief Mapping from external match ids to information about that |
169 | * id. */ |
170 | std::unordered_map<ReportID, external_report_info> externalIdMap; |
171 | |
172 | /** \brief Mapping from expression index to exhaustion key. */ |
173 | std::map<s64a, u32> toExhaustibleKeyMap; |
174 | |
175 | /** \brief Unallocated expression index, used for \ref |
176 | * getUnassociatedExhaustibleKey. |
177 | * |
178 | * TODO: work out why this is signed. |
179 | */ |
180 | s64a freeEIndex; |
181 | |
182 | /** \brief True if database is globally exhaustible (all patterns must be |
183 | * highlander for this to be the case). */ |
184 | bool global_exhaust; |
185 | }; |
186 | |
187 | std::set<u32> reportsToEkeys(const std::set<ReportID> &reports, |
188 | const ReportManager &rm); |
189 | |
190 | } // namespace ue2 |
191 | |
192 | #endif |
193 | |