@@ -808,6 +808,174 @@ EXPORT_SYMBOL_GPL(unregister_trace_event);
808
808
* Standard events
809
809
*/
810
810
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
+
811
979
enum print_line_t trace_nop_print (struct trace_iterator * iter , int flags ,
812
980
struct trace_event * event )
813
981
{
0 commit comments