genevent with align support
[lttv.git] / genevent / genevent.c
1 /*
2
3 genevent.c: Generate helper declarations and functions to trace events
4 from an event description file.
5
6 Copyright (C) 2002, Xianxiu Yang
7 Copyright (C) 2002, Michel Dagenais
8
9 This 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
11 the Free Software Foundation; version 2 of the License.
12
13 This 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>
39 #include <ctype.h>
40 #include <stdio.h>
41 #include <stdarg.h>
42 #include <linux/errno.h>
43 #include <assert.h>
44
45 #include "parser.h"
46 #include "genevent.h"
47
48 /* Named types may be referenced from anywhere */
49
50 facility * fac;
51
52 int 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) {
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);
95 }
96 else in.error(&in,"facility token was expected");
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 ****************************************************************************/
125 void generateFile(char *name){
126 char *loadName, *hName, *hIdName, *cName, *tmp, *tmp2;
127 FILE * lFp, *hFp, *iFp, *cFp;
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 }
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;
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;
160 lFp = fopen(loadName,"w");
161 if(!lFp){
162 printf("Cannot open the file : %s\n",loadName);
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 }
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 }
183
184 free(loadName);
185 free(hName);
186 free(hIdName);
187 free(cName);
188
189 generateChecksum(fac->name, &checksum, &(fac->events));
190
191 /* generate .h file, event enumeration then structures and functions */
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);
194 fprintf(iFp, "#ifdef CONFIG_LTT\n");
195 generateEnumEvent(iFp, fac->name, &nbEvent, checksum);
196 fprintf(iFp, "#endif //CONFIG_LTT\n");
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);
202 //fprintf(hFp, "#ifdef CONFIG_LTT\n");
203 generateTypeDefs(hFp, fac->name);
204 generateStructFunc(hFp, fac->name,checksum);
205 //fprintf(hFp, "#endif //CONFIG_LTT\n");
206 fprintf(hFp, "#endif //_LTT_FACILITY_%s_H_\n",fac->capname);
207
208 /* generate .h file, calls to register the facility at init time */
209 generateLoaderfile(lFp,fac->name,nbEvent,checksum,fac->capname);
210
211 // create ltt-facility-loader-facname.c
212 generateCfile(cFp, tmp);
213
214 fclose(hFp);
215 fclose(iFp);
216 fclose(lFp);
217 fclose(cFp);
218
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 ****************************************************************************/
231 void generateEnumEvent(FILE *fp, char *facName, int * nbEvent, unsigned long checksum) {
232 int pos = 0;
233
234 fprintf(fp,"#include <linux/ltt-facilities.h>\n\n");
235
236 fprintf(fp,"/**** facility handle ****/\n\n");
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);
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++) {
244 fprintf(fp,"\tevent_%s", ((event *)(fac->events.array[pos]))->name);
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
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 ****************************************************************************/
268
269 static void
270 printStruct(FILE * fp, int len, void ** array, char * name, char * facName,
271 int * whichTypeFirst, int * hasStrSeq, int * structCount,
272 type_descriptor *type)
273 {
274 int flag = 0;
275 int pos;
276 field * fld;
277 type_descriptor * td;
278
279 for (pos = 0; pos < len; pos++) {
280 fld = (field *)array[pos];
281 td = fld->type;
282 if( td->type == STRING || td->type == SEQUENCE ||
283 td->type == ARRAY) {
284 (*hasStrSeq)++;
285 }
286 // if (*whichTypeFirst == 0) {
287 // *whichTypeFirst = 1; //struct first
288 // }
289 if (flag == 0) {
290 flag = 1;
291
292 fprintf(fp,"struct %s_%s",name, facName);
293 if (structCount) {
294 fprintf(fp, "_%d {\n",++*structCount);
295 } else {
296 fprintf(fp, " {\n");
297 }
298 }
299 fprintf(fp, "\t%s %s; /* %s */\n",
300 getTypeStr(td),fld->name,fld->description );
301 #if 0
302 } else {
303 if (*whichTypeFirst == 0) {
304 //string or sequence or array first
305 *whichTypeFirst = 2;
306 }
307 (*hasStrSeq)++;
308 if(flag) {
309 fprintf(fp,"} __attribute__ ((packed));\n\n");
310 }
311 flag = 0;
312 }
313 #endif //0
314 }
315
316 if(flag) {
317 if(type->alignment == 0)
318 fprintf(fp,"} __attribute__ ((packed));\n\n");
319 else {
320 if(type->alignment != 1 && type->alignment != 2
321 && type->alignment != 4 && type->alignment != 8) {
322 printf("Wrong alignment %i, using packed.\n", type->alignment);
323 fprintf(fp,"} __attribute__ ((packed));\n\n");
324 } else
325 fprintf(fp,"} __attribute__ ((aligned(%i)));\n\n", type->alignment);
326 }
327 }
328 }
329
330
331 /*****************************************************************************
332 *Function name
333 * generateHfile : Create the typedefs
334 *Input Params
335 * fp : file to be written to
336 ****************************************************************************/
337 void
338 generateTypeDefs(FILE * fp, char *facName)
339 {
340 int pos, tmp = 1;
341
342 fprintf(fp,"#include <linux/types.h>\n");
343 fprintf(fp,"#include <linux/spinlock.h>\n");
344 fprintf(fp,"#include <linux/ltt/ltt-facility-id-%s.h>\n\n", facName);
345 fprintf(fp,"#include <linux/ltt-core.h>\n");
346
347 #if 0 //broken
348 fprintf(fp, "/**** Basic Type Definitions ****/\n\n");
349
350 for (pos = 0; pos < fac->named_types.values.position; pos++) {
351 type_descriptor * type =
352 (type_descriptor*)fac->named_types.values.array[pos];
353 printStruct(fp, type->fields.position, type->fields.array,
354 "", type->type_name, &tmp, &tmp, NULL);
355 fprintf(fp, "typedef struct _%s %s;\n\n",
356 type->type_name, type->type_name);
357 }
358 #endif //0
359 }
360
361
362 /*****************************************************************************
363 *Function name
364 * generateEnumDefinition: generate enum definition if it exists
365 *Input Params
366 * fp : file to be written to
367 * fHead : enum type
368 ****************************************************************************/
369 void generateEnumDefinition(FILE * fp, type_descriptor * type){
370 int pos;
371
372 if(type->already_printed) return;
373
374 fprintf(fp,"enum {\n");
375 for(pos = 0; pos < type->labels.position; pos++){
376 fprintf(fp,"\tLTT_ENUM_%s", type->labels.array[pos]);
377 if (pos != type->labels.position - 1) fprintf(fp,",");
378 if(type->labels_description.array[pos] != NULL)
379 fprintf(fp,"\t/* %s */\n",type->labels_description.array[pos]);
380 else
381 fprintf(fp,"\n");
382 }
383 fprintf(fp,"};\n\n\n");
384
385 type->already_printed = 1;
386 }
387
388 /*****************************************************************************
389 *Function name
390 * generateStrucTFunc: output structure and function to .h file
391 *Input Params
392 * fp : file to be written to
393 * facName : name of facility
394 ****************************************************************************/
395 void generateStructFunc(FILE * fp, char * facName, unsigned long checksum){
396 event * ev;
397 field * fld;
398 type_descriptor * td;
399 int pos, pos1;
400 int hasStrSeq, flag, structCount, seqCount,strCount, whichTypeFirst=0;
401
402 for(pos = 0; pos < fac->events.position; pos++){
403 ev = (event *) fac->events.array[pos];
404 //yxx if(ev->nested)continue;
405 fprintf(fp,"/**** structure and trace function for event: %s ****/\n\n",
406 ev->name);
407 //if(ev->type == 0){ // event without type
408 // fprintf(fp,"static inline void trace_%s_%s(void){\n",facName,ev->name);
409 // fprintf(fp,"\tltt_log_event(ltt_facility_%s_%X, event_%s, 0, NULL);\n",
410 // facName,checksum,ev->name);
411 // fprintf(fp,"};\n\n\n");
412 // continue;
413 //}
414
415 //if fields contain enum, print out enum definition
416 //MD : fixed in generateEnumDefinition to do not print the same enum
417 //twice.
418 if(ev->type != 0)
419 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
420 fld = (field *)ev->type->fields.array[pos1];
421 if(fld->type->type == ENUM) generateEnumDefinition(fp, fld->type);
422 }
423
424 //default: no string, array or sequence in the event
425 hasStrSeq = 0;
426 whichTypeFirst = 0;
427 structCount = 0;
428
429 //structure for kernel
430 if(ev->type != 0)
431 printStruct(fp, ev->type->fields.position, ev->type->fields.array,
432 ev->name, facName, &whichTypeFirst, &hasStrSeq, &structCount,
433 ev->type);
434
435
436 //trace function : function name and parameters : stub function.
437 seqCount = 0;
438 strCount = 0;
439 fprintf(fp, "#ifndef CONFIG_LTT\n");
440 fprintf(fp,"static inline void trace_%s_%s(",facName,ev->name);
441 if(ev->type == 0)
442 fprintf(fp, "void");
443 else
444 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
445 fld = (field *)ev->type->fields.array[pos1];
446 td = fld->type;
447 if(td->type == ARRAY ){
448 fprintf(fp,"%s * %s",getTypeStr(td), fld->name);
449 }else if(td->type == STRING){
450 fprintf(fp,"short int strlength_%d, %s * %s",
451 ++strCount, getTypeStr(td), fld->name);
452 }else if(td->type == SEQUENCE){
453 fprintf(fp,"%s seqlength_%d, %s * %s",
454 uintOutputTypes[td->size], ++seqCount,getTypeStr(td), fld->name);
455 }else fprintf(fp,"%s %s",getTypeStr(td), fld->name);
456 if(pos1 != ev->type->fields.position - 1) fprintf(fp,", ");
457 }
458 fprintf(fp,")\n{\n");
459 fprintf(fp,"}\n");
460 fprintf(fp,"#else\n");
461
462 //trace function : function name and parameters
463 seqCount = 0;
464 strCount = 0;
465 fprintf(fp,"static inline void trace_%s_%s(",facName,ev->name);
466 if(ev->type == 0)
467 fprintf(fp, "void");
468 else
469 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
470 fld = (field *)ev->type->fields.array[pos1];
471 td = fld->type;
472 if(td->type == ARRAY ){
473 fprintf(fp,"%s * %s",getTypeStr(td), fld->name);
474 }else if(td->type == STRING){
475 fprintf(fp,"short int strlength_%d, %s * %s",
476 ++strCount, getTypeStr(td), fld->name);
477 }else if(td->type == SEQUENCE){
478 fprintf(fp,"%s seqlength_%d, %s * %s",
479 uintOutputTypes[td->size], ++seqCount,getTypeStr(td), fld->name);
480 }else fprintf(fp,"%s %s",getTypeStr(td), fld->name);
481 if(pos1 != ev->type->fields.position - 1) fprintf(fp,", ");
482 }
483 fprintf(fp,")\n{\n");
484
485
486
487 //length of buffer : length of all structures
488 fprintf(fp,"\tint length = ");
489 if(ev->type == 0) fprintf(fp, "0");
490
491 for(pos1=0;pos1<structCount;pos1++){
492 fprintf(fp,"sizeof(struct %s_%s_%d)",ev->name, facName,pos1+1);
493 if(pos1 != structCount-1) fprintf(fp," + ");
494 }
495
496 //length of buffer : length of all arrays, sequences and strings
497 seqCount = 0;
498 strCount = 0;
499 flag = 0;
500 if(ev->type != 0)
501 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
502 fld = (field *)ev->type->fields.array[pos1];
503 td = fld->type;
504 if(td->type == SEQUENCE || td->type==STRING || td->type==ARRAY){
505 if(structCount || flag > 0) fprintf(fp," + ");
506 if(td->type == SEQUENCE)
507 fprintf(fp,"sizeof(%s) + sizeof(%s) * seqlength_%d",
508 uintOutputTypes[td->size], getTypeStr(td), ++seqCount);
509 else if(td->type==STRING) fprintf(fp,"strlength_%d + 1", ++strCount);
510 else if(td->type==ARRAY)
511 fprintf(fp,"sizeof(%s) * %d", getTypeStr(td),td->size);
512 if(structCount == 0) flag = 1;
513 }
514 }
515 fprintf(fp,";\n");
516
517 //allocate buffer
518 // MD no more need. fprintf(fp,"\tchar buff[buflength];\n");
519 // write directly to the channel
520 fprintf(fp, "\tunsigned int index;\n");
521 fprintf(fp, "\tstruct ltt_channel_struct *channel;\n");
522 fprintf(fp, "\tstruct ltt_trace_struct *trace;\n");
523 fprintf(fp, "\tunsigned long _flags;\n");
524 fprintf(fp, "\tvoid *buff;\n");
525 fprintf(fp, "\tunsigned int header_length;\n");
526 fprintf(fp, "\tunsigned int event_length;\n");
527 fprintf(fp, "\tint resret;\n");
528 fprintf(fp, "\tunsigned char _offset;\n");
529 fprintf(fp, "\tstruct rchan_buf *buf;\n");
530
531 if(ev->type != 0)
532 fprintf(fp, "\tstruct %s_%s_1* __1;\n\n", ev->name, facName);
533
534 /* Warning : this is done prior to taking locks :
535 * setting this value must be done at the end of the trace activation.
536 * (we don't care for trace removal, as the list of traces is protected : it
537 * just won't iterate on any trace). */
538 fprintf(fp,
539 "\tif(ltt_traces.num_active_traces == 0) return;\n\n");
540
541 fprintf(fp, "\t/* Disable interrupts. */\n");
542 fprintf(fp, "\tlocal_irq_save(_flags);\n");
543 fprintf(fp, "\tpreempt_disable();\n\n");
544
545 fprintf(fp, "\tltt_nesting[smp_processor_id()]++;\n");
546 fprintf(fp, "\tbarrier();\n");
547 fprintf(fp, "\tif(ltt_nesting[smp_processor_id()] > 1) goto unlock;\n");
548 fprintf(fp, "\tspin_lock(&ltt_traces.locks[smp_processor_id()]);\n\n");
549
550 fprintf(fp,
551 "\tindex = ltt_get_index_from_facility(ltt_facility_%s_%X,\n"\
552 "\t\t\t\tevent_%s);\n",
553 facName, checksum, ev->name);
554 fprintf(fp,"\n");
555
556 /* For each trace */
557 fprintf(fp, "\tlist_for_each_entry(trace, &ltt_traces.head, list) {\n");
558 fprintf(fp, "\t\tif(!trace->active) continue;\n\n");
559
560 fprintf(fp, "\t\tchannel = ltt_get_channel_from_index(trace, index);\n");
561 fprintf(fp, "\t\tbuf = channel->rchan->buf[smp_processor_id()];\n");
562 /* Warning : not atomic reservation : event size depends on the current
563 * address for alignment */
564 fprintf(fp, "\t\theader_length = "
565 "ltt_get_event_header_size(trace, channel,"
566 "buf->data + buf->offset, &_offset);\n");
567 fprintf(fp, "\t\tevent_length = header_length + length;\n");
568
569 /* Reserve the channel */
570 fprintf(fp, "\t\tbuff = relay_reserve(channel->rchan, event_length, &resret);\n");
571 fprintf(fp, "\t\tif(buff == NULL) {\n");
572 fprintf(fp, "\t\t\t/* Buffer is full*/\n");
573 fprintf(fp, "\t\t\t/* for debug BUG(); */\n"); // DEBUG!
574 fprintf(fp, "\t\t\tchannel->events_lost[smp_processor_id()]++;\n");
575 fprintf(fp, "\t\t\tbreak;\n"); /* don't commit a NULL reservation! */
576 fprintf(fp, "\t\t}\n");
577
578 /* DEBUG */
579 fprintf(fp, "\t\tif(resret == 1) {\n");
580 fprintf(fp, "printk(\"f%%lu e\%%u \", ltt_facility_%s_%X, event_%s);",
581 facName, checksum, ev->name);
582 fprintf(fp, "\t\t}\n");
583
584 /* Write the header */
585 fprintf(fp, "\n");
586 fprintf(fp, "\t\tltt_write_event_header(trace, channel, buff, \n"
587 "\t\t\t\tltt_facility_%s_%X, event_%s, length, _offset);\n",
588 facName, checksum, ev->name);
589 fprintf(fp, "\n");
590
591 //declare a char pointer if needed : starts at the end of the structs.
592 if(structCount + hasStrSeq > 1) {
593 fprintf(fp,"\t\tchar * ptr = (char*)buff + header_length");
594 for(pos1=0;pos1<structCount;pos1++){
595 fprintf(fp," + sizeof(struct %s_%s_%d)",ev->name, facName,pos1+1);
596 }
597 if(structCount + hasStrSeq > 1) fprintf(fp,";\n");
598 }
599
600 // Declare an alias pointer of the struct type to the beginning
601 // of the reserved area, just after the event header.
602 if(ev->type != 0)
603 fprintf(fp, "\t\t__1 = (struct %s_%s_1 *)(buff + header_length);\n",
604 ev->name, facName);
605 //allocate memory for new struct and initialize it
606 //if(whichTypeFirst == 1){ //struct first
607 //for(pos1=0;pos1<structCount;pos1++){
608 // if(pos1==0) fprintf(fp,
609 // "\tstruct %s_%s_1 * __1 = (struct %s_%s_1 *)buff;\n",
610 // ev->name, facName,ev->name, facName);
611 //MD disabled else fprintf(fp,
612 // "\tstruct %s_%s_%d __%d;\n",
613 // ev->name, facName,pos1+1,pos1+1);
614 //}
615 //}else if(whichTypeFirst == 2){
616 // for(pos1=0;pos1<structCount;pos1++)
617 // fprintf(fp,"\tstruct %s_%s_%d __%d;\n",
618 // ev->name, facName,pos1+1,pos1+1);
619 //}
620 fprintf(fp,"\n");
621
622 if(structCount) fprintf(fp,"\t\t//initialize structs\n");
623 //flag = 0;
624 //structCount = 0;
625 if(ev->type != 0)
626 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
627 fld = (field *)ev->type->fields.array[pos1];
628 td = fld->type;
629 if(td->type != ARRAY && td->type != SEQUENCE && td->type != STRING){
630 //if(flag == 0){
631 // flag = 1;
632 // structCount++;
633 // if(structCount > 1) fprintf(fp,"\n");
634 //}
635 fprintf(fp, "\t\t__1->%s = %s;\n", fld->name, fld->name );
636
637 //if(structCount == 1 && whichTypeFirst == 1)
638 // fprintf(fp, "\t__1->%s = %s;\n",fld->name,fld->name );
639 //else
640 // fprintf(fp, "\t__%d.%s = %s;\n",structCount ,fld->name,fld->name);
641 }
642 //else flag = 0;
643 }
644 if(structCount) fprintf(fp,"\n");
645 //set ptr to the end of first struct if needed;
646 //if(structCount + hasStrSeq > 1){
647 // fprintf(fp,"\n\t\t//set ptr to the end of the first struct\n");
648 // fprintf(fp,"\t\tptr += sizeof(struct %s_%s_1);\n\n",ev->name, facName);
649 //}
650
651 //copy struct, sequence and string to buffer
652 seqCount = 0;
653 strCount = 0;
654 flag = 0;
655 structCount = 0;
656 if(ev->type != 0)
657 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
658 fld = (field *)ev->type->fields.array[pos1];
659 td = fld->type;
660 // if(td->type != STRING && td->type != SEQUENCE && td->type != ARRAY){
661 // if(flag == 0) structCount++;
662 // flag++;
663 // if((structCount > 1 || whichTypeFirst == 2) && flag == 1){
664 // assert(0); // MD : disabled !
665 // fprintf(fp,"\t//copy struct to buffer\n");
666 // fprintf(fp,"\tmemcpy(ptr, &__%d, sizeof(struct %s_%s_%d));\n",
667 // structCount, ev->name, facName,structCount);
668 // fprintf(fp,"\tptr += sizeof(struct %s_%s_%d);\n\n",
669 // ev->name, facName,structCount);
670 // }
671 // }
672 //else if(td->type == SEQUENCE){
673 if(td->type == SEQUENCE){
674 flag = 0;
675 fprintf(fp,"\t\t//copy sequence length and sequence to buffer\n");
676 fprintf(fp,"\t\t*ptr = seqlength_%d;\n",++seqCount);
677 fprintf(fp,"\t\tptr += sizeof(%s);\n",uintOutputTypes[td->size]);
678 fprintf(fp,"\t\tmemcpy(ptr, %s, sizeof(%s) * seqlength_%d);\n",
679 fld->name, getTypeStr(td), seqCount);
680 fprintf(fp,"\t\tptr += sizeof(%s) * seqlength_%d;\n\n",
681 getTypeStr(td), seqCount);
682 }
683 else if(td->type==STRING){
684 flag = 0;
685 fprintf(fp,"\t\t//copy string to buffer\n");
686 fprintf(fp,"\t\tif(strlength_%d > 0){\n",++strCount);
687 fprintf(fp,"\t\t\tmemcpy(ptr, %s, strlength_%d + 1);\n",
688 fld->name, strCount);
689 fprintf(fp,"\t\t\tptr += strlength_%d + 1;\n",strCount);
690 fprintf(fp,"\t\t}else{\n");
691 fprintf(fp,"\t\t\t*ptr = '\\0';\n");
692 fprintf(fp,"\t\t\tptr += 1;\n");
693 fprintf(fp,"\t\t}\n\n");
694 }else if(td->type==ARRAY){
695 flag = 0;
696 fprintf(fp,"\t//copy array to buffer\n");
697 fprintf(fp,"\tmemcpy(ptr, %s, sizeof(%s) * %d);\n",
698 fld->name, getTypeStr(td), td->size);
699 fprintf(fp,"\tptr += sizeof(%s) * %d;\n\n", getTypeStr(td), td->size);
700 }
701 }
702 if(structCount + seqCount > 1) fprintf(fp,"\n");
703
704 fprintf(fp,"\n");
705 fprintf(fp, "\t\t/* Commit the work */\n");
706 fprintf(fp, "\t\trelay_commit(channel->rchan->buf[smp_processor_id()],\n"
707 "\t\t\t\tbuff, event_length);\n");
708 fprintf(fp, "\t\tltt_write_commit_counter("
709 "channel->rchan->buf[smp_processor_id()],\n"
710 "\t\t\t\tbuff);\n");
711
712 /* End of traces iteration */
713 fprintf(fp, "\t}\n\n");
714
715 fprintf(fp, "\n");
716 // The generated preempt_check_resched is not dangerous because
717 // interrupts are disabled.
718 fprintf(fp, "\tspin_unlock(&ltt_traces.locks[smp_processor_id()]);\n");
719
720 fprintf(fp, "unlock:\n");
721 fprintf(fp, "\tbarrier();\n");
722 fprintf(fp, "\tltt_nesting[smp_processor_id()]--;\n");
723 fprintf(fp, "\t/* Re-enable interrupts */\n");
724 fprintf(fp, "\tlocal_irq_restore(_flags);\n");
725 fprintf(fp, "\tpreempt_enable_no_resched();\n");
726 //fprintf(fp, "\tpreempt_check_resched();\n");
727
728 //call trace function
729 //fprintf(fp,"\n\t//call trace function\n");
730 //fprintf(fp,"\tltt_log_event(ltt_facility_%s_%X, %s, bufLength, buff);\n",facName,checksum,ev->name);
731 fprintf(fp,"}\n");
732 fprintf(fp, "#endif //CONFIG_LTT\n\n");
733 }
734
735 }
736
737 /*****************************************************************************
738 *Function name
739 * getTypeStr : generate type string
740 *Input Params
741 * td : a type descriptor
742 *Return Values
743 * char * : type string
744 ****************************************************************************/
745 char * getTypeStr(type_descriptor * td){
746 type_descriptor * t ;
747
748 switch(td->type){
749 case INT:
750 return intOutputTypes[td->size];
751 case UINT:
752 return uintOutputTypes[td->size];
753 case POINTER:
754 return "void *";
755 case LONG:
756 return "long";
757 case ULONG:
758 return "unsigned long";
759 case SIZE_T:
760 return "size_t";
761 case SSIZE_T:
762 return "ssize_t";
763 case OFF_T:
764 return "off_t";
765 case FLOAT:
766 return floatOutputTypes[td->size];
767 case STRING:
768 return "const char";
769 case ENUM:
770 return uintOutputTypes[td->size];
771 case ARRAY:
772 case SEQUENCE:
773 t = td->nested_type;
774 switch(t->type){
775 case INT:
776 return intOutputTypes[t->size];
777 case UINT:
778 return uintOutputTypes[t->size];
779 case POINTER:
780 return "void *";
781 case LONG:
782 return "long";
783 case ULONG:
784 return "unsigned long";
785 case SIZE_T:
786 return "size_t";
787 case SSIZE_T:
788 return "ssize_t";
789 case OFF_T:
790 return "off_t";
791 case FLOAT:
792 return floatOutputTypes[t->size];
793 case STRING:
794 return "const char";
795 case ENUM:
796 return uintOutputTypes[t->size];
797 default :
798 error_callback(NULL,"Nested struct is not supportted");
799 break;
800 }
801 break;
802 case STRUCT: //for now we do not support nested struct
803 error_callback(NULL,"Nested struct is not supportted");
804 break;
805 default:
806 error_callback(NULL,"No type information");
807 break;
808 }
809 return NULL;
810 }
811
812 /*****************************************************************************
813 *Function name
814 * generateLoaderfile: generate a facility loaded .h file
815 *Input Params
816 * fp : file to be written to
817 * facName : name of facility
818 * nbEvent : number of events in the facility
819 * checksum : checksum for the facility
820 ****************************************************************************/
821 void generateLoaderfile(FILE * fp, char * facName, int nbEvent, unsigned long checksum, char *capname){
822 fprintf(fp, "#ifndef _LTT_FACILITY_LOADER_%s_H_\n",capname);
823 fprintf(fp, "#define _LTT_FACILITY_LOADER_%s_H_\n\n",capname);
824 fprintf(fp,"#include <linux/ltt-facilities.h>\n", facName, checksum);
825 fprintf(fp,"ltt_facility_t\tltt_facility_%s;\n", facName, checksum);
826 fprintf(fp,"ltt_facility_t\tltt_facility_%s_%X;\n\n", facName, checksum);
827
828 fprintf(fp,"#define LTT_FACILITY_SYMBOL\t\t\t\t\t\t\tltt_facility_%s\n",
829 facName);
830 fprintf(fp,"#define LTT_FACILITY_CHECKSUM_SYMBOL\t\tltt_facility_%s_%X\n",
831 facName, checksum);
832 fprintf(fp,"#define LTT_FACILITY_CHECKSUM\t\t\t\t\t\t0x%X\n", checksum);
833 fprintf(fp,"#define LTT_FACILITY_NAME\t\t\t\t\t\t\t\t\"%s\"\n", facName);
834 fprintf(fp,"#define LTT_FACILITY_NUM_EVENTS\t\t\t\t\t%d\n\n", nbEvent);
835 fprintf(fp, "#endif //_LTT_FACILITY_LOADER_%s_H_\n",capname);
836 }
837
838 void generateCfile(FILE * fp, char * filefacname){
839
840 fprintf(fp, "/*\n");
841 fprintf(fp, " * ltt-facility-loader-%s.c\n", filefacname);
842 fprintf(fp, " *\n");
843 fprintf(fp, " * (C) Copyright 2005 - \n");
844 fprintf(fp, " * Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)\n");
845 fprintf(fp, " *\n");
846 fprintf(fp, " * Contains the LTT facility loader.\n");
847 fprintf(fp, " *\n");
848 fprintf(fp, " */\n");
849 fprintf(fp, "\n");
850 fprintf(fp, "\n");
851 fprintf(fp, "#include <linux/ltt-facilities.h>\n");
852 fprintf(fp, "#include <linux/module.h>\n");
853 fprintf(fp, "#include <linux/init.h>\n");
854 fprintf(fp, "#include <linux/config.h>\n");
855 fprintf(fp, "#include \"ltt-facility-loader-%s.h\"\n", filefacname);
856 fprintf(fp, "\n");
857 fprintf(fp, "\n");
858 fprintf(fp, "#ifdef CONFIG_LTT\n");
859 fprintf(fp, "\n");
860 fprintf(fp, "EXPORT_SYMBOL(LTT_FACILITY_SYMBOL);\n");
861 fprintf(fp, "EXPORT_SYMBOL(LTT_FACILITY_CHECKSUM_SYMBOL);\n");
862 fprintf(fp, "\n");
863 fprintf(fp, "static const char ltt_facility_name[] = LTT_FACILITY_NAME;\n");
864 fprintf(fp, "\n");
865 fprintf(fp, "#define SYMBOL_STRING(sym) #sym\n");
866 fprintf(fp, "\n");
867 fprintf(fp, "static struct ltt_facility facility = {\n");
868 fprintf(fp, "\t.name = ltt_facility_name,\n");
869 fprintf(fp, "\t.num_events = LTT_FACILITY_NUM_EVENTS,\n");
870 fprintf(fp, "\t.checksum = LTT_FACILITY_CHECKSUM,\n");
871 fprintf(fp, "\t.symbol = SYMBOL_STRING(LTT_FACILITY_SYMBOL)\n");
872 fprintf(fp, "};\n");
873 fprintf(fp, "\n");
874 fprintf(fp, "#ifndef MODULE\n");
875 fprintf(fp, "\n");
876 fprintf(fp, "/* Built-in facility. */\n");
877 fprintf(fp, "\n");
878 fprintf(fp, "static int __init facility_init(void)\n");
879 fprintf(fp, "{\n");
880 fprintf(fp, "\tprintk(KERN_INFO \"LTT : ltt-facility-%s init in kernel\\n\");\n", filefacname);
881 fprintf(fp, "\n");
882 fprintf(fp, "\tLTT_FACILITY_SYMBOL = ltt_facility_builtin_register(&facility);\n");
883 fprintf(fp, "\tLTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;\n");
884 fprintf(fp, "\t\n");
885 fprintf(fp, "\treturn LTT_FACILITY_SYMBOL;\n");
886 fprintf(fp, "}\n");
887 fprintf(fp, "__initcall(facility_init);\n");
888 fprintf(fp, "\n");
889 fprintf(fp, "\n");
890 fprintf(fp, "\n");
891 fprintf(fp, "#else \n");
892 fprintf(fp, "\n");
893 fprintf(fp, "/* Dynamic facility. */\n");
894 fprintf(fp, "\n");
895 fprintf(fp, "static int __init facility_init(void)\n");
896 fprintf(fp, "{\n");
897 fprintf(fp, "\tprintk(KERN_INFO \"LTT : ltt-facility-%s init dynamic\\n\");\n", filefacname);
898 fprintf(fp, "\n");
899 fprintf(fp, "\tLTT_FACILITY_SYMBOL = ltt_facility_dynamic_register(&facility);\n");
900 fprintf(fp, "\tLTT_FACILITY_SYMBOL_CHECKSUM = LTT_FACILITY_SYMBOL;\n");
901 fprintf(fp, "\n");
902 fprintf(fp, "\treturn LTT_FACILITY_SYMBOL;\n");
903 fprintf(fp, "}\n");
904 fprintf(fp, "\n");
905 fprintf(fp, "static void __exit facility_exit(void)\n");
906 fprintf(fp, "{\n");
907 fprintf(fp, "\tint err;\n");
908 fprintf(fp, "\n");
909 fprintf(fp, "\terr = ltt_facility_dynamic_unregister(LTT_FACILITY_SYMBOL);\n");
910 fprintf(fp, "\tif(err != 0)\n");
911 fprintf(fp, "\t\tprintk(KERN_ERR \"LTT : Error in unregistering facility.\\n\");\n");
912 fprintf(fp, "\n");
913 fprintf(fp, "}\n");
914 fprintf(fp, "\n");
915 fprintf(fp, "module_init(facility_init)\n");
916 fprintf(fp, "module_exit(facility_exit)\n");
917 fprintf(fp, "\n");
918 fprintf(fp, "\n");
919 fprintf(fp, "MODULE_LICENSE(\"GPL\");\n");
920 fprintf(fp, "MODULE_AUTHOR(\"Mathieu Desnoyers\");\n");
921 fprintf(fp, "MODULE_DESCRIPTION(\"Linux Trace Toolkit Facility\");\n");
922 fprintf(fp, "\n");
923 fprintf(fp, "#endif //MODULE\n");
924 fprintf(fp, "\n");
925 fprintf(fp, "#endif //CONFIG_LTT\n");
926 }
927
928
This page took 0.053851 seconds and 5 git commands to generate.