add scripts
[lttv.git] / genevent-new / genevent.c
index aba40e528d204b411c2dcef8c54ec93d245b85e7..88fbde1576e54d7ba313834f880542407047ff0b 100644 (file)
@@ -386,6 +386,8 @@ int print_type_declaration(type_descriptor_t * td, FILE *fd, unsigned int tabs,
        char basename[PATH_MAX];
        unsigned int basename_len = 0;
        
+       if(td->custom_write) return 0;  /* Does print custom type */
+       
        strncpy(basename, nest_name, PATH_MAX);
        basename_len = strlen(basename);
        
@@ -666,6 +668,7 @@ int print_type_write(type_descriptor_t * td, FILE *fd, unsigned int tabs,
        char basename[PATH_MAX];
        unsigned int basename_len = 0;
        char get_ptr_char[2] = "";
+       char custom[PATH_MAX] = "";
        
        strncpy(basename, nest_name, PATH_MAX);
        basename_len = strlen(basename);
@@ -690,6 +693,10 @@ int print_type_write(type_descriptor_t * td, FILE *fd, unsigned int tabs,
                strcpy(get_ptr_char, "&");
        }
 
+       if(td->custom_write) {
+               strcpy(custom, "_custom");
+       }
+
        switch(td->type) {
                case INT_FIXED:
                case UINT_FIXED:
@@ -734,32 +741,32 @@ int print_type_write(type_descriptor_t * td, FILE *fd, unsigned int tabs,
                case STRING:
                        print_tabs(tabs, fd);
                        fprintf(fd,
-                                       "lttng_write_string_%s(buffer, to_base, to, from, len, %s%s);\n",
-                                       basename, obj_prefix, field_name);
+                                       "lttng_write%s_string_%s(buffer, to_base, to, from, len, %s%s);\n",
+                                       custom, basename, obj_prefix, field_name);
                        break;
                case SEQUENCE:
                        print_tabs(tabs, fd);
                        fprintf(fd,
-                                       "lttng_write_sequence_%s(buffer, to_base, to, from, len, %s%s%s);",
-                                       basename, get_ptr_char, obj_prefix, field_name);
+                                       "lttng_write%s_sequence_%s(buffer, to_base, to, from, len, %s%s%s);",
+                                       custom, basename, get_ptr_char, obj_prefix, field_name);
                        break;
                case STRUCT:
                        print_tabs(tabs, fd);
                        fprintf(fd,
-                                       "lttng_write_struct_%s(buffer, to_base, to, from, len, %s%s%s);",
-                                       basename, get_ptr_char, obj_prefix, field_name);
+                                       "lttng_write%s_struct_%s(buffer, to_base, to, from, len, %s%s%s);",
+                                       custom, basename, get_ptr_char, obj_prefix, field_name);
                        break;
                case UNION:
                        print_tabs(tabs, fd);
                        fprintf(fd,
-                                       "lttng_write_union_%s(buffer, to_base, to, from, len, %s%s%s);",
-                                       basename, get_ptr_char, obj_prefix, field_name);
+                                       "lttng_write%s_union_%s(buffer, to_base, to, from, len, %s%s%s);",
+                                       custom, basename, get_ptr_char, obj_prefix, field_name);
                        break;
                case ARRAY:
                        print_tabs(tabs, fd);
                        fprintf(fd,
-                                       "lttng_write_array_%s(buffer, to_base, to, from, len, %s%s);",
-                                       basename, obj_prefix, field_name);
+                                       "lttng_write%s_array_%s(buffer, to_base, to, from, len, %s%s);",
+                                       custom, basename, obj_prefix, field_name);
                        break;
                case NONE:
                        printf("Error : type NONE unexpected\n");
