@@ -808,6 +808,174 @@ EXPORT_SYMBOL_GPL(unregister_trace_event);
808808 * Standard events
809809 */
810810
811+ static void print_array (struct trace_iterator * iter , void * pos ,
812+ struct ftrace_event_field * field )
813+ {
814+ int offset ;
815+ int len ;
816+ int i ;
817+
818+ offset = * (int * )pos & 0xffff ;
819+ len = * (int * )pos >> 16 ;
820+
821+ if (field )
822+ offset += field -> offset ;
823+
824+ if (offset + len >= iter -> ent_size ) {
825+ trace_seq_puts (& iter -> seq , "<OVERFLOW>" );
826+ return ;
827+ }
828+
829+ for (i = 0 ; i < len ; i ++ , pos ++ ) {
830+ if (i )
831+ trace_seq_putc (& iter -> seq , ',' );
832+ trace_seq_printf (& iter -> seq , "%02x" , * (unsigned char * )pos );
833+ }
834+ }
835+
836+ static void print_fields (struct trace_iterator * iter , struct trace_event_call * call ,
837+ struct list_head * head )
838+ {
839+ struct ftrace_event_field * field ;
840+ int offset ;
841+ int len ;
842+ int ret ;
843+ void * pos ;
844+
845+ list_for_each_entry (field , head , link ) {
846+ trace_seq_printf (& iter -> seq , " %s=" , field -> name );
847+ if (field -> offset + field -> size > iter -> ent_size ) {
848+ trace_seq_puts (& iter -> seq , "<OVERFLOW>" );
849+ continue ;
850+ }
851+ pos = (void * )iter -> ent + field -> offset ;
852+
853+ switch (field -> filter_type ) {
854+ case FILTER_COMM :
855+ case FILTER_STATIC_STRING :
856+ trace_seq_printf (& iter -> seq , "%.*s" , field -> size , (char * )pos );
857+ break ;
858+ case FILTER_RDYN_STRING :
859+ case FILTER_DYN_STRING :
860+ offset = * (int * )pos & 0xffff ;
861+ len = * (int * )pos >> 16 ;
862+
863+ if (field -> filter_type == FILTER_RDYN_STRING )
864+ offset += field -> offset ;
865+
866+ if (offset + len >= iter -> ent_size ) {
867+ trace_seq_puts (& iter -> seq , "<OVERFLOW>" );
868+ break ;
869+ }
870+ pos = (void * )iter -> ent + offset ;
871+ trace_seq_printf (& iter -> seq , "%.*s" , len , (char * )pos );
872+ break ;
873+ case FILTER_PTR_STRING :
874+ if (!iter -> fmt_size )
875+ trace_iter_expand_format (iter );
876+ pos = * (void * * )pos ;
877+ ret = strncpy_from_kernel_nofault (iter -> fmt , pos ,
878+ iter -> fmt_size );
879+ if (ret < 0 )
880+ trace_seq_printf (& iter -> seq , "(0x%px)" , pos );
881+ else
882+ trace_seq_printf (& iter -> seq , "(0x%px:%s)" ,
883+ pos , iter -> fmt );
884+ break ;
885+ case FILTER_TRACE_FN :
886+ pos = * (void * * )pos ;
887+ trace_seq_printf (& iter -> seq , "%pS" , pos );
888+ break ;
889+ case FILTER_CPU :
890+ case FILTER_OTHER :
891+ switch (field -> size ) {
892+ case 1 :
893+ if (isprint (* (char * )pos )) {
894+ trace_seq_printf (& iter -> seq , "'%c'" ,
895+ * (unsigned char * )pos );
896+ }
897+ trace_seq_printf (& iter -> seq , "(%d)" ,
898+ * (unsigned char * )pos );
899+ break ;
900+ case 2 :
901+ trace_seq_printf (& iter -> seq , "0x%x (%d)" ,
902+ * (unsigned short * )pos ,
903+ * (unsigned short * )pos );
904+ break ;
905+ case 4 :
906+ /* dynamic array info is 4 bytes */
907+ if (strstr (field -> type , "__data_loc" )) {
908+ print_array (iter , pos , NULL );
909+ break ;
910+ }
911+
912+ if (strstr (field -> type , "__rel_loc" )) {
913+ print_array (iter , pos , field );
914+ break ;
915+ }
916+
917+ trace_seq_printf (& iter -> seq , "0x%x (%d)" ,
918+ * (unsigned int * )pos ,
919+ * (unsigned int * )pos );
920+ break ;
921+ case 8 :
922+ trace_seq_printf (& iter -> seq , "0x%llx (%lld)" ,
923+ * (unsigned long long * )pos ,
924+ * (unsigned long long * )pos );
925+ break ;
926+ default :
927+ trace_seq_puts (& iter -> seq , "<INVALID-SIZE>" );
928+ break ;
929+ }
930+ break ;
931+ default :
932+ trace_seq_puts (& iter -> seq , "<INVALID-TYPE>" );
933+ }
934+ }
935+ trace_seq_putc (& iter -> seq , '\n' );
936+ }
937+
938+ enum print_line_t print_event_fields (struct trace_iterator * iter ,
939+ struct trace_event * event )
940+ {
941+ struct trace_event_call * call ;
942+ struct list_head * head ;
943+
944+ /* ftrace defined events have separate call structures */
945+ if (event -> type <= __TRACE_LAST_TYPE ) {
946+ bool found = false;
947+
948+ down_read (& trace_event_sem );
949+ list_for_each_entry (call , & ftrace_events , list ) {
950+ if (call -> event .type == event -> type ) {
951+ found = true;
952+ break ;
953+ }
954+ /* No need to search all events */
955+ if (call -> event .type > __TRACE_LAST_TYPE )
956+ break ;
957+ }
958+ up_read (& trace_event_sem );
959+ if (!found ) {
960+ trace_seq_printf (& iter -> seq , "UNKNOWN TYPE %d\n" , event -> type );
961+ goto out ;
962+ }
963+ } else {
964+ call = container_of (event , struct trace_event_call , event );
965+ }
966+ head = trace_get_fields (call );
967+
968+ trace_seq_printf (& iter -> seq , "%s:" , trace_event_name (call ));
969+
970+ if (head && !list_empty (head ))
971+ print_fields (iter , call , head );
972+ else
973+ trace_seq_puts (& iter -> seq , "No fields found\n" );
974+
975+ out :
976+ return trace_handle_return (& iter -> seq );
977+ }
978+
811979enum print_line_t trace_nop_print (struct trace_iterator * iter , int flags ,
812980 struct trace_event * event )
813981{
0 commit comments