genevent update
[lttv.git] / genevent / genevent.c
CommitLineData
3888436c 1/*
2
3genevent.c: Generate helper declarations and functions to trace events
4 from an event description file.
5
6Copyright (C) 2002, Xianxiu Yang
7Copyright (C) 2002, Michel Dagenais
8
9This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11the Free Software Foundation; version 2 of the License.
12
13This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21*/
22
23/* This program reads the ".event" event definitions input files
24 specified as command line arguments and generates corresponding
25 ".c" and ".h" files required to trace such events in the kernel.
26
27 The program uses a very simple tokenizer, called from a hand written
28 recursive descent parser to fill a data structure describing the events.
29 The result is a sequence of events definitions which refer to type
30 definitions.
31
32 A table of named types is maintained to allow refering to types by name
33 when the same type is used at several places. Finally a sequence of
34 all types is maintained to facilitate the freeing of all type
35 information when the processing of an ".event" file is finished. */
36
37#include <stdlib.h>
38#include <string.h>
31cbc5d3 39#include <ctype.h>
3888436c 40#include <stdio.h>
41#include <stdarg.h>
42#include <linux/errno.h>
d7ed29cd 43#include <assert.h>
3888436c 44
45#include "parser.h"
46#include "genevent.h"
47
48/* Named types may be referenced from anywhere */
49
50facility * fac;
51
52int main(int argc, char** argv)
53{
54 char *token;
55 parse_file in;
56 char buffer[BUFFER_SIZE];
57 int i;
58
59 if(argc < 2){
60 printf("At least one event definition file is needed\n");
61 exit(1);
62 }
63
64 in.buffer = buffer;
65 in.error = error_callback;
66
67 for(i = 1 ; i < argc ; i++) {
68 in.lineno = 0;
69 in.name = allocAndCopy(argv[i]);
70
71 in.fp = fopen(in.name, "r");
72 if(!in.fp ){
73 in.error(&in,"cannot open facility input file");
74 }
75
76 while(1){
77 token = getToken(&in);
78 if(in.type == ENDFILE) break;
79
80 if(strcmp(token, "<")) in.error(&in,"not a facility file");
81 token = getName(&in);
82
83 if(strcmp("facility",token) == 0) {
a8f6f123 84 fac = memAlloc(sizeof(facility));
85 fac->name = NULL;
86 fac->description = NULL;
87 sequence_init(&(fac->events));
88 table_init(&(fac->named_types));
89 sequence_init(&(fac->unnamed_types));
90
91 parseFacility(&in, fac);
92
93 //check if any namedType is not defined
94 checkNamedTypesImplemented(&fac->named_types);
31cbc5d3 95 }
a8f6f123 96 else in.error(&in,"facility token was expected");
3888436c 97
98 generateFile(argv[i]);
99
100 free(fac->name);
101 free(fac->description);
102 freeEvents(&fac->events);
103 sequence_dispose(&fac->events);
104 freeNamedType(&fac->named_types);
105 table_dispose(&fac->named_types);
106 freeTypes(&fac->unnamed_types);
107 sequence_dispose(&fac->unnamed_types);
108 free(fac);
109 }
110
111 free(in.name);
112 fclose(in.fp);
113
114 }
115 return 0;
116}
117
118
119/*****************************************************************************
120 *Function name
121 * generateFile : generate .c and .h file
122 *Input Params
123 * name : name of event definition file
124 ****************************************************************************/
125void generateFile(char *name){
a8f6f123 126 char *loadName, *hName, *hIdName, *cName, *tmp, *tmp2;
127 FILE * lFp, *hFp, *iFp, *cFp;
3888436c 128 int nbEvent;
129 unsigned long checksum=0;
130
131 //remove .xml if it exists
132 tmp = &name[strlen(name)-4];
133 if(strcmp(tmp, ".xml") == 0){
134 *tmp = '\0';
135 }
136
137 tmp = strrchr(name,'/');
138 if(tmp){
139 tmp++;
140 }else{
141 tmp = name;
142 }
6d387597 143
144 loadName = appendString("ltt-facility-loader-", tmp);
145 tmp2 = appendString(loadName,".h");
146 free(loadName);
147 loadName = tmp2;
148 hName = appendString("ltt-facility-", tmp);
149 tmp2 = appendString(hName,".h");
150 free(hName);
151 hName = tmp2;
a8f6f123 152 hIdName = appendString("ltt-facility-id-", tmp);
153 tmp2 = appendString(hIdName,".h");
154 free(hIdName);
155 hIdName = tmp2;
156 cName = appendString("ltt-facility-loader-", tmp);
157 tmp2 = appendString(cName,".c");
158 free(cName);
159 cName = tmp2;
6d387597 160 lFp = fopen(loadName,"w");
161 if(!lFp){
162 printf("Cannot open the file : %s\n",loadName);
3888436c 163 exit(1);
164 }
165
166 hFp = fopen(hName,"w");
167 if(!hFp){
168 printf("Cannot open the file : %s\n",hName);
169 exit(1);
170 }
a8f6f123 171
172 iFp = fopen(hIdName,"w");
173 if(!iFp){
174 printf("Cannot open the file : %s\n",hIdName);
175 exit(1);
176 }
177
178 cFp = fopen(cName,"w");
179 if(!cFp){
180 printf("Cannot open the file : %s\n",cName);
181 exit(1);
182 }
3888436c 183
6d387597 184 free(loadName);
3888436c 185 free(hName);
a8f6f123 186 free(hIdName);
187 free(cName);
3888436c 188
189 generateChecksum(fac->name, &checksum, &(fac->events));
190
191 /* generate .h file, event enumeration then structures and functions */
a8f6f123 192 fprintf(iFp, "#ifndef _LTT_FACILITY_ID_%s_H_\n",fac->capname);
193 fprintf(iFp, "#define _LTT_FACILITY_ID_%s_H_\n\n",fac->capname);
1bedc199 194 fprintf(iFp, "#ifdef CONFIG_LTT\n");
a8f6f123 195 generateEnumEvent(iFp, fac->name, &nbEvent, checksum);
1bedc199 196 fprintf(iFp, "#endif //CONFIG_LTT\n");
a8f6f123 197 fprintf(iFp, "#endif //_LTT_FACILITY_ID_%s_H_\n",fac->capname);
198
199
200 fprintf(hFp, "#ifndef _LTT_FACILITY_%s_H_\n",fac->capname);
201 fprintf(hFp, "#define _LTT_FACILITY_%s_H_\n\n",fac->capname);
1bedc199 202 //fprintf(hFp, "#ifdef CONFIG_LTT\n");
a8f6f123 203 generateTypeDefs(hFp, fac->name);
31cbc5d3 204 generateStructFunc(hFp, fac->name,checksum);
1bedc199 205 //fprintf(hFp, "#endif //CONFIG_LTT\n");
a8f6f123 206 fprintf(hFp, "#endif //_LTT_FACILITY_%s_H_\n",fac->capname);
3888436c 207
6d387597 208 /* generate .h file, calls to register the facility at init time */
8c6ca411 209 generateLoaderfile(lFp,fac->name,nbEvent,checksum,fac->capname);
3888436c 210
a8f6f123 211 // create ltt-facility-loader-facname.c
212 generateCfile(cFp, tmp);
213
3888436c 214 fclose(hFp);
a8f6f123 215 fclose(iFp);
6d387597 216 fclose(lFp);
a8f6f123 217 fclose(cFp);
218
3888436c 219}
220
221
222/*****************************************************************************
223 *Function name
224 * generateEnumEvent : output event enum to .h file
225 *Input Params
226 * fp : file to be written to
227 * facName : name of facility
228 *Output Params
229 * nbEvent : number of events in the facility
230 ****************************************************************************/
31cbc5d3 231void generateEnumEvent(FILE *fp, char *facName, int * nbEvent, unsigned long checksum) {
3888436c 232 int pos = 0;
233
a8f6f123 234 fprintf(fp,"#include <linux/ltt-facilities.h>\n\n");
3888436c 235
236 fprintf(fp,"/**** facility handle ****/\n\n");
a8f6f123 237 fprintf(fp,"extern ltt_facility_t ltt_facility_%s_%X;\n",facName, checksum);
238 fprintf(fp,"extern ltt_facility_t ltt_facility_%s;\n\n\n",facName, checksum);
3888436c 239
240 fprintf(fp,"/**** event type ****/\n\n");
241 fprintf(fp,"enum %s_event {\n",facName);
242
243 for(pos = 0; pos < fac->events.position;pos++) {
a8f6f123 244 fprintf(fp,"\tevent_%s", ((event *)(fac->events.array[pos]))->name);
3888436c 245 if(pos != fac->events.position-1) fprintf(fp,",\n");
246 }
247 fprintf(fp,"\n};\n\n\n");
248
249 // fprintf(fp,"/**** number of events in the facility ****/\n\n");
250 // fprintf(fp,"int nbEvents_%s = %d;\n\n\n",facName, fac->events.position);
251 *nbEvent = fac->events.position;
252}
253
254
31cbc5d3 255/*****************************************************************************
256 *Function name
257 * printStruct : Generic struct printing function
258 *Input Params
259 * fp : file to be written to
260 * len : number of fields
261 * array : array of field info
262 * name : basic struct name
263 * facName : name of facility
264 * whichTypeFirst : struct or array/sequence first
265 * hasStrSeq : string or sequence present?
266 * structCount : struct postfix
267 ****************************************************************************/
cb1eb7ce 268
31cbc5d3 269static void
270printStruct(FILE * fp, int len, void ** array, char * name, char * facName,
a8f6f123 271 int * whichTypeFirst, int * hasStrSeq, int * structCount)
31cbc5d3 272{
273 int flag = 0;
274 int pos;
275 field * fld;
276 type_descriptor * td;
277
278 for (pos = 0; pos < len; pos++) {
279 fld = (field *)array[pos];
280 td = fld->type;
a8f6f123 281 if( td->type == STRING || td->type == SEQUENCE ||
282 td->type == ARRAY) {
283 (*hasStrSeq)++;
284 }
285// if (*whichTypeFirst == 0) {
286// *whichTypeFirst = 1; //struct first
287// }
31cbc5d3 288 if (flag == 0) {
289 flag = 1;
290
cb1eb7ce 291 fprintf(fp,"struct %s_%s",name, facName);
292 if (structCount) {
a8f6f123 293 fprintf(fp, "_%d {\n",++*structCount);
cb1eb7ce 294 } else {
295 fprintf(fp, " {\n");
296 }
31cbc5d3 297 }
cb1eb7ce 298 fprintf(fp, "\t%s %s; /* %s */\n",
299 getTypeStr(td),fld->name,fld->description );
a8f6f123 300#if 0
31cbc5d3 301 } else {
cb1eb7ce 302 if (*whichTypeFirst == 0) {
31cbc5d3 303 //string or sequence or array first
cb1eb7ce 304 *whichTypeFirst = 2;
305 }
306 (*hasStrSeq)++;
307 if(flag) {
308 fprintf(fp,"} __attribute__ ((packed));\n\n");
309 }
310 flag = 0;
31cbc5d3 311 }
a8f6f123 312#endif //0
31cbc5d3 313 }
314
315 if(flag) {
316 fprintf(fp,"} __attribute__ ((packed));\n\n");
317 }
318}
319
320
321/*****************************************************************************
322 *Function name
323 * generateHfile : Create the typedefs
324 *Input Params
325 * fp : file to be written to
326 ****************************************************************************/
327void
a8f6f123 328generateTypeDefs(FILE * fp, char *facName)
31cbc5d3 329{
330 int pos, tmp = 1;
331
a8f6f123 332 fprintf(fp,"#include <linux/types.h>\n");
333 fprintf(fp,"#include <linux/spinlock.h>\n");
334 fprintf(fp,"#include <linux/ltt/ltt-facility-id-%s.h>\n\n", facName);
335 fprintf(fp,"#include <linux/ltt-core.h>\n");
336
31cbc5d3 337 fprintf(fp, "/**** Basic Type Definitions ****/\n\n");
338
339 for (pos = 0; pos < fac->named_types.values.position; pos++) {
340 type_descriptor * type =
341 (type_descriptor*)fac->named_types.values.array[pos];
342 printStruct(fp, type->fields.position, type->fields.array,
343 "", type->type_name, &tmp, &tmp, NULL);
344 fprintf(fp, "typedef struct _%s %s;\n\n",
345 type->type_name, type->type_name);
346 }
347}
348
349
3888436c 350/*****************************************************************************
351 *Function name
352 * generateEnumDefinition: generate enum definition if it exists
353 *Input Params
354 * fp : file to be written to
355 * fHead : enum type
356 ****************************************************************************/
357void generateEnumDefinition(FILE * fp, type_descriptor * type){
358 int pos;
359
a8f6f123 360 if(type->already_printed) return;
361
3888436c 362 fprintf(fp,"enum {\n");
363 for(pos = 0; pos < type->labels.position; pos++){
a8f6f123 364 fprintf(fp,"\tLTT_ENUM_%s", type->labels.array[pos]);
8c6ca411 365 if (pos != type->labels.position - 1) fprintf(fp,",");
a8f6f123 366 if(type->labels_description.array[pos] != NULL)
367 fprintf(fp,"\t/* %s */\n",type->labels_description.array[pos]);
368 else
369 fprintf(fp,"\n");
3888436c 370 }
8c6ca411 371 fprintf(fp,"};\n\n\n");
44cac8a9 372
a8f6f123 373 type->already_printed = 1;
3888436c 374}
375
376/*****************************************************************************
377 *Function name
378 * generateStrucTFunc: output structure and function to .h file
379 *Input Params
380 * fp : file to be written to
381 * facName : name of facility
382 ****************************************************************************/
31cbc5d3 383void generateStructFunc(FILE * fp, char * facName, unsigned long checksum){
3888436c 384 event * ev;
385 field * fld;
386 type_descriptor * td;
387 int pos, pos1;
388 int hasStrSeq, flag, structCount, seqCount,strCount, whichTypeFirst=0;
389
390 for(pos = 0; pos < fac->events.position; pos++){
391 ev = (event *) fac->events.array[pos];
392 //yxx if(ev->nested)continue;
d7ed29cd 393 fprintf(fp,"/**** structure and trace function for event: %s ****/\n\n",
394 ev->name);
a8f6f123 395 //if(ev->type == 0){ // event without type
396 // fprintf(fp,"static inline void trace_%s_%s(void){\n",facName,ev->name);
397 // fprintf(fp,"\tltt_log_event(ltt_facility_%s_%X, event_%s, 0, NULL);\n",
398 // facName,checksum,ev->name);
399 // fprintf(fp,"};\n\n\n");
400 // continue;
401 //}
3888436c 402
403 //if fields contain enum, print out enum definition
d7ed29cd 404 //MD : fixed in generateEnumDefinition to do not print the same enum
405 //twice.
a8f6f123 406 if(ev->type != 0)
407 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
408 fld = (field *)ev->type->fields.array[pos1];
409 if(fld->type->type == ENUM) generateEnumDefinition(fp, fld->type);
410 }
3888436c 411
412 //default: no string, array or sequence in the event
413 hasStrSeq = 0;
414 whichTypeFirst = 0;
3888436c 415 structCount = 0;
31cbc5d3 416
417 //structure for kernel
a8f6f123 418 if(ev->type != 0)
419 printStruct(fp, ev->type->fields.position, ev->type->fields.array,
420 ev->name, facName, &whichTypeFirst, &hasStrSeq, &structCount);
3888436c 421
1bedc199 422
423 //trace function : function name and parameters : stub function.
424 seqCount = 0;
425 strCount = 0;
426 fprintf(fp, "#ifndef CONFIG_LTT\n");
427 fprintf(fp,"static inline void trace_%s_%s(",facName,ev->name);
428 if(ev->type == 0)
429 fprintf(fp, "void");
430 else
431 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
432 fld = (field *)ev->type->fields.array[pos1];
433 td = fld->type;
434 if(td->type == ARRAY ){
435 fprintf(fp,"%s * %s",getTypeStr(td), fld->name);
436 }else if(td->type == STRING){
437 fprintf(fp,"short int strlength_%d, %s * %s",
438 ++strCount, getTypeStr(td), fld->name);
439 }else if(td->type == SEQUENCE){
440 fprintf(fp,"%s seqlength_%d, %s * %s",
441 uintOutputTypes[td->size], ++seqCount,getTypeStr(td), fld->name);
442 }else fprintf(fp,"%s %s",getTypeStr(td), fld->name);
443 if(pos1 != ev->type->fields.position - 1) fprintf(fp,", ");
444 }
445 fprintf(fp,")\n{\n");
446 fprintf(fp,"}\n");
447 fprintf(fp,"#else\n");
448
3888436c 449 //trace function : function name and parameters
450 seqCount = 0;
451 strCount = 0;
452 fprintf(fp,"static inline void trace_%s_%s(",facName,ev->name);
a8f6f123 453 if(ev->type == 0)
454 fprintf(fp, "void");
455 else
456 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
457 fld = (field *)ev->type->fields.array[pos1];
458 td = fld->type;
459 if(td->type == ARRAY ){
460 fprintf(fp,"%s * %s",getTypeStr(td), fld->name);
461 }else if(td->type == STRING){
462 fprintf(fp,"short int strlength_%d, %s * %s",
463 ++strCount, getTypeStr(td), fld->name);
464 }else if(td->type == SEQUENCE){
465 fprintf(fp,"%s seqlength_%d, %s * %s",
466 uintOutputTypes[td->size], ++seqCount,getTypeStr(td), fld->name);
467 }else fprintf(fp,"%s %s",getTypeStr(td), fld->name);
468 if(pos1 != ev->type->fields.position - 1) fprintf(fp,", ");
469 }
d7ed29cd 470 fprintf(fp,")\n{\n");
3888436c 471
1bedc199 472
473
3888436c 474 //length of buffer : length of all structures
a8f6f123 475 fprintf(fp,"\tint length = ");
476 if(ev->type == 0) fprintf(fp, "0");
477
3888436c 478 for(pos1=0;pos1<structCount;pos1++){
479 fprintf(fp,"sizeof(struct %s_%s_%d)",ev->name, facName,pos1+1);
480 if(pos1 != structCount-1) fprintf(fp," + ");
481 }
482
483 //length of buffer : length of all arrays, sequences and strings
484 seqCount = 0;
485 strCount = 0;
486 flag = 0;
a8f6f123 487 if(ev->type != 0)
488 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
489 fld = (field *)ev->type->fields.array[pos1];
490 td = fld->type;
491 if(td->type == SEQUENCE || td->type==STRING || td->type==ARRAY){
492 if(structCount || flag > 0) fprintf(fp," + ");
493 if(td->type == SEQUENCE)
494 fprintf(fp,"sizeof(%s) + sizeof(%s) * seqlength_%d",
495 uintOutputTypes[td->size], getTypeStr(td), ++seqCount);
496 else if(td->type==STRING) fprintf(fp,"strlength_%d + 1", ++strCount);
497 else if(td->type==ARRAY)
498 fprintf(fp,"sizeof(%s) * %d", getTypeStr(td),td->size);
499 if(structCount == 0) flag = 1;
500 }
501 }
3888436c 502 fprintf(fp,";\n");
503
504 //allocate buffer
d7ed29cd 505 // MD no more need. fprintf(fp,"\tchar buff[buflength];\n");
506 // write directly to the channel
507 fprintf(fp, "\tunsigned int index;\n");
508 fprintf(fp, "\tstruct ltt_channel_struct *channel;\n");
509 fprintf(fp, "\tstruct ltt_trace_struct *trace;\n");
a8f6f123 510 fprintf(fp, "\tunsigned long _flags;\n");
2f74104a 511 fprintf(fp, "\tvoid *buff;\n");
512 fprintf(fp, "\tunsigned int header_length;\n");
513 fprintf(fp, "\tunsigned int event_length;\n");
514 fprintf(fp, "\tint resret;\n");
1bedc199 515 fprintf(fp, "\tunsigned char _offset;\n");
516 fprintf(fp, "\tstruct rchan_buf *buf;\n");
2f74104a 517
a8f6f123 518 if(ev->type != 0)
519 fprintf(fp, "\tstruct %s_%s_1* __1;\n\n", ev->name, facName);
d7ed29cd 520
1bedc199 521 /* Warning : this is done prior to taking locks :
522 * setting this value must be done at the end of the trace activation.
523 * (we don't care for trace removal, as the list of traces is protected : it
524 * just won't iterate on any trace). */
525 fprintf(fp,
526 "\tif(ltt_traces.num_active_traces == 0) return;\n\n");
527
2f74104a 528 fprintf(fp, "\t/* Disable interrupts. */\n");
529 fprintf(fp, "\tlocal_irq_save(_flags);\n");
530 fprintf(fp, "\tpreempt_disable();\n\n");
531
532 fprintf(fp, "\tltt_nesting[smp_processor_id()]++;\n");
1bedc199 533 fprintf(fp, "\tbarrier();\n");
534 fprintf(fp, "\tif(ltt_nesting[smp_processor_id()] > 1) goto unlock;\n");
2f74104a 535 fprintf(fp, "\tspin_lock(&ltt_traces.locks[smp_processor_id()]);\n\n");
536
d7ed29cd 537 fprintf(fp,
538 "\tindex = ltt_get_index_from_facility(ltt_facility_%s_%X,\n"\
a8f6f123 539 "\t\t\t\tevent_%s);\n",
d7ed29cd 540 facName, checksum, ev->name);
541 fprintf(fp,"\n");
542
a8f6f123 543 /* For each trace */
d7ed29cd 544 fprintf(fp, "\tlist_for_each_entry(trace, &ltt_traces.head, list) {\n");
a8f6f123 545 fprintf(fp, "\t\tif(!trace->active) continue;\n\n");
546
1bedc199 547 fprintf(fp, "\t\tchannel = ltt_get_channel_from_index(trace, index);\n");
548 fprintf(fp, "\t\tbuf = channel->rchan->buf[smp_processor_id()];\n");
549 /* Warning : not atomic reservation : event size depends on the current
550 * address for alignment */
2f74104a 551 fprintf(fp, "\t\theader_length = "
1bedc199 552 "ltt_get_event_header_size(trace, channel,"
553 "buf->data + buf->offset, &_offset);\n");
2f74104a 554 fprintf(fp, "\t\tevent_length = header_length + length;\n");
d7ed29cd 555
556 /* Reserve the channel */
2f74104a 557 fprintf(fp, "\t\tbuff = relay_reserve(channel->rchan, event_length, &resret);\n");
a8f6f123 558 fprintf(fp, "\t\tif(buff == NULL) {\n");
559 fprintf(fp, "\t\t\t/* Buffer is full*/\n");
560 fprintf(fp, "\t\t\t/* for debug BUG(); */\n"); // DEBUG!
561 fprintf(fp, "\t\t\tchannel->events_lost[smp_processor_id()]++;\n");
e3cc790d 562 fprintf(fp, "\t\t\tbreak;\n"); /* don't commit a NULL reservation! */
a8f6f123 563 fprintf(fp, "\t\t}\n");
d7ed29cd 564
a8f6f123 565 /* DEBUG */
2f74104a 566 fprintf(fp, "\t\tif(resret == 1) {\n");
567 fprintf(fp, "printk(\"f%%lu e\%%u \", ltt_facility_%s_%X, event_%s);",
a8f6f123 568 facName, checksum, ev->name);
2f74104a 569 fprintf(fp, "\t\t}\n");
a8f6f123 570
571 /* Write the header */
572 fprintf(fp, "\n");
573 fprintf(fp, "\t\tltt_write_event_header(trace, channel, buff, \n"
1bedc199 574 "\t\t\t\tltt_facility_%s_%X, event_%s, length, _offset);\n",
a8f6f123 575 facName, checksum, ev->name);
576 fprintf(fp, "\n");
577
d7ed29cd 578 //declare a char pointer if needed : starts at the end of the structs.
579 if(structCount + hasStrSeq > 1) {
580 fprintf(fp,"\t\tchar * ptr = (char*)buff + header_length");
581 for(pos1=0;pos1<structCount;pos1++){
582 fprintf(fp," + sizeof(struct %s_%s_%d)",ev->name, facName,pos1+1);
583 }
584 if(structCount + hasStrSeq > 1) fprintf(fp,";\n");
3888436c 585 }
d7ed29cd 586
587 // Declare an alias pointer of the struct type to the beginning
588 // of the reserved area, just after the event header.
a8f6f123 589 if(ev->type != 0)
590 fprintf(fp, "\t\t__1 = (struct %s_%s_1 *)(buff + header_length);\n",
591 ev->name, facName);
d7ed29cd 592 //allocate memory for new struct and initialize it
593 //if(whichTypeFirst == 1){ //struct first
a8f6f123 594 //for(pos1=0;pos1<structCount;pos1++){
595 // if(pos1==0) fprintf(fp,
d7ed29cd 596 // "\tstruct %s_%s_1 * __1 = (struct %s_%s_1 *)buff;\n",
597 // ev->name, facName,ev->name, facName);
598 //MD disabled else fprintf(fp,
599 // "\tstruct %s_%s_%d __%d;\n",
600 // ev->name, facName,pos1+1,pos1+1);
601 //}
602 //}else if(whichTypeFirst == 2){
603 // for(pos1=0;pos1<structCount;pos1++)
a8f6f123 604 // fprintf(fp,"\tstruct %s_%s_%d __%d;\n",
d7ed29cd 605 // ev->name, facName,pos1+1,pos1+1);
606 //}
3888436c 607 fprintf(fp,"\n");
608
d7ed29cd 609 if(structCount) fprintf(fp,"\t\t//initialize structs\n");
610 //flag = 0;
611 //structCount = 0;
a8f6f123 612 if(ev->type != 0)
613 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
614 fld = (field *)ev->type->fields.array[pos1];
615 td = fld->type;
616 if(td->type != ARRAY && td->type != SEQUENCE && td->type != STRING){
617 //if(flag == 0){
618 // flag = 1;
619 // structCount++;
620 // if(structCount > 1) fprintf(fp,"\n");
621 //}
622 fprintf(fp, "\t\t__1->%s = %s;\n", fld->name, fld->name );
623
624 //if(structCount == 1 && whichTypeFirst == 1)
625 // fprintf(fp, "\t__1->%s = %s;\n",fld->name,fld->name );
626 //else
627 // fprintf(fp, "\t__%d.%s = %s;\n",structCount ,fld->name,fld->name);
628 }
629 //else flag = 0;
630 }
631 if(structCount) fprintf(fp,"\n");
3888436c 632 //set ptr to the end of first struct if needed;
1bedc199 633 //if(structCount + hasStrSeq > 1){
634 // fprintf(fp,"\n\t\t//set ptr to the end of the first struct\n");
635 // fprintf(fp,"\t\tptr += sizeof(struct %s_%s_1);\n\n",ev->name, facName);
636 //}
3888436c 637
638 //copy struct, sequence and string to buffer
639 seqCount = 0;
640 strCount = 0;
641 flag = 0;
642 structCount = 0;
a8f6f123 643 if(ev->type != 0)
644 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
645 fld = (field *)ev->type->fields.array[pos1];
646 td = fld->type;
647 // if(td->type != STRING && td->type != SEQUENCE && td->type != ARRAY){
648 // if(flag == 0) structCount++;
649 // flag++;
650 // if((structCount > 1 || whichTypeFirst == 2) && flag == 1){
651 // assert(0); // MD : disabled !
652 // fprintf(fp,"\t//copy struct to buffer\n");
653 // fprintf(fp,"\tmemcpy(ptr, &__%d, sizeof(struct %s_%s_%d));\n",
654 // structCount, ev->name, facName,structCount);
655 // fprintf(fp,"\tptr += sizeof(struct %s_%s_%d);\n\n",
656 // ev->name, facName,structCount);
657 // }
658 // }
659 //else if(td->type == SEQUENCE){
660 if(td->type == SEQUENCE){
661 flag = 0;
662 fprintf(fp,"\t\t//copy sequence length and sequence to buffer\n");
663 fprintf(fp,"\t\t*ptr = seqlength_%d;\n",++seqCount);
664 fprintf(fp,"\t\tptr += sizeof(%s);\n",uintOutputTypes[td->size]);
665 fprintf(fp,"\t\tmemcpy(ptr, %s, sizeof(%s) * seqlength_%d);\n",
666 fld->name, getTypeStr(td), seqCount);
667 fprintf(fp,"\t\tptr += sizeof(%s) * seqlength_%d;\n\n",
668 getTypeStr(td), seqCount);
669 }
670 else if(td->type==STRING){
671 flag = 0;
672 fprintf(fp,"\t\t//copy string to buffer\n");
673 fprintf(fp,"\t\tif(strlength_%d > 0){\n",++strCount);
674 fprintf(fp,"\t\t\tmemcpy(ptr, %s, strlength_%d + 1);\n",
675 fld->name, strCount);
676 fprintf(fp,"\t\t\tptr += strlength_%d + 1;\n",strCount);
677 fprintf(fp,"\t\t}else{\n");
678 fprintf(fp,"\t\t\t*ptr = '\\0';\n");
679 fprintf(fp,"\t\t\tptr += 1;\n");
680 fprintf(fp,"\t\t}\n\n");
681 }else if(td->type==ARRAY){
682 flag = 0;
683 fprintf(fp,"\t//copy array to buffer\n");
684 fprintf(fp,"\tmemcpy(ptr, %s, sizeof(%s) * %d);\n",
685 fld->name, getTypeStr(td), td->size);
686 fprintf(fp,"\tptr += sizeof(%s) * %d;\n\n", getTypeStr(td), td->size);
687 }
688 }
3888436c 689 if(structCount + seqCount > 1) fprintf(fp,"\n");
690
d7ed29cd 691 fprintf(fp,"\n");
692 fprintf(fp, "\t\t/* Commit the work */\n");
a8f6f123 693 fprintf(fp, "\t\trelay_commit(channel->rchan->buf[smp_processor_id()],\n"
694 "\t\t\t\tbuff, event_length);\n");
1bedc199 695 fprintf(fp, "\t\tltt_write_commit_counter("
696 "channel->rchan->buf[smp_processor_id()],\n"
697 "\t\t\t\tbuff);\n");
d7ed29cd 698
699 /* End of traces iteration */
700 fprintf(fp, "\t}\n\n");
701
a8f6f123 702 fprintf(fp, "\n");
1bedc199 703 // The generated preempt_check_resched is not dangerous because
704 // interrupts are disabled.
705 fprintf(fp, "\tspin_unlock(&ltt_traces.locks[smp_processor_id()]);\n");
2f74104a 706
707 fprintf(fp, "unlock:\n");
1bedc199 708 fprintf(fp, "\tbarrier();\n");
2f74104a 709 fprintf(fp, "\tltt_nesting[smp_processor_id()]--;\n");
710 fprintf(fp, "\t/* Re-enable interrupts */\n");
711 fprintf(fp, "\tlocal_irq_restore(_flags);\n");
1bedc199 712 fprintf(fp, "\tpreempt_enable_no_resched();\n");
2f74104a 713 //fprintf(fp, "\tpreempt_check_resched();\n");
714
3888436c 715 //call trace function
d7ed29cd 716 //fprintf(fp,"\n\t//call trace function\n");
717 //fprintf(fp,"\tltt_log_event(ltt_facility_%s_%X, %s, bufLength, buff);\n",facName,checksum,ev->name);
1bedc199 718 fprintf(fp,"}\n");
719 fprintf(fp, "#endif //CONFIG_LTT\n\n");
3888436c 720 }
721
722}
723
724/*****************************************************************************
725 *Function name
726 * getTypeStr : generate type string
727 *Input Params
728 * td : a type descriptor
729 *Return Values
730 * char * : type string
731 ****************************************************************************/
732char * getTypeStr(type_descriptor * td){
733 type_descriptor * t ;
734
735 switch(td->type){
736 case INT:
737 return intOutputTypes[td->size];
738 case UINT:
739 return uintOutputTypes[td->size];
31cbc5d3 740 case POINTER:
741 return "void *";
742 case LONG:
743 return "long";
744 case ULONG:
745 return "unsigned long";
746 case SIZE_T:
747 return "size_t";
748 case SSIZE_T:
749 return "ssize_t";
750 case OFF_T:
751 return "off_t";
3888436c 752 case FLOAT:
753 return floatOutputTypes[td->size];
754 case STRING:
a8f6f123 755 return "const char";
3888436c 756 case ENUM:
757 return uintOutputTypes[td->size];
758 case ARRAY:
759 case SEQUENCE:
760 t = td->nested_type;
761 switch(t->type){
762 case INT:
a8f6f123 763 return intOutputTypes[t->size];
3888436c 764 case UINT:
a8f6f123 765 return uintOutputTypes[t->size];
31cbc5d3 766 case POINTER:
767 return "void *";
768 case LONG:
769 return "long";
770 case ULONG:
771 return "unsigned long";
772 case SIZE_T:
773 return "size_t";
774 case SSIZE_T:
775 return "ssize_t";
776 case OFF_T:
777 return "off_t";
3888436c 778 case FLOAT:
a8f6f123 779 return floatOutputTypes[t->size];
3888436c 780 case STRING:
a8f6f123 781 return "const char";
3888436c 782 case ENUM:
a8f6f123 783 return uintOutputTypes[t->size];
3888436c 784 default :
a8f6f123 785 error_callback(NULL,"Nested struct is not supportted");
786 break;
3888436c 787 }
788 break;
789 case STRUCT: //for now we do not support nested struct
790 error_callback(NULL,"Nested struct is not supportted");
791 break;
792 default:
793 error_callback(NULL,"No type information");
794 break;
795 }
796 return NULL;
797}
798
799/*****************************************************************************
800 *Function name
6d387597 801 * generateLoaderfile: generate a facility loaded .h file
3888436c 802 *Input Params
803 * fp : file to be written to
804 * facName : name of facility
805 * nbEvent : number of events in the facility
806 * checksum : checksum for the facility
807 ****************************************************************************/
8c6ca411 808void generateLoaderfile(FILE * fp, char * facName, int nbEvent, unsigned long checksum, char *capname){
a8f6f123 809 fprintf(fp, "#ifndef _LTT_FACILITY_LOADER_%s_H_\n",capname);
810 fprintf(fp, "#define _LTT_FACILITY_LOADER_%s_H_\n\n",capname);
8c6ca411 811 fprintf(fp,"#include <linux/ltt-facilities.h>\n", facName, checksum);
44cac8a9 812 fprintf(fp,"ltt_facility_t\tltt_facility_%s;\n", facName, checksum);
6d387597 813 fprintf(fp,"ltt_facility_t\tltt_facility_%s_%X;\n\n", facName, checksum);
814
a8f6f123 815 fprintf(fp,"#define LTT_FACILITY_SYMBOL\t\t\t\t\t\t\tltt_facility_%s\n",
44cac8a9 816 facName);
a8f6f123 817 fprintf(fp,"#define LTT_FACILITY_CHECKSUM_SYMBOL\t\tltt_facility_%s_%X\n",
6d387597 818 facName, checksum);
a8f6f123 819 fprintf(fp,"#define LTT_FACILITY_CHECKSUM\t\t\t\t\t\t0x%X\n", checksum);
820 fprintf(fp,"#define LTT_FACILITY_NAME\t\t\t\t\t\t\t\t\"%s\"\n", facName);
821 fprintf(fp,"#define LTT_FACILITY_NUM_EVENTS\t\t\t\t\t%d\n\n", nbEvent);
822 fprintf(fp, "#endif //_LTT_FACILITY_LOADER_%s_H_\n",capname);
823}
824
825void generateCfile(FILE * fp, char * filefacname){
826
827 fprintf(fp, "/*\n");
828 fprintf(fp, " * ltt-facility-loader-%s.c\n", filefacname);
829 fprintf(fp, " *\n");
830 fprintf(fp, " * (C) Copyright 2005 - \n");
831 fprintf(fp, " * Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)\n");
832 fprintf(fp, " *\n");
833 fprintf(fp, " * Contains the LTT facility loader.\n");
834 fprintf(fp, " *\n");
835 fprintf(fp, " */\n");
836 fprintf(fp, "\n");
837 fprintf(fp, "\n");
838 fprintf(fp, "#include <linux/ltt-facilities.h>\n");
839 fprintf(fp, "#include <linux/module.h>\n");
840 fprintf(fp, "#include <linux/init.h>\n");
841 fprintf(fp, "#include <linux/config.h>\n");
842 fprintf(fp, "#include \"ltt-facility-loader-%s.h\"\n", filefacname);
843 fprintf(fp, "\n");
844 fprintf(fp, "\n");
845 fprintf(fp, "#ifdef CONFIG_LTT\n");
846 fprintf(fp, "\n");
847 fprintf(fp, "EXPORT_SYMBOL(LTT_FACILITY_SYMBOL);\n");
848 fprintf(fp, "EXPORT_SYMBOL(LTT_FACILITY_CHECKSUM_SYMBOL);\n");
849 fprintf(fp, "\n");
850 fprintf(fp, "static const char ltt_facility_name[] = LTT_FACILITY_NAME;\n");
851 fprintf(fp, "\n");
852 fprintf(fp, "#define SYMBOL_STRING(sym) #sym\n");
853 fprintf(fp, "\n");
854 fprintf(fp, "static struct ltt_facility facility = {\n");
855 fprintf(fp, "\t.name = ltt_facility_name,\n");
856 fprintf(fp, "\t.num_events = LTT_FACILITY_NUM_EVENTS,\n");
857 fprintf(fp, "\t.checksum = LTT_FACILITY_CHECKSUM,\n");
858 fprintf(fp, "\t.symbol = SYMBOL_STRING(LTT_FACILITY_SYMBOL)\n");
859 fprintf(fp, "};\n");
860 fprintf(fp, "\n");
861 fprintf(fp, "#ifndef MODULE\n");
862 fprintf(fp, "\n");
863 fprintf(fp, "/* Built-in facility. */\n");
864 fprintf(fp, "\n");
865 fprintf(fp, "static int __init facility_init(void)\n");
866 fprintf(fp, "{\n");
867 fprintf(fp, "\tprintk(KERN_INFO \"LTT : ltt-facility-%s init in kernel\\n\");\n", filefacname);
868 fprintf(fp, "\n");
869 fprintf(fp, "\tLTT_FACILITY_SYMBOL = ltt_facility_builtin_register(&facility);\n");
870 fprintf(fp, "\tLTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;\n");
871 fprintf(fp, "\t\n");
872 fprintf(fp, "\treturn LTT_FACILITY_SYMBOL;\n");
873 fprintf(fp, "}\n");
874 fprintf(fp, "__initcall(facility_init);\n");
875 fprintf(fp, "\n");
876 fprintf(fp, "\n");
877 fprintf(fp, "\n");
878 fprintf(fp, "#else \n");
879 fprintf(fp, "\n");
880 fprintf(fp, "/* Dynamic facility. */\n");
881 fprintf(fp, "\n");
882 fprintf(fp, "static int __init facility_init(void)\n");
883 fprintf(fp, "{\n");
884 fprintf(fp, "\tprintk(KERN_INFO \"LTT : ltt-facility-%s init dynamic\\n\");\n", filefacname);
885 fprintf(fp, "\n");
886 fprintf(fp, "\tLTT_FACILITY_SYMBOL = ltt_facility_dynamic_register(&facility);\n");
887 fprintf(fp, "\tLTT_FACILITY_SYMBOL_CHECKSUM = LTT_FACILITY_SYMBOL;\n");
888 fprintf(fp, "\n");
889 fprintf(fp, "\treturn LTT_FACILITY_SYMBOL;\n");
890 fprintf(fp, "}\n");
891 fprintf(fp, "\n");
892 fprintf(fp, "static void __exit facility_exit(void)\n");
893 fprintf(fp, "{\n");
894 fprintf(fp, "\tint err;\n");
895 fprintf(fp, "\n");
896 fprintf(fp, "\terr = ltt_facility_dynamic_unregister(LTT_FACILITY_SYMBOL);\n");
897 fprintf(fp, "\tif(err != 0)\n");
898 fprintf(fp, "\t\tprintk(KERN_ERR \"LTT : Error in unregistering facility.\\n\");\n");
899 fprintf(fp, "\n");
900 fprintf(fp, "}\n");
901 fprintf(fp, "\n");
902 fprintf(fp, "module_init(facility_init)\n");
903 fprintf(fp, "module_exit(facility_exit)\n");
904 fprintf(fp, "\n");
905 fprintf(fp, "\n");
906 fprintf(fp, "MODULE_LICENSE(\"GPL\");\n");
907 fprintf(fp, "MODULE_AUTHOR(\"Mathieu Desnoyers\");\n");
908 fprintf(fp, "MODULE_DESCRIPTION(\"Linux Trace Toolkit Facility\");\n");
909 fprintf(fp, "\n");
910 fprintf(fp, "#endif //MODULE\n");
911 fprintf(fp, "\n");
912 fprintf(fp, "#endif //CONFIG_LTT\n");
3888436c 913}
914
915
This page took 0.065022 seconds and 4 git commands to generate.