blob: 679119050abc7a36bdaf22bdfaea00fb0bde44e9 [file] [log] [blame]
José Fonseca7e329022010-11-19 17:05:18 +00001/**************************************************************************
2 *
3 * Copyright 2010 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 *
24 **************************************************************************/
25
Jose Fonseca9653f952015-05-19 16:32:43 +010026#pragma once
José Fonseca7e329022010-11-19 17:05:18 +000027
28
José Fonseca7e329022010-11-19 17:05:18 +000029#include <iostream>
José Fonseca89851d02010-11-28 12:16:52 +000030#include <list>
José Fonseca7e329022010-11-19 17:05:18 +000031
Zack Rusin712429a2011-08-25 23:22:30 -040032#include "trace_file.hpp"
José Fonseca7e329022010-11-19 17:05:18 +000033#include "trace_format.hpp"
34#include "trace_model.hpp"
José Fonseca67964382012-03-27 23:54:30 +010035#include "trace_api.hpp"
José Fonseca7e329022010-11-19 17:05:18 +000036
37
José Fonsecab4a3d142011-10-27 07:43:19 +010038namespace trace {
José Fonseca7e329022010-11-19 17:05:18 +000039
José Fonseca61e61f72011-09-11 16:53:34 +010040
41struct ParseBookmark
42{
43 File::Offset offset;
44 unsigned next_call_no;
45};
46
47
Jon Ashburn9459abf2014-09-04 23:03:37 +010048// Parser interface
49class AbstractParser
50{
51public:
52 virtual ~AbstractParser() {}
53 virtual Call *parse_call(void) = 0;
54 virtual void getBookmark(ParseBookmark &bookmark) = 0;
55 virtual void setBookmark(const ParseBookmark &bookmark) = 0;
56 virtual bool open(const char *filename) = 0;
57 virtual void close(void) = 0;
58 virtual unsigned long long getVersion(void) const = 0;
Jose Fonsecac110dbc2017-06-23 13:04:17 +010059 virtual const Properties & getProperties(void) const = 0;
60
61 const std::string & getProperty(const char *name) const;
Jon Ashburn9459abf2014-09-04 23:03:37 +010062};
63
64
65class Parser: public AbstractParser
José Fonseca7e329022010-11-19 17:05:18 +000066{
67protected:
Jose Fonsecae8a5de72017-06-22 15:18:52 +010068 File *file = nullptr;
José Fonsecafa922142010-11-25 09:36:04 +000069
José Fonsecae2d65222011-09-11 22:04:07 +010070 enum Mode {
71 FULL = 0,
72 SCAN,
73 SKIP
74 };
75
Jose Fonsecac110dbc2017-06-23 13:04:17 +010076 Properties properties;
77
José Fonseca19828972010-11-29 20:34:32 +000078 typedef std::list<Call *> CallList;
79 CallList calls;
José Fonseca34957132010-11-25 16:14:45 +000080
José Fonseca340f5692011-11-30 07:04:44 +000081 struct FunctionSigFlags : public FunctionSig {
82 CallFlags flags;
83 };
84
José Fonseca6a6d3e42011-09-11 14:14:21 +010085 // Helper template that extends a base signature structure, with additional
86 // parsing information.
87 template< class T >
88 struct SigState : public T {
89 // Offset in the file of where signature was defined. It is used when
90 // reparsing to determine whether the signature definition is to be
91 // expected next or not.
José Fonseca9c25e062013-05-06 07:25:40 +010092 File::Offset fileOffset;
José Fonseca6a6d3e42011-09-11 14:14:21 +010093 };
94
José Fonseca340f5692011-11-30 07:04:44 +000095 typedef SigState<FunctionSigFlags> FunctionSigState;
José Fonseca6a6d3e42011-09-11 14:14:21 +010096 typedef SigState<StructSig> StructSigState;
97 typedef SigState<EnumSig> EnumSigState;
98 typedef SigState<BitmaskSig> BitmaskSigState;
José Fonseca9c25e062013-05-06 07:25:40 +010099 typedef SigState<StackFrame> StackFrameState;
José Fonseca6a6d3e42011-09-11 14:14:21 +0100100
101 typedef std::vector<FunctionSigState *> FunctionMap;
102 typedef std::vector<StructSigState *> StructMap;
103 typedef std::vector<EnumSigState *> EnumMap;
104 typedef std::vector<BitmaskSigState *> BitmaskMap;
José Fonseca9c25e062013-05-06 07:25:40 +0100105 typedef std::vector<StackFrameState *> StackFrameMap;
José Fonseca6a6d3e42011-09-11 14:14:21 +0100106
José Fonseca19828972010-11-29 20:34:32 +0000107 FunctionMap functions;
José Fonseca19828972010-11-29 20:34:32 +0000108 StructMap structs;
José Fonseca19828972010-11-29 20:34:32 +0000109 EnumMap enums;
José Fonseca19828972010-11-29 20:34:32 +0000110 BitmaskMap bitmasks;
José Fonseca9c25e062013-05-06 07:25:40 +0100111 StackFrameMap frames;
José Fonsecad35973c2010-11-26 14:14:45 +0000112
José Fonseca340f5692011-11-30 07:04:44 +0000113
Jose Fonsecae8a5de72017-06-22 15:18:52 +0100114 FunctionSig *glGetErrorSig = nullptr;
José Fonseca34957132010-11-25 16:14:45 +0000115
Jose Fonsecae8a5de72017-06-22 15:18:52 +0100116 int next_event_type = -1;
117 unsigned next_call_no = 0;
118
119 unsigned long long version = 0;
120 unsigned long long semanticVersion = 0;
121
Jon Ashburn9459abf2014-09-04 23:03:37 +0100122public:
Jose Fonsecae8a5de72017-06-22 15:18:52 +0100123 API api = API_UNKNOWN;
José Fonseca99221832011-03-22 22:15:46 +0000124
José Fonseca57dbaf52011-04-10 14:45:43 +0100125 Parser();
José Fonseca7e329022010-11-19 17:05:18 +0000126
José Fonseca57dbaf52011-04-10 14:45:43 +0100127 ~Parser();
José Fonseca6f51d3b2010-11-22 19:56:19 +0000128
Jose Fonseca697391f2016-03-05 14:44:37 +0000129 bool open(const char *filename) override;
José Fonseca7e329022010-11-19 17:05:18 +0000130
Jose Fonseca697391f2016-03-05 14:44:37 +0000131 void close(void) override;
José Fonseca7e329022010-11-19 17:05:18 +0000132
Jose Fonseca697391f2016-03-05 14:44:37 +0000133 Call *parse_call(void) override {
José Fonsecae2d65222011-09-11 22:04:07 +0100134 return parse_call(FULL);
135 }
José Fonseca7e329022010-11-19 17:05:18 +0000136
Zack Rusin712429a2011-08-25 23:22:30 -0400137 bool supportsOffsets() const
138 {
Zack Rusin7c767752011-09-01 11:33:51 -0400139 return file->supportsOffsets();
Zack Rusin712429a2011-08-25 23:22:30 -0400140 }
141
Jose Fonseca697391f2016-03-05 14:44:37 +0000142 void getBookmark(ParseBookmark &bookmark) override;
Zack Rusin712429a2011-08-25 23:22:30 -0400143
Jose Fonseca697391f2016-03-05 14:44:37 +0000144 void setBookmark(const ParseBookmark &bookmark) override;
Zack Rusine0df9522011-09-01 01:50:56 -0400145
Jose Fonseca697391f2016-03-05 14:44:37 +0000146 unsigned long long getVersion(void) const override {
Jose Fonsecae8a5de72017-06-22 15:18:52 +0100147 return semanticVersion;
Jon Ashburn9459abf2014-09-04 23:03:37 +0100148 }
149
Jose Fonsecac110dbc2017-06-23 13:04:17 +0100150 const Properties & getProperties(void) const override {
151 return properties;
152 }
153
Robert Tarasov67634522020-06-24 16:17:48 -0700154
155 int percentRead() const {
Zack Rusin2b1bd4f2011-09-04 16:14:22 -0400156 return file->percentRead();
157 }
158
Robert Tarasov67634522020-06-24 16:17:48 -0700159 size_t containerSizeInBytes() const {
160 return file->containerSizeInBytes();
161 }
162
163 size_t containerBytesRead() const {
164 return file->containerBytesRead();
165 }
166
167 size_t dataBytesRead() const {
168 return file->dataBytesRead();
169 }
170
171 const char *containerType() const {
172 return file->containerType();
173 }
174
José Fonsecae2d65222011-09-11 22:04:07 +0100175 Call *scan_call() {
176 return parse_call(SCAN);
177 }
Zack Rusin46c4a322011-09-02 01:08:49 -0400178
José Fonseca57dbaf52011-04-10 14:45:43 +0100179protected:
José Fonsecae2d65222011-09-11 22:04:07 +0100180 Call *parse_call(Mode mode);
181
José Fonseca340f5692011-11-30 07:04:44 +0000182 FunctionSigFlags *parse_function_sig(void);
José Fonseca6a6d3e42011-09-11 14:14:21 +0100183 StructSig *parse_struct_sig();
José Fonsecaeb644512011-12-11 10:33:55 +0000184 EnumSig *parse_old_enum_sig();
José Fonseca6a6d3e42011-09-11 14:14:21 +0100185 EnumSig *parse_enum_sig();
186 BitmaskSig *parse_bitmask_sig();
José Fonsecae2d65222011-09-11 22:04:07 +0100187
Jose Fonsecade9621f2015-08-14 00:10:21 +0100188public:
José Fonseca340f5692011-11-30 07:04:44 +0000189 static CallFlags
190 lookupCallFlags(const char *name);
191
Jose Fonsecade9621f2015-08-14 00:10:21 +0100192protected:
Jose Fonsecac110dbc2017-06-23 13:04:17 +0100193 void parseProperties(void);
194
José Fonsecae2d65222011-09-11 22:04:07 +0100195 Call *parse_Call(Mode mode);
José Fonseca6a6d3e42011-09-11 14:14:21 +0100196
José Fonsecae2d65222011-09-11 22:04:07 +0100197 void parse_enter(Mode mode);
Zack Rusin46c4a322011-09-02 01:08:49 -0400198
José Fonsecae2d65222011-09-11 22:04:07 +0100199 Call *parse_leave(Mode mode);
Zack Rusin46c4a322011-09-02 01:08:49 -0400200
José Fonsecae2d65222011-09-11 22:04:07 +0100201 bool parse_call_details(Call *call, Mode mode);
Zack Rusin46c4a322011-09-02 01:08:49 -0400202
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400203 bool parse_call_backtrace(Call *call, Mode mode);
José Fonseca9c25e062013-05-06 07:25:40 +0100204 StackFrame * parse_backtrace_frame(Mode mode);
Eugene Velesevichaa1b2132013-04-23 17:56:14 +0400205
José Fonseca340f5692011-11-30 07:04:44 +0000206 void adjust_call_flags(Call *call);
207
José Fonsecae2d65222011-09-11 22:04:07 +0100208 void parse_arg(Call *call, Mode mode);
Zack Rusin46c4a322011-09-02 01:08:49 -0400209
José Fonseca838decf2011-09-11 14:44:41 +0100210 Value *parse_value(void);
Zack Rusin46c4a322011-09-02 01:08:49 -0400211 void scan_value(void);
José Fonsecae2d65222011-09-11 22:04:07 +0100212 inline Value *parse_value(Mode mode) {
213 if (mode == FULL) {
214 return parse_value();
215 } else {
216 scan_value();
217 return NULL;
218 }
219 }
Zack Rusin46c4a322011-09-02 01:08:49 -0400220
José Fonseca838decf2011-09-11 14:44:41 +0100221 Value *parse_sint();
Zack Rusin46c4a322011-09-02 01:08:49 -0400222 void scan_sint();
223
José Fonseca838decf2011-09-11 14:44:41 +0100224 Value *parse_uint();
Zack Rusin46c4a322011-09-02 01:08:49 -0400225 void scan_uint();
226
José Fonseca838decf2011-09-11 14:44:41 +0100227 Value *parse_float();
Zack Rusin46c4a322011-09-02 01:08:49 -0400228 void scan_float();
229
José Fonseca838decf2011-09-11 14:44:41 +0100230 Value *parse_double();
Zack Rusin46c4a322011-09-02 01:08:49 -0400231 void scan_double();
232
José Fonseca838decf2011-09-11 14:44:41 +0100233 Value *parse_string();
Zack Rusin46c4a322011-09-02 01:08:49 -0400234 void scan_string();
235
José Fonseca838decf2011-09-11 14:44:41 +0100236 Value *parse_enum();
Zack Rusin46c4a322011-09-02 01:08:49 -0400237 void scan_enum();
238
José Fonseca838decf2011-09-11 14:44:41 +0100239 Value *parse_bitmask();
Zack Rusin46c4a322011-09-02 01:08:49 -0400240 void scan_bitmask();
241
José Fonseca838decf2011-09-11 14:44:41 +0100242 Value *parse_array(void);
Zack Rusin46c4a322011-09-02 01:08:49 -0400243 void scan_array(void);
244
José Fonseca838decf2011-09-11 14:44:41 +0100245 Value *parse_blob(void);
Zack Rusin46c4a322011-09-02 01:08:49 -0400246 void scan_blob(void);
247
José Fonseca838decf2011-09-11 14:44:41 +0100248 Value *parse_struct();
Zack Rusin46c4a322011-09-02 01:08:49 -0400249 void scan_struct();
250
José Fonseca838decf2011-09-11 14:44:41 +0100251 Value *parse_opaque();
Zack Rusin46c4a322011-09-02 01:08:49 -0400252 void scan_opaque();
253
José Fonseca112a1322012-04-27 17:15:32 +0100254 Value *parse_repr();
255 void scan_repr();
256
José Fonsecad5cda7c2014-09-25 15:19:09 +0100257 Value *parse_wstring();
258 void scan_wstring();
259
Jose Fonsecac110dbc2017-06-23 13:04:17 +0100260 char * read_string(void);
Zack Rusin46c4a322011-09-02 01:08:49 -0400261 void skip_string(void);
262
José Fonsecaeb644512011-12-11 10:33:55 +0000263 signed long long read_sint(void);
264 void skip_sint(void);
265
José Fonseca838decf2011-09-11 14:44:41 +0100266 unsigned long long read_uint(void);
Zack Rusin46c4a322011-09-02 01:08:49 -0400267 void skip_uint(void);
268
José Fonseca838decf2011-09-11 14:44:41 +0100269 inline int read_byte(void);
Zack Rusin46c4a322011-09-02 01:08:49 -0400270 inline void skip_byte(void);
José Fonseca7e329022010-11-19 17:05:18 +0000271};
272
273
Robert Tarasovf41a37c2019-09-20 13:14:29 -0700274struct FrameSpan {
275 typedef unsigned long frame_t;
276 FrameSpan(frame_t begin_, frame_t end_)
277 : begin(begin_), end(end_) {}
278 FrameSpan(const FrameSpan &other)
279 : begin(other.begin), end(other.end) {}
280 frame_t begin;
281 frame_t end;
282};
283
284typedef std::vector<FrameSpan> FrameSpanArray;
285
Jose Fonseca0c287892015-10-14 14:19:01 +0100286AbstractParser *
Robert Tarasov80624902019-09-16 18:24:15 -0700287loopParser(AbstractParser *parser,
Robert Tarasovf41a37c2019-09-20 13:14:29 -0700288 const FrameSpan &loop_span,
289 unsigned long loop_repeat_count);
Jon Ashburn9459abf2014-09-04 23:03:37 +0100290
José Fonsecab4a3d142011-10-27 07:43:19 +0100291} /* namespace trace */
José Fonseca7e329022010-11-19 17:05:18 +0000292