@@ -879,6 +879,122 @@ static void test_btf_dump_var_data(struct btf *btf, struct btf_dump *d,
879
879
"static int bpf_cgrp_storage_busy = (int)2" , 2 );
880
880
}
881
881
882
+ struct btf_dump_string_ctx {
883
+ struct btf * btf ;
884
+ struct btf_dump * d ;
885
+ char * str ;
886
+ struct btf_dump_type_data_opts * opts ;
887
+ int array_id ;
888
+ };
889
+
890
+ static int btf_dump_one_string (struct btf_dump_string_ctx * ctx ,
891
+ char * ptr , size_t ptr_sz ,
892
+ const char * expected_val )
893
+ {
894
+ size_t type_sz ;
895
+ int ret ;
896
+
897
+ ctx -> str [0 ] = '\0' ;
898
+ type_sz = btf__resolve_size (ctx -> btf , ctx -> array_id );
899
+ ret = btf_dump__dump_type_data (ctx -> d , ctx -> array_id , ptr , ptr_sz , ctx -> opts );
900
+ if (type_sz <= ptr_sz ) {
901
+ if (!ASSERT_EQ (ret , type_sz , "failed/unexpected type_sz" ))
902
+ return - EINVAL ;
903
+ }
904
+ if (!ASSERT_STREQ (ctx -> str , expected_val , "ensure expected/actual match" ))
905
+ return - EFAULT ;
906
+ return 0 ;
907
+ }
908
+
909
+ static void btf_dump_strings (struct btf_dump_string_ctx * ctx )
910
+ {
911
+ struct btf_dump_type_data_opts * opts = ctx -> opts ;
912
+
913
+ opts -> emit_strings = true;
914
+
915
+ opts -> compact = true;
916
+ opts -> emit_zeroes = false;
917
+
918
+ opts -> skip_names = false;
919
+ btf_dump_one_string (ctx , "foo" , 4 , "(char[4])\"foo\"" );
920
+
921
+ opts -> skip_names = true;
922
+ btf_dump_one_string (ctx , "foo" , 4 , "\"foo\"" );
923
+
924
+ /* This should have no effect. */
925
+ opts -> emit_zeroes = false;
926
+ btf_dump_one_string (ctx , "foo" , 4 , "\"foo\"" );
927
+
928
+ /* This should have no effect. */
929
+ opts -> compact = false;
930
+ btf_dump_one_string (ctx , "foo" , 4 , "\"foo\"" );
931
+
932
+ /* Non-printable characters come out as hex. */
933
+ btf_dump_one_string (ctx , "fo\xff" , 4 , "\"fo\\xff\"" );
934
+ btf_dump_one_string (ctx , "fo\x7" , 4 , "\"fo\\x07\"" );
935
+
936
+ /*
937
+ * Strings that are too long for the specified type ("char[4]")
938
+ * should fall back to the current behavior.
939
+ */
940
+ opts -> compact = true;
941
+ btf_dump_one_string (ctx , "abcde" , 6 , "['a','b','c','d',]" );
942
+
943
+ /*
944
+ * Strings that are too short for the specified type ("char[4]")
945
+ * should work normally.
946
+ */
947
+ btf_dump_one_string (ctx , "ab" , 3 , "\"ab\"" );
948
+
949
+ /* Non-NUL-terminated arrays don't get printed as strings. */
950
+ char food [4 ] = { 'f' , 'o' , 'o' , 'd' };
951
+ char bye [3 ] = { 'b' , 'y' , 'e' };
952
+
953
+ btf_dump_one_string (ctx , food , 4 , "['f','o','o','d',]" );
954
+ btf_dump_one_string (ctx , bye , 3 , "['b','y','e',]" );
955
+
956
+ /* The embedded NUL should terminate the string. */
957
+ char embed [4 ] = { 'f' , 'o' , '\0' , 'd' };
958
+
959
+ btf_dump_one_string (ctx , embed , 4 , "\"fo\"" );
960
+ }
961
+
962
+ static void test_btf_dump_string_data (void )
963
+ {
964
+ struct test_ctx t = {};
965
+ char str [STRSIZE ];
966
+ struct btf_dump * d ;
967
+ DECLARE_LIBBPF_OPTS (btf_dump_type_data_opts , opts );
968
+ struct btf_dump_string_ctx ctx ;
969
+ int char_id , int_id , array_id ;
970
+
971
+ if (test_ctx__init (& t ))
972
+ return ;
973
+
974
+ d = btf_dump__new (t .btf , btf_dump_snprintf , str , NULL );
975
+ if (!ASSERT_OK_PTR (d , "could not create BTF dump" ))
976
+ return ;
977
+
978
+ /* Generate BTF for a four-element char array. */
979
+ char_id = btf__add_int (t .btf , "char" , 1 , BTF_INT_CHAR );
980
+ ASSERT_EQ (char_id , 1 , "char_id" );
981
+ int_id = btf__add_int (t .btf , "int" , 4 , BTF_INT_SIGNED );
982
+ ASSERT_EQ (int_id , 2 , "int_id" );
983
+ array_id = btf__add_array (t .btf , int_id , char_id , 4 );
984
+ ASSERT_EQ (array_id , 3 , "array_id" );
985
+
986
+ ctx .btf = t .btf ;
987
+ ctx .d = d ;
988
+ ctx .str = str ;
989
+ ctx .opts = & opts ;
990
+ ctx .array_id = array_id ;
991
+
992
+ btf_dump_strings (& ctx );
993
+
994
+ btf_dump__free (d );
995
+ test_ctx__free (& t );
996
+ }
997
+
882
998
static void test_btf_datasec (struct btf * btf , struct btf_dump * d , char * str ,
883
999
const char * name , const char * expected_val ,
884
1000
void * data , size_t data_sz )
@@ -970,6 +1086,8 @@ void test_btf_dump() {
970
1086
test_btf_dump_struct_data (btf , d , str );
971
1087
if (test__start_subtest ("btf_dump: var_data" ))
972
1088
test_btf_dump_var_data (btf , d , str );
1089
+ if (test__start_subtest ("btf_dump: string_data" ))
1090
+ test_btf_dump_string_data ();
973
1091
btf_dump__free (d );
974
1092
btf__free (btf );
975
1093
0 commit comments