@@ -831,6 +838,8 @@ int print_type_alignment_fct(type_descriptor_t * td, FILE *fd,
        char basename[PATH_MAX];
        unsigned int basename_len = 0;
        
+       if(td->custom_write) return 0;  /* Does print custom type */
+
        strncpy(basename, nest_name, PATH_MAX);
        basename_len = strlen(basename);
        
@@ -852,6 +861,11 @@ int print_type_alignment_fct(type_descriptor_t * td, FILE *fd,
        
        switch(td->type) {
                case SEQUENCE:
+                       if(((field_t*)td->fields.array[1])->type->type_name == NULL) {
+                               /* Not a named nested type : we must print its align fct */
+                               if(print_type_alignment_fct(((field_t*)td->fields.array[1])->type, fd,
+                                                               0, basename, "")) return 1;
+                       }
                        /* Function header */
                        fprintf(fd, "static inline size_t lttng_get_alignment_sequence_%s(\n",
                                        basename);
@@ -882,6 +896,15 @@ int print_type_alignment_fct(type_descriptor_t * td, FILE *fd,
                        fprintf(fd, "return align;\n");
                        break;
                case STRUCT:
+                       for(unsigned int i=0;i<td->fields.position;i++){
+                               field_t *field = (field_t*)(td->fields.array[i]);
+                               type_descriptor_t *type = field->type;
+                               if(type->type_name == NULL) {
+                                       /* Not a named nested type : we must print its align fct */
+                                       if(print_type_alignment_fct(type, fd,
+                                                               0, basename, field->name)) return 1;
+                               }
+                       }
                        /* Function header */
                        fprintf(fd, "static inline size_t lttng_get_alignment_struct_%s(\n",
                                        basename);
@@ -909,6 +932,15 @@ int print_type_alignment_fct(type_descriptor_t * td, FILE *fd,
 
                        break;
                case UNION:
+                       for(unsigned int i=0;i<td->fields.position;i++){
+                               field_t *field = (field_t*)(td->fields.array[i]);
+                               type_descriptor_t *type = field->type;
+                               if(type->type_name == NULL) {
+                                       /* Not a named nested type : we must print its align fct */
+                                       if(print_type_alignment_fct(type, fd,
+                                                               0, basename, field->name)) return 1;
+                               }
+                       }
                        /* Function header */
                        fprintf(fd, "static inline size_t lttng_get_alignment_union_%s(\n",
                                        basename);
@@ -936,6 +968,11 @@ int print_type_alignment_fct(type_descriptor_t * td, FILE *fd,
 
                        break;
                case ARRAY:
+                       if(((field_t*)td->fields.array[0])->type->type_name == NULL) {
+                               /* Not a named nested type : we must print its align fct */
+                               if(print_type_alignment_fct(((field_t*)td->fields.array[0])->type, fd,
+                                                               0, basename, "")) return 1;
+                       }
                        /* Function header */
                        fprintf(fd, "static inline size_t lttng_get_alignment_array_%s(\n",
                                        basename);
@@ -977,6 +1014,8 @@ int print_type_write_fct(type_descriptor_t * td, FILE *fd, unsigned int tabs,
        char basename[PATH_MAX];
        unsigned int basename_len = 0;
        
+       if(td->custom_write) return 0;  /* Does print custom type */
+
        strncpy(basename, nest_name, PATH_MAX);
        basename_len = strlen(basename);
        
@@ -998,9 +1037,41 @@ int print_type_write_fct(type_descriptor_t * td, FILE *fd, unsigned int tabs,
        
        switch(td->type) {
                case SEQUENCE:
+                       if(((field_t*)td->fields.array[1])->type->type_name == NULL) {
+                               /* Not a named nested type : we must print its write fct */
+                               if(print_type_write_fct(((field_t*)td->fields.array[1])->type, fd,
+                                                               0, basename, "")) return 1;
+                       }
+                       break;
                case STRUCT:
+                       for(unsigned int i=0;i<td->fields.position;i++){
+                               field_t *field = (field_t*)(td->fields.array[i]);
+                               type_descriptor_t *type = field->type;
+                               if(type->type_name == NULL) {
+                                       /* Not a named nested type : we must print its write fct */
+                                       if(print_type_write_fct(type, fd,
+                                                               0, basename, field->name)) return 1;
+                               }
+                       }
+                       break;
                case UNION:
+                       for(unsigned int i=0;i<td->fields.position;i++){
+                               field_t *field = (field_t*)(td->fields.array[i]);
+                               type_descriptor_t *type = field->type;
+                               if(type->type_name == NULL) {
+                                       /* Not a named nested type : we must print its write fct */
+                                       if(print_type_write_fct(type, fd,
+                                                               0, basename, field->name)) return 1;
+                               }
+                       }
+                       break;
                case ARRAY:
+                       if(((field_t*)td->fields.array[0])->type->type_name == NULL) {
+                               /* Not a named nested type : we must print its write fct */
+                               if(print_type_write_fct(((field_t*)td->fields.array[0])->type, fd,
+                                                               0, basename, "")) return 1;
+                       }
+                       break;
                case STRING:
                        break;
                default:
@@ -1383,7 +1454,7 @@ int print_event_logging_function(char *basename, facility_t *fac,
                fprintf(fd, "const void **from = &real_from;\n");
                print_tabs(1, fd);
        }
-       fprintf(fd, "cycles_t tsc;\n");
+       fprintf(fd, "u64 tsc;\n");
        print_tabs(1, fd);
        fprintf(fd, "size_t before_hdr_pad, after_hdr_pad, header_size;\n");
        fprintf(fd, "\n");
@@ -1571,131 +1642,665 @@ int print_event_logging_function(char *basename, facility_t *fac,
        return 0;
 }
 
-
-/* ltt-facility-name.h : main logging header.
- * log_header */
-
-void print_log_header_head(facility_t *fac, FILE *fd)
+/* print_event_logging_function_user_generic
+ * Print the logging function of an event for userspace tracing. This is the
+ * core of genevent */
+int print_event_logging_function_user_generic(char *basename, facility_t *fac,
+               event_t *event, FILE *fd)
 {
-       fprintf(fd, "#ifndef _LTT_FACILITY_%s_H_\n", fac->capname);
-       fprintf(fd, "#define _LTT_FACILITY_%s_H_\n\n", fac->capname);
-  fprintf(fd, "#include <linux/types.h>\n");
-       if(!fac->arch)
-         fprintf(fd, "#include <linux/ltt/ltt-facility-id-%s.h>\n", fac->name);
-       else
-         fprintf(fd, "#include <asm/ltt/ltt-facility-id-%s_%s.h>\n",
-                               fac->name,
-                               fac->arch);
-  fprintf(fd, "#include <linux/ltt-core.h>\n");
-       fprintf(fd, "\n");
-}
-
+       char *attrib;
 
-
-int print_log_header_types(facility_t *fac, FILE *fd)
-{
-       sequence_t *types = &fac->named_types.values;
-       fprintf(fd, "/* Named types */\n");
-       fprintf(fd, "\n");
+       fprintf(fd, "#ifndef LTT_TRACE_FAST\n");
        
-       for(unsigned int i = 0; i < types->position; i++) {
-               /* For each named type, print the definition */
-               if(print_type_declaration(types->array[i], fd,
-                                               0, "", "")) return 1;
-               /* Print also the align function */
-               if(print_type_alignment_fct(types->array[i], fd,
-                                               0, "", "")) return 1;
-               /* Print also the write function */
-               if(print_type_write_fct(types->array[i], fd,
-                                               0, "", "")) return 1;
+       if(event->no_instrument_function) {
+               attrib = "__attribute__((no_instrument_function)) ";
+       } else {
+               attrib = "";
        }
-       return 0;
-}
-
-int print_log_header_events(facility_t *fac, FILE *fd)
-{
-       sequence_t *events = &fac->events;
-       char basename[PATH_MAX];
-       unsigned int facname_len;
-       
-       strncpy(basename, fac->name, PATH_MAX);
-       facname_len = strlen(basename);
-       strncat(basename, "_", PATH_MAX-facname_len);
-       facname_len = strlen(basename);
+       if(event->param_buffer) {
+               fprintf(fd, "static inline %sint trace_%s_param_buffer(\n", attrib, basename);
+       } else {
+               fprintf(fd, "static inline %sint trace_%s(\n",attrib, basename);
+       }
+       int     has_argument = 0;
+       int has_type_fixed = 0;
 
-       for(unsigned int i = 0; i < events->position; i++) {
-               event_t *event = (event_t*)events->array[i];
-               strncpy(&basename[facname_len], event->name, PATH_MAX-facname_len);
-               
-               /* For each event, print structure, and then logging function */
-               fprintf(fd, "/* Event %s structures */\n",
-                               event->name);
+       if(event->param_buffer) {
+               if(has_argument) {
+                               fprintf(fd, ",");
+                               fprintf(fd, "\n");
+               }
+               print_tabs(2, fd);
+               fprintf(fd, "void *buffer");
+               has_argument = 1;
+               fprintf(fd, ",");
+               fprintf(fd, "\n");
+               print_tabs(2, fd);
+               fprintf(fd, "size_t reserve_size");
+       } else {
                for(unsigned int j = 0; j < event->fields.position; j++) {
-                       /* For each unnamed type, print the definition */
+                       /* For each field, print the function argument */
                        field_t *f = (field_t*)event->fields.array[j];
                        type_descriptor_t *t = f->type;
-                       if(t->type_name == NULL) {
-                               if((print_type_declaration(t, fd, 0, basename, f->name))) return 1;
-                               /* Print also the align function */
-                               if((print_type_alignment_fct(t, fd, 0, basename, f->name))) return 1;
-                               /* Print also the write function */
-                               if((print_type_write_fct(t, fd, 0, basename, f->name))) return 1;
+                       if(has_argument) {
+                               fprintf(fd, ",");
+                               fprintf(fd, "\n");
                        }
+                       if(print_arg(t, fd, 2, basename, f->name)) return 1;
+                       has_argument = 1;
+               }
+       }
+       if(!has_argument) {
+               print_tabs(2, fd);
+               fprintf(fd, "void");
+       }
+       fprintf(fd,")\n");
+       fprintf(fd, 
+                       "#ifndef LTT_TRACE\n");
+       fprintf(fd, "{\n");
+       fprintf(fd, "}\n");
+       fprintf(fd,"#else\n");
+       fprintf(fd, "{\n");
+       /* Print the function variables */
+       print_tabs(1, fd);
+       fprintf(fd, "int ret = 0;\n");
+       if(event->param_buffer) {
+               print_tabs(1, fd);
+               fprintf(fd, "reserve_size = ltt_align(reserve_size, sizeof(void *));\n");
+               print_tabs(1, fd);
+               fprintf(fd, "{\n");
+               goto do_syscall;
+       }
+       print_tabs(1, fd);
+       fprintf(fd, "void *buffer = NULL;\n");
+       print_tabs(1, fd);
+       fprintf(fd, "size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */\n");
+       print_tabs(1, fd);
+       fprintf(fd, "size_t *to_base = &real_to_base;\n");
+       print_tabs(1, fd);
+       fprintf(fd, "size_t real_to = 0;\n");
+       print_tabs(1, fd);
+       fprintf(fd, "size_t *to = &real_to;\n");
+       print_tabs(1, fd);
+       fprintf(fd, "size_t real_len = 0;\n");
+       print_tabs(1, fd);
+       fprintf(fd, "size_t *len = &real_len;\n");
+       print_tabs(1, fd);
+       fprintf(fd, "size_t reserve_size;\n");
+       print_tabs(1, fd);
+       fprintf(fd, "size_t slot_size;\n");
+       print_tabs(1, fd);
+
+       if(event->fields.position > 0) {
+               for(unsigned int i=0;i<event->fields.position;i++){
+                       /* Search for at least one child with fixed size. It means
+                        * we need local variables.*/
+                       field_t *field = (field_t*)(event->fields.array[i]);
+                       type_descriptor_t *type = field->type;
+                       has_type_fixed = has_type_local(type);
+                       if(has_type_fixed) break;
+               }
+               
+               if(has_type_fixed) {
+                       fprintf(fd, "size_t align;\n");
+                       print_tabs(1, fd);
                }
 
-               fprintf(fd, "\n");
+               fprintf(fd, "const void *real_from;\n");
+               print_tabs(1, fd);
+               fprintf(fd, "const void **from = &real_from;\n");
+               print_tabs(1, fd);
+       }
 
-               fprintf(fd, "/* Event %s logging function */\n",
-                               event->name);
+       /* Calculate event variable len + event data alignment offset.
+        * Assume that the padding for alignment starts at a void*
+        * address.
+        * This excludes the header size and alignment. */
+
+       print_tabs(1, fd);
+       fprintf(fd, "/* For each field, calculate the field size. */\n");
+       print_tabs(1, fd);
+       fprintf(fd, "/* size = *to_base + *to + *len */\n");
+       print_tabs(1, fd);
+       fprintf(fd, "/* Assume that the padding for alignment starts at a\n");
+       print_tabs(1, fd);
+       fprintf(fd, " * sizeof(void *) address. */\n");
+       fprintf(fd, "\n");
 
-               if(print_event_logging_function(basename, fac, event, fd)) return 1;
+       for(unsigned int i=0;i<event->fields.position;i++){
+               field_t *field = (field_t*)(event->fields.array[i]);
+               type_descriptor_t *type = field->type;
+               /* Set from */
+               print_tabs(1, fd);
+               switch(type->type) {
+                       case SEQUENCE:
+                       case UNION:
+                       case ARRAY:
+                       case STRUCT:
+                       case STRING:
+                               fprintf(fd, "*from = lttng_param_%s;\n", field->name);
+                               break;
+                       default:
+                               fprintf(fd, "*from = &lttng_param_%s;\n", field->name);
+                               break;
+               }
 
+               if(print_type_write(type,
+                               fd, 1, basename, field->name, "lttng_param_", 0)) return 1;
                fprintf(fd, "\n");
        }
-       
-       return 0;
-}
-
+       print_tabs(1, fd);
+       fprintf(fd, "reserve_size = *to_base + *to + *len;\n");
 
-void print_log_header_tail(facility_t *fac, FILE *fd)
-{
-       fprintf(fd, "#endif //_LTT_FACILITY_%s_H_\n",fac->capname);
-}
-       
-int print_log_header(facility_t *fac)
-{
-       char filename[PATH_MAX];
-       unsigned int filename_size = 0;
-       FILE *fd;
-       dprintf("%s\n", fac->name);
+       print_tabs(1, fd);
+       fprintf(fd, "{\n");
+       print_tabs(2, fd);
+       fprintf(fd, "char stack_buffer[reserve_size];\n");
+       print_tabs(2, fd);
+       fprintf(fd, "buffer = stack_buffer;\n");
+       fprintf(fd, "\n");
 
-       strcpy(filename, "ltt-facility-");
-       filename_size = strlen(filename);
        
-       strncat(filename, fac->name, PATH_MAX - filename_size);
-       filename_size = strlen(filename);
-
-       if(fac->arch) {
-               strncat(filename, "_", PATH_MAX - filename_size);
-               filename_size = strlen(filename);
+       //print_tabs(2, fd);
+       // for DEBUG only 
+       // fprintf(fd, "goto commit; /* DEBUG : never actually write. */\n\n");
+       print_tabs(2, fd);
+       fprintf(fd, "*to_base = *to = *len = 0;\n");
+       fprintf(fd, "\n");
 
-               strncat(filename, fac->arch, PATH_MAX - filename_size);
-               filename_size = strlen(filename);
-       }
+       /* write data. */
 
-       strncat(filename, ".h", PATH_MAX - filename_size);
-       filename_size = strlen(filename);
+       for(unsigned int i=0;i<event->fields.position;i++){
+               field_t *field = (field_t*)(event->fields.array[i]);
+               type_descriptor_t *type = field->type;
        
-
-       fd = fopen(filename, "w");
-       if(fd == NULL) {
+               /* Set from */
+               print_tabs(2, fd);
+               switch(type->type) {
+                       case SEQUENCE:
+                       case UNION:
+                       case ARRAY:
+                       case STRUCT:
+                       case STRING:
+                               fprintf(fd, "*from = lttng_param_%s;\n", field->name);
+                               break;
+                       default:
+                               fprintf(fd, "*from = &lttng_param_%s;\n", field->name);
+                               break;
+               }
+
+
+               if(print_type_write(type,
+                               fd, 2, basename, field->name, "lttng_param_", 0)) return 1;
+               fprintf(fd, "\n");
+               
+               /* Don't forget to flush pending memcpy */
+               print_tabs(2, fd);
+               fprintf(fd, "/* Flush pending memcpy */\n");
+               print_tabs(2, fd);
+               fprintf(fd, "if(*len != 0) {\n");
+               print_tabs(3, fd);
+               fprintf(fd, "memcpy(buffer+*to_base+*to, *from, *len);\n");
+               print_tabs(3, fd);
+               fprintf(fd, "*to += *len;\n");
+               //print_tabs(3, fd);
+               //fprintf(fd, "from += len;\n");
+               print_tabs(3, fd);
+               fprintf(fd, "*len = 0;\n");
+               print_tabs(2, fd);
+               fprintf(fd, "}\n");
+               fprintf(fd, "\n");
+       }
+
+do_syscall:
+       print_tabs(2, fd);
+       fprintf(fd, "ret = ltt_trace_generic(ltt_facility_%s_%X, event_%s_%s, buffer, reserve_size, LTT_BLOCKING);\n", fac->name, fac->checksum, fac->name, event->name);
+
+       print_tabs(1, fd);
+       fprintf(fd, "}\n\n");
+       
+       print_tabs(1, fd);
+       fprintf(fd, "return ret;\n\n");
+
+       fprintf(fd, "}\n");
+       fprintf(fd, 
+                       "#endif //LTT_TRACE\n");
+       fprintf(fd, "#endif //!LTT_TRACE_FAST\n\n");
+
+       return 0;
+}
+
+/* print_event_logging_function_user_fast
+ * Print the logging function of an event for userspace tracing. This is the
+ * core of genevent */
+int print_event_logging_function_user_fast(char *basename, facility_t *fac,
+               event_t *event, FILE *fd)
+{
+       char *attrib;
+
+       fprintf(fd, "#ifdef LTT_TRACE_FAST\n");
+       
+       if(event->no_instrument_function) {
+               attrib = "__attribute__((no_instrument_function)) ";
+       } else {
+               attrib = "";
+       }
+       fprintf(fd, "static inline %sint trace_%s(\n",attrib, basename);
+
+       int     has_argument = 0;
+       int has_type_fixed = 0;
+
+       for(unsigned int j = 0; j < event->fields.position; j++) {
+               /* For each field, print the function argument */
+               field_t *f = (field_t*)event->fields.array[j];
+               type_descriptor_t *t = f->type;
+               if(has_argument) {
+                       fprintf(fd, ",");
+                       fprintf(fd, "\n");
+               }
+               if(print_arg(t, fd, 2, basename, f->name)) return 1;
+               has_argument = 1;
+       }
+       if(!has_argument) {
+               print_tabs(2, fd);
+               fprintf(fd, "void");
+       }
+       fprintf(fd,")\n");
+       fprintf(fd, 
+                       "#ifndef LTT_TRACE\n");
+       fprintf(fd, "{\n");
+       fprintf(fd, "}\n");
+       fprintf(fd,"#else\n");
+       fprintf(fd, "{\n");
+       /* Print the function variables */
+       print_tabs(1, fd);
+       fprintf(fd, "unsigned int index;\n");
+       print_tabs(1, fd);
+       fprintf(fd, "struct ltt_trace_info *trace = thread_trace_info;\n");
+       print_tabs(1, fd);
+       fprintf(fd, "struct ltt_buf *ltt_buf;\n");
+       print_tabs(1, fd);
+       fprintf(fd, "void *buffer = NULL;\n");
+       print_tabs(1, fd);
+       fprintf(fd, "size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */\n");
+       print_tabs(1, fd);
+       fprintf(fd, "size_t *to_base = &real_to_base;\n");
+       print_tabs(1, fd);
+       fprintf(fd, "size_t real_to = 0;\n");
+       print_tabs(1, fd);
+       fprintf(fd, "size_t *to = &real_to;\n");
+       print_tabs(1, fd);
+       fprintf(fd, "size_t real_len = 0;\n");
+       print_tabs(1, fd);
+       fprintf(fd, "size_t *len = &real_len;\n");
+       print_tabs(1, fd);
+       fprintf(fd, "size_t reserve_size;\n");
+       print_tabs(1, fd);
+       fprintf(fd, "size_t slot_size;\n");
+       print_tabs(1, fd);
+
+       if(event->fields.position > 0) {
+               for(unsigned int i=0;i<event->fields.position;i++){
+                       /* Search for at least one child with fixed size. It means
+                        * we need local variables.*/
+                       field_t *field = (field_t*)(event->fields.array[i]);
+                       type_descriptor_t *type = field->type;
+                       has_type_fixed = has_type_local(type);
+                       if(has_type_fixed) break;
+               }
+               
+               if(has_type_fixed) {
+                       fprintf(fd, "size_t align;\n");
+                       print_tabs(1, fd);
+               }
+
+               fprintf(fd, "const void *real_from;\n");
+               print_tabs(1, fd);
+               fprintf(fd, "const void **from = &real_from;\n");
+               print_tabs(1, fd);
+       }
+       fprintf(fd, "uint64_t tsc;\n");
+       print_tabs(1, fd);
+       fprintf(fd, "size_t before_hdr_pad, after_hdr_pad, header_size;\n");
+       fprintf(fd, "\n");
+       
+       print_tabs(1, fd);
+       fprintf(fd, "if(!trace) {\n");
+       print_tabs(2, fd);
+       fprintf(fd, "ltt_thread_init();\n");
+       print_tabs(2, fd);
+       fprintf(fd, "trace = thread_trace_info;\n");
+       print_tabs(1, fd);
+       fprintf(fd, "}\n\n");
+       fprintf(fd, "\n");
+
+       /* Calculate event variable len + event data alignment offset.
+        * Assume that the padding for alignment starts at a void*
+        * address.
+        * This excludes the header size and alignment. */
+
+       print_tabs(1, fd);
+       fprintf(fd, "/* For each field, calculate the field size. */\n");
+       print_tabs(1, fd);
+       fprintf(fd, "/* size = *to_base + *to + *len */\n");
+       print_tabs(1, fd);
+       fprintf(fd, "/* Assume that the padding for alignment starts at a\n");
+       print_tabs(1, fd);
+       fprintf(fd, " * sizeof(void *) address. */\n");
+       fprintf(fd, "\n");
+
+       for(unsigned int i=0;i<event->fields.position;i++){
+               field_t *field = (field_t*)(event->fields.array[i]);
+               type_descriptor_t *type = field->type;
+               /* Set from */
+               print_tabs(1, fd);
+               switch(type->type) {
+                       case SEQUENCE:
+                       case UNION:
+                       case ARRAY:
+                       case STRUCT:
+                       case STRING:
+                               fprintf(fd, "*from = lttng_param_%s;\n", field->name);
+                               break;
+                       default:
+                               fprintf(fd, "*from = &lttng_param_%s;\n", field->name);
+                               break;
+               }
+
+               if(print_type_write(type,
+                               fd, 1, basename, field->name, "lttng_param_", 0)) return 1;
+               fprintf(fd, "\n");
+       }
+       print_tabs(1, fd);
+       fprintf(fd, "reserve_size = *to_base + *to + *len;\n");
+
+       print_tabs(1, fd);
+       fprintf(fd, "trace->nesting++;\n");
+
+       /* Get facility index */
+
+       print_tabs(1, fd);
+       fprintf(fd, 
+               "index = ltt_get_index_from_facility(ltt_facility_%s_%X,\n"\
+                               "\t\t\t\t\t\tevent_%s_%s);\n",
+                       fac->name, fac->checksum, fac->name, event->name);
+       fprintf(fd,"\n");
+
+       
+       print_tabs(1, fd);
+       fprintf(fd, "{\n");
+
+       if(event->per_trace) {
+               print_tabs(2, fd);
+               fprintf(fd, "if(dest_trace != trace) continue;\n\n");
+       }
+       print_tabs(2, fd);
+       fprintf(fd, "ltt_buf = ltt_get_channel_from_index(trace, index);\n");
+       print_tabs(2, fd);
+
+       
+       /* Relay reserve */
+       /* If error, increment event lost counter (done by ltt_reserve_slot) and 
+        * return */
+       print_tabs(2, fd);
+       fprintf(fd, "slot_size = 0;\n");
+       print_tabs(2, fd);
+       fprintf(fd, "buffer = ltt_reserve_slot(trace, ltt_buf,\n");
+       print_tabs(3, fd);
+       fprintf(fd, "reserve_size, &slot_size, &tsc,\n");
+       print_tabs(3, fd);
+       fprintf(fd, "&before_hdr_pad, &after_hdr_pad, &header_size);\n");
+       /* If error, return */
+       print_tabs(2, fd);
+       fprintf(fd, "if(!buffer) goto end; /* buffer full */\n\n");
+       //print_tabs(2, fd);
+       // for DEBUG only 
+       // fprintf(fd, "goto commit; /* DEBUG : never actually write. */\n\n");
+       print_tabs(2, fd);
+       fprintf(fd, "*to_base = *to = *len = 0;\n");
+       fprintf(fd, "\n");
+
+       /* Write event header */
+       print_tabs(2, fd);
+       fprintf(fd, "ltt_write_event_header(trace, ltt_buf, buffer,\n");
+       print_tabs(3, fd);
+       fprintf(fd, "ltt_facility_%s_%X, event_%s_%s,\n", fac->name, fac->checksum,
+                                                                       fac->name, event->name);
+       print_tabs(3, fd);
+       fprintf(fd, "reserve_size, before_hdr_pad, tsc);\n");
+       print_tabs(2, fd);
+       fprintf(fd, "*to_base += before_hdr_pad + after_hdr_pad + header_size;\n");
+       fprintf(fd, "\n");
+       
+       /* write data. */
+
+       for(unsigned int i=0;i<event->fields.position;i++){
+               field_t *field = (field_t*)(event->fields.array[i]);
+               type_descriptor_t *type = field->type;
+       
+               /* Set from */
+               print_tabs(2, fd);
+               switch(type->type) {
+                       case SEQUENCE:
+                       case UNION:
+                       case ARRAY:
+                       case STRUCT:
+                       case STRING:
+                               fprintf(fd, "*from = lttng_param_%s;\n", field->name);
+                               break;
+                       default:
+                               fprintf(fd, "*from = &lttng_param_%s;\n", field->name);
+                               break;
+               }
+
+
+               if(print_type_write(type,
+                               fd, 2, basename, field->name, "lttng_param_", 0)) return 1;
+               fprintf(fd, "\n");
+               
+               /* Don't forget to flush pending memcpy */
+               print_tabs(2, fd);
+               fprintf(fd, "/* Flush pending memcpy */\n");
+               print_tabs(2, fd);
+               fprintf(fd, "if(*len != 0) {\n");
+               print_tabs(3, fd);
+               fprintf(fd, "memcpy(buffer+*to_base+*to, *from, *len);\n");
+               print_tabs(3, fd);
+               fprintf(fd, "*to += *len;\n");
+               //print_tabs(3, fd);
+               //fprintf(fd, "from += len;\n");
+               print_tabs(3, fd);
+               fprintf(fd, "*len = 0;\n");
+               print_tabs(2, fd);
+               fprintf(fd, "}\n");
+               fprintf(fd, "\n");
+       }
+
+       
+       /* commit */
+       // for DEBUG only.
+       //fprintf(fd, "commit:\n"); /* DEBUG! */
+       print_tabs(2, fd);
+       fprintf(fd, "ltt_commit_slot(ltt_buf, buffer, slot_size);\n\n");
+       
+       fprintf(fd, "}\n\n");
+
+       fprintf(fd, "end:\n");
+       /* Release locks */
+       print_tabs(1, fd);
+       fprintf(fd, "trace->nesting--;\n");
+
+
+       fprintf(fd, "}\n");
+       fprintf(fd, 
+                       "#endif //LTT_TRACE\n");
+       fprintf(fd, "#endif //LTT_TRACE_FAST\n");
+
+       return 0;
+}
+
+
+
+
+
+
+/* ltt-facility-name.h : main logging header.
+ * log_header */
+
+void print_log_header_head(facility_t *fac, FILE *fd)
+{
+       fprintf(fd, "#ifndef _LTT_FACILITY_%s_H_\n", fac->capname);
+       fprintf(fd, "#define _LTT_FACILITY_%s_H_\n\n", fac->capname);
+  fprintf(fd, "#include <linux/types.h>\n");
+       if(!fac->arch)
+         fprintf(fd, "#include <linux/ltt/ltt-facility-id-%s.h>\n", fac->name);
+       else
+         fprintf(fd, "#include <asm/ltt/ltt-facility-id-%s_%s.h>\n",
+                               fac->name,
+                               fac->arch);
+  fprintf(fd, "#include <linux/ltt-core.h>\n");
+       fprintf(fd, "\n");
+}
+
+/* ltt-facility-name.h : main logging header.
+ * log_header */
+
+void print_log_header_head_user(facility_t *fac, FILE *fd)
+{
+       fprintf(fd, "#ifndef _LTT_FACILITY_%s_H_\n", fac->capname);
+       fprintf(fd, "#define _LTT_FACILITY_%s_H_\n\n", fac->capname);
+  fprintf(fd, "#include <sys/types.h>\n");
+       if(!fac->arch)
+         fprintf(fd, "#include <ltt/ltt-facility-id-%s.h>\n", fac->name);
+       else
+         fprintf(fd, "#include <asm/ltt/ltt-facility-id-%s_%s.h>\n",
+                               fac->name,
+                               fac->arch);
+  fprintf(fd, "#include <ltt/ltt-usertrace.h>\n");
+       fprintf(fd, "\n");
+}
+
+
+int print_log_header_types(facility_t *fac, FILE *fd)
+{
+       sequence_t *types = &fac->named_types.values;
+       fprintf(fd, "/* Named types */\n");
+       fprintf(fd, "\n");
+       
+       for(unsigned int i = 0; i < types->position; i++) {
+               /* For each named type, print the definition */
+               if(print_type_declaration(types->array[i], fd,
+                                               0, "", "")) return 1;
+               /* Print also the align function */
+               if(print_type_alignment_fct(types->array[i], fd,
+                                               0, "", "")) return 1;
+               /* Print also the write function */
+               if(print_type_write_fct(types->array[i], fd,
+                                               0, "", "")) return 1;
+       }
+       return 0;
+}
+
+int print_log_header_events(facility_t *fac, FILE *fd)
+{
+       sequence_t *events = &fac->events;
+       char basename[PATH_MAX];
+       unsigned int facname_len;
+       
+       strncpy(basename, fac->name, PATH_MAX);
+       facname_len = strlen(basename);
+       strncat(basename, "_", PATH_MAX-facname_len);
+       facname_len = strlen(basename);
+
+       for(unsigned int i = 0; i < events->position; i++) {
+               event_t *event = (event_t*)events->array[i];
+               strncpy(&basename[facname_len], event->name, PATH_MAX-facname_len);
+               
+               /* For each event, print structure, and then logging function */
+               fprintf(fd, "/* Event %s structures */\n",
+                               event->name);
+               for(unsigned int j = 0; j < event->fields.position; j++) {
+                       /* For each unnamed type, print the definition */
+                       field_t *f = (field_t*)event->fields.array[j];
+                       type_descriptor_t *t = f->type;
+                       if(t->type_name == NULL) {
+                               if((print_type_declaration(t, fd, 0, basename, f->name))) return 1;
+                               /* Print also the align function */
+                               if((print_type_alignment_fct(t, fd, 0, basename, f->name))) return 1;
+                               /* Print also the write function */
+                               if((print_type_write_fct(t, fd, 0, basename, f->name))) return 1;
+                       }
+               }
+
+               fprintf(fd, "\n");
+
+               fprintf(fd, "/* Event %s logging function */\n",
+                               event->name);
+               
+               if(!fac->user) {
+                       if(print_event_logging_function(basename, fac, event, fd)) return 1;
+               } else {
+                       if(print_event_logging_function_user_generic(basename, fac, event, fd))
+                               return 1;
+                       if(print_event_logging_function_user_fast(basename, fac, event, fd))
+                               return 1;
+               }
+
+               fprintf(fd, "\n");
+       }
+       
+       return 0;
+}
+
+
+void print_log_header_tail(facility_t *fac, FILE *fd)
+{
+       fprintf(fd, "#endif //_LTT_FACILITY_%s_H_\n",fac->capname);
+}
+
+void print_log_header_tail_user(facility_t *fac, FILE *fd)
+{
+       fprintf(fd, "#endif //_LTT_FACILITY_%s_H_\n",fac->capname);
+}
+       
+int print_log_header(facility_t *fac)
+{
+       char filename[PATH_MAX];
+       unsigned int filename_size = 0;
+       FILE *fd;
+       dprintf("%s\n", fac->name);
+
+       strcpy(filename, "ltt-facility-");
+       filename_size = strlen(filename);
+       
+       strncat(filename, fac->name, PATH_MAX - filename_size);
+       filename_size = strlen(filename);
+
+       if(fac->arch) {
+               strncat(filename, "_", PATH_MAX - filename_size);
+               filename_size = strlen(filename);
+
+               strncat(filename, fac->arch, PATH_MAX - filename_size);
+               filename_size = strlen(filename);
+       }
+
+       strncat(filename, ".h", PATH_MAX - filename_size);
+       filename_size = strlen(filename);
+       
+
+       fd = fopen(filename, "w");
+       if(fd == NULL) {
                printf("Error opening file %s for writing : %s\n",
                                filename, strerror(errno));
                return errno;
        }
 
        /* Print file head */
-       print_log_header_head(fac, fd);
+       if(!fac->user)
+               print_log_header_head(fac, fd);
+       else
+               print_log_header_head_user(fac, fd);
 
        /* print named types in declaration order */
        if(print_log_header_types(fac, fd)) return 1;
@@ -1704,7 +2309,11 @@ int print_log_header(facility_t *fac)
        if(print_log_header_events(fac, fd)) return 1;
        
        /* Print file tail */
-       print_log_header_tail(fac, fd);
+       if(!fac->user)
+               print_log_header_tail(fac, fd);
+       else
+               print_log_header_tail_user(fac, fd);
+
 
        
        fclose(fd);
@@ -1750,39 +2359,75 @@ int print_id_header(facility_t *fac)
                return errno;
        }
 
-  fprintf(fd, "#ifndef _LTT_FACILITY_ID_%s_H_\n",fac->capname);
-  fprintf(fd, "#define _LTT_FACILITY_ID_%s_H_\n\n",fac->capname);
-  fprintf(fd, "#ifdef CONFIG_LTT\n");
+       if(!fac->user) {
+               fprintf(fd, "#ifndef _LTT_FACILITY_ID_%s_H_\n",fac->capname);
+               fprintf(fd, "#define _LTT_FACILITY_ID_%s_H_\n\n",fac->capname);
+               fprintf(fd, "#ifdef CONFIG_LTT\n");
 
-  fprintf(fd,"#include <linux/ltt-facilities.h>\n\n");
+               fprintf(fd,"#include <linux/ltt-facilities.h>\n\n");
 
-  fprintf(fd,"/****  facility handle  ****/\n\n");
-  fprintf(fd,"extern ltt_facility_t ltt_facility_%s_%X;\n",
-                       fac->name, fac->checksum);
-  fprintf(fd,"extern ltt_facility_t ltt_facility_%s;\n\n\n",fac->name);
+               fprintf(fd,"/****  facility handle  ****/\n\n");
+               fprintf(fd,"extern ltt_facility_t ltt_facility_%s_%X;\n",
+                               fac->name, fac->checksum);
+               fprintf(fd,"extern ltt_facility_t ltt_facility_%s;\n\n\n",fac->name);
 
-       strncpy(basename, fac->name, PATH_MAX);
-       basename_len = strlen(basename);
-       strncat(basename, "_", PATH_MAX - basename_len);
-       basename_len++;
-       
-       fprintf(fd,"/****  event index  ****/\n\n");
-       fprintf(fd,"enum %s_event {\n",fac->name);
-       
-       for(unsigned int i = 0; i < fac->events.position; i++) {
-               event_t *event = (event_t*)fac->events.array[i];
-               strncpy(basename+basename_len, event->name, PATH_MAX-basename_len);
+               strncpy(basename, fac->name, PATH_MAX);
+               basename_len = strlen(basename);
+               strncat(basename, "_", PATH_MAX - basename_len);
+               basename_len++;
+               
+               fprintf(fd,"/****  event index  ****/\n\n");
+               fprintf(fd,"enum %s_event {\n",fac->name);
+               
+               for(unsigned int i = 0; i < fac->events.position; i++) {
+                       event_t *event = (event_t*)fac->events.array[i];
+                       strncpy(basename+basename_len, event->name, PATH_MAX-basename_len);
+                       print_tabs(1, fd);
+                       fprintf(fd, "event_%s,\n", basename);
+               }
                print_tabs(1, fd);
-               fprintf(fd, "event_%s,\n", basename);
-       }
-       print_tabs(1, fd);
-       fprintf(fd, "facility_%s_num_events\n", fac->name);
-       fprintf(fd, "};\n");
-       fprintf(fd, "\n");
+               fprintf(fd, "facility_%s_num_events\n", fac->name);
+               fprintf(fd, "};\n");
+               fprintf(fd, "\n");
 
 
-  fprintf(fd, "#endif //CONFIG_LTT\n");
-  fprintf(fd, "#endif //_LTT_FACILITY_ID_%s_H_\n",fac->capname);
+               fprintf(fd, "#endif //CONFIG_LTT\n");
+               fprintf(fd, "#endif //_LTT_FACILITY_ID_%s_H_\n",fac->capname);
+       } else {
+               fprintf(fd, "#ifndef _LTT_FACILITY_ID_%s_H_\n",fac->capname);
+               fprintf(fd, "#define _LTT_FACILITY_ID_%s_H_\n\n",fac->capname);
+               fprintf(fd, "#ifdef LTT_TRACE\n");
+
+               fprintf(fd,"#include <ltt/ltt-usertrace.h>\n\n");
+
+               fprintf(fd,"/****  facility handle  ****/\n\n");
+               fprintf(fd,"extern ltt_facility_t ltt_facility_%s_%X;\n",
+                               fac->name, fac->checksum);
+               fprintf(fd,"extern ltt_facility_t ltt_facility_%s;\n\n\n",fac->name);
+
+               strncpy(basename, fac->name, PATH_MAX);
+               basename_len = strlen(basename);
+               strncat(basename, "_", PATH_MAX - basename_len);
+               basename_len++;
+               
+               fprintf(fd,"/****  event index  ****/\n\n");
+               fprintf(fd,"enum %s_event {\n",fac->name);
+               
+               for(unsigned int i = 0; i < fac->events.position; i++) {
+                       event_t *event = (event_t*)fac->events.array[i];
+                       strncpy(basename+basename_len, event->name, PATH_MAX-basename_len);
+                       print_tabs(1, fd);
+                       fprintf(fd, "event_%s,\n", basename);
+               }
+               print_tabs(1, fd);
+               fprintf(fd, "facility_%s_num_events\n", fac->name);
+               fprintf(fd, "};\n");
+               fprintf(fd, "\n");
+
+
+               fprintf(fd, "#endif //LTT_TRACE\n");
+               fprintf(fd, "#endif //_LTT_FACILITY_ID_%s_H_\n",fac->capname);
+       }
 
 
        fclose(fd);
@@ -1856,7 +2501,70 @@ int print_loader_header(facility_t *fac)
        return 0;
 }
 
-/* ltt-facility-loader-name.c : generic faciilty loader
+int print_loader_header_user(facility_t *fac)
+{
+       char filename[PATH_MAX];
+       unsigned int filename_size = 0;
+       FILE *fd;
+       dprintf("%s\n", fac->name);
+
+       strcpy(filename, "ltt-facility-loader-");
+       filename_size = strlen(filename);
+       
+       strncat(filename, fac->name, PATH_MAX - filename_size);
+       filename_size = strlen(filename);
+
+       if(fac->arch) {
+               strncat(filename, "_", PATH_MAX - filename_size);
+               filename_size = strlen(filename);
+
+               strncat(filename, fac->arch, PATH_MAX - filename_size);
+               filename_size = strlen(filename);
+       }
+
+       strncat(filename, ".h", PATH_MAX - filename_size);
+       filename_size = strlen(filename);
+       
+
+       fd = fopen(filename, "w");
+       if(fd == NULL) {
+               printf("Error opening file %s for writing : %s\n",
+                               filename, strerror(errno));
+               return errno;
+       }
+
+  fprintf(fd, "#ifndef _LTT_FACILITY_LOADER_%s_H_\n", fac->capname);
+  fprintf(fd, "#define _LTT_FACILITY_LOADER_%s_H_\n\n", fac->capname);
+  fprintf(fd,"#include <ltt/ltt-usertrace.h>\n");
+       if(!fac->arch)
+         fprintf(fd,"#include <ltt/ltt-facility-id-%s.h>\n\n",
+                               fac->name);
+       else
+         fprintf(fd,"#include <asm/ltt/ltt-facility-id-%s_%s.h>\n\n",
+                               fac->name,
+                               fac->arch);
+  fprintf(fd,"ltt_facility_t\tltt_facility_%s;\n", fac->name);
+  fprintf(fd,"ltt_facility_t\tltt_facility_%s_%X;\n\n",
+                       fac->name, fac->checksum);
+
+  fprintf(fd,"#define LTT_FACILITY_SYMBOL\t\t\t\t\t\t\tltt_facility_%s\n",
+      fac->name);
+  fprintf(fd,"#define LTT_FACILITY_CHECKSUM_SYMBOL\t\tltt_facility_%s_%X\n",
+      fac->name, fac->checksum);
+  fprintf(fd,"#define LTT_FACILITY_CHECKSUM\t\t\t\t\t\t0x%X\n", fac->checksum);
+  fprintf(fd,"#define LTT_FACILITY_NAME\t\t\t\t\t\t\t\t\"%s\"\n", fac->name);
+  fprintf(fd,"#define LTT_FACILITY_NUM_EVENTS\t\t\t\t\tfacility_%s_num_events\n\n",
+                       fac->name);
+  fprintf(fd, "#endif //_LTT_FACILITY_LOADER_%s_H_\n", fac->capname);
+
+       fclose(fd);
+
+       return 0;
+}
+
+
+
+/* ltt-facility-loader-name.c : generic facility loader
  * loader_c */
 int print_loader_c(facility_t *fac)
 {
@@ -1931,51 +2639,31 @@ int print_loader_c(facility_t *fac)
   fprintf(fd, "\t.symbol = SYMBOL_STRING(LTT_FACILITY_SYMBOL),\n");
   fprintf(fd, "};\n");
   fprintf(fd, "\n");
-  fprintf(fd, "#ifndef MODULE\n");
-  fprintf(fd, "\n");
-  fprintf(fd, "/* Built-in facility. */\n");
-  fprintf(fd, "\n");
   fprintf(fd, "static int __init facility_init(void)\n");
   fprintf(fd, "{\n");
   fprintf(fd, "\tprintk(KERN_INFO \"LTT : ltt-facility-%s init in kernel\\n\");\n", fac->name);
   fprintf(fd, "\n");
-  fprintf(fd, "\tLTT_FACILITY_SYMBOL = ltt_facility_builtin_register(&facility);\n");
+  fprintf(fd, "\tLTT_FACILITY_SYMBOL = ltt_facility_kernel_register(&facility);\n");
   fprintf(fd, "\tLTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;\n");
   fprintf(fd, "\t\n");
   fprintf(fd, "\treturn LTT_FACILITY_SYMBOL;\n");
   fprintf(fd, "}\n");
-  fprintf(fd, "__initcall(facility_init);\n");
-  fprintf(fd, "\n");
-  fprintf(fd, "\n");
-  fprintf(fd, "\n");
-  fprintf(fd, "#else \n");
-  fprintf(fd, "\n");
-  fprintf(fd, "/* Dynamic facility. */\n");
-  fprintf(fd, "\n");
-  fprintf(fd, "static int __init facility_init(void)\n");
-  fprintf(fd, "{\n");
-  fprintf(fd, "\tprintk(KERN_INFO \"LTT : ltt-facility-%s init dynamic\\n\");\n", fac->name);
-  fprintf(fd, "\n");
-  fprintf(fd, "\tLTT_FACILITY_SYMBOL = ltt_facility_dynamic_register(&facility);\n");
-  fprintf(fd, "\tLTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;\n");
-  fprintf(fd, "\n");
-  fprintf(fd, "\treturn LTT_FACILITY_SYMBOL;\n");
-  fprintf(fd, "}\n");
   fprintf(fd, "\n");
+  fprintf(fd, "#ifndef MODULE\n");
+  fprintf(fd, "__initcall(facility_init);\n");
+  fprintf(fd, "#else\n");
+  fprintf(fd, "module_init(facility_init);\n");
   fprintf(fd, "static void __exit facility_exit(void)\n");
   fprintf(fd, "{\n");
   fprintf(fd, "\tint err;\n");
   fprintf(fd, "\n");
-  fprintf(fd, "\terr = ltt_facility_dynamic_unregister(LTT_FACILITY_SYMBOL);\n");
+  fprintf(fd, "\terr = ltt_facility_unregister(LTT_FACILITY_SYMBOL);\n");
   fprintf(fd, "\tif(err != 0)\n");
   fprintf(fd, "\t\tprintk(KERN_ERR \"LTT : Error in unregistering facility.\\n\");\n");
   fprintf(fd, "\n");
   fprintf(fd, "}\n");
-  fprintf(fd, "\n");
-  fprintf(fd, "module_init(facility_init)\n");
   fprintf(fd, "module_exit(facility_exit)\n");
   fprintf(fd, "\n");
-  fprintf(fd, "\n");
   fprintf(fd, "MODULE_LICENSE(\"GPL\");\n");
   fprintf(fd, "MODULE_AUTHOR(\"Mathieu Desnoyers\");\n");
   fprintf(fd, "MODULE_DESCRIPTION(\"Linux Trace Toolkit Facility\");\n");
@@ -1989,6 +2677,100 @@ int print_loader_c(facility_t *fac)
        return 0;
 }
 
+int print_loader_c_user(facility_t *fac)
+{
+       char filename[PATH_MAX];
+       unsigned int filename_size = 0;
+       FILE *fd;
+       dprintf("%s\n", fac->name);
+
+       strcpy(filename, "ltt-facility-loader-");
+       filename_size = strlen(filename);
+       
+       strncat(filename, fac->name, PATH_MAX - filename_size);
+       filename_size = strlen(filename);
+
+       if(fac->arch) {
+               strncat(filename, "_", PATH_MAX - filename_size);
+               filename_size = strlen(filename);
+
+               strncat(filename, fac->arch, PATH_MAX - filename_size);
+               filename_size = strlen(filename);
+       }
+
+       strncat(filename, ".c", PATH_MAX - filename_size);
+       filename_size = strlen(filename);
+       
+
+       fd = fopen(filename, "w");
+       if(fd == NULL) {
+               printf("Error opening file %s for writing : %s\n",
+                               filename, strerror(errno));
+               return errno;
+       }
+
+  fprintf(fd, "/*\n");
+       if(!fac->arch)
+         fprintf(fd, " * ltt-facility-loader-%s.c\n", fac->name);
+       else
+         fprintf(fd, " * ltt-facility-loader-%s_%s.c\n", fac->name, fac->arch);
+  fprintf(fd, " *\n");
+  fprintf(fd, " * (C) Copyright  2005 - \n");
+  fprintf(fd, " *          Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)\n");
+  fprintf(fd, " *\n");
+  fprintf(fd, " * Contains the LTT user space facility loader.\n");
+  fprintf(fd, " *\n");
+  fprintf(fd, " */\n");
+  fprintf(fd, "\n");
+  fprintf(fd, "\n");
+  fprintf(fd, "#define LTT_TRACE\n");
+  fprintf(fd, "#include <error.h>\n");
+  fprintf(fd, "#include <stdio.h>\n");
+  fprintf(fd, "#include <ltt/ltt-usertrace.h>\n");
+       if(!fac->arch)
+       fprintf(fd, "#include \"ltt-facility-loader-%s.h\"\n", fac->name);
+       else
+         fprintf(fd, "#include \"ltt-facility-loader-%s_%s.h\"\n",
+                               fac->name, fac->arch);
+  fprintf(fd, "\n");
+  fprintf(fd, "static struct user_facility_info facility = {\n");
+  fprintf(fd, "\t.name = LTT_FACILITY_NAME,\n");
+  fprintf(fd, "\t.num_events = LTT_FACILITY_NUM_EVENTS,\n");
+  fprintf(fd, "#ifndef LTT_PACK\n");
+  fprintf(fd, "\t.alignment = sizeof(void*),\n");
+  fprintf(fd, "#else\n");
+  fprintf(fd, "\t.alignment = 0,\n");
+  fprintf(fd, "#endif //LTT_PACK\n");
+  fprintf(fd, "\t.checksum = LTT_FACILITY_CHECKSUM,\n");
+  fprintf(fd, "\t.int_size = sizeof(int),\n");
+  fprintf(fd, "\t.long_size = sizeof(long),\n");
+  fprintf(fd, "\t.pointer_size = sizeof(void*),\n");
+  fprintf(fd, "\t.size_t_size = sizeof(size_t)\n");
+  fprintf(fd, "};\n");
+  fprintf(fd, "\n");
+  fprintf(fd, "static void __attribute__((constructor)) __ltt_user_init(void)\n");
+  fprintf(fd, "{\n");
+  fprintf(fd, "\tint err;\n");
+       fprintf(fd, "#ifdef LTT_SHOW_DEBUG\n");
+  fprintf(fd, "\tprintf(\"LTT : ltt-facility-%s init in userspace\\n\");\n", fac->name);
+       fprintf(fd, "#endif //LTT_SHOW_DEBUG\n");
+  fprintf(fd, "\n");
+  fprintf(fd, "\terr = ltt_register_generic(&LTT_FACILITY_SYMBOL, &facility);\n");
+  fprintf(fd, "\tLTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;\n");
+  fprintf(fd, "\t\n");
+  fprintf(fd, "\tif(err) {\n");
+       fprintf(fd, "#ifdef LTT_SHOW_DEBUG\n");
+  fprintf(fd, "\t\tperror(\"Error in ltt_register_generic\");\n");
+       fprintf(fd, "#endif //LTT_SHOW_DEBUG\n");
+  fprintf(fd, "\t}\n");
+  fprintf(fd, "}\n");
+  fprintf(fd, "\n");
+
+       fclose(fd);
+
+       return 0;
+}
+
 
 
 /* open facility */
@@ -2036,7 +2818,23 @@ facility_t *ltt_facility_open(char * pathname)
                
                if(strcmp(token, "<")) in.error(&in,"not a facility file");
                token = getName(&in);
+               if(strcmp(token, "?")) in.error(&in,"not a facility file");
+               token = getName(&in);
+               if(strcmp(token, "xml")) in.error(&in,"not a facility file");
+               token = getName(&in);
+               if(strcmp(token, "version")) in.error(&in,"not a facility file");
+               token = getName(&in);
+               if(strcmp(token, "=")) in.error(&in,"not a facility file");
+               token = getQuotedString(&in);
+               if(strcmp(token, "1.0")) in.error(&in,"not a facility file");
+               token = getName(&in);
+               if(strcmp(token, "?")) in.error(&in,"not a facility file");
+               token = getToken(&in);
+               if(strcmp(token, ">")) in.error(&in,"not a facility file");
 
+               token = getName(&in);
+               if(strcmp(token, "<")) in.error(&in,"not a facility file");
+               token = getName(&in);
                if(strcmp("facility",token) == 0) {
                        fac = malloc(sizeof(facility_t));
                        fac->name = NULL;
@@ -2158,12 +2956,18 @@ int main(int argc, char **argv)
        
        /* ltt-facility-loader-name.h : facility specific loader info.
         * loader_header */
-       err = print_loader_header(fac);
+       if(!fac->user)
+               err = print_loader_header(fac);
+       else
+               err = print_loader_header_user(fac);
        if(err) return err;
 
        /* ltt-facility-loader-name.c : generic faciilty loader
         * loader_c */
-       err = print_loader_c(fac);
+       if(!fac->user)
+               err = print_loader_c(fac);
+       else
+               err = print_loader_c_user(fac);
        if(err) return err;
 
        /* close the facility */
This page took 0.038621 seconds and 4 git commands to generate.