@@ -156,13 +156,23 @@ struct filter {
156
156
bool abs ;
157
157
};
158
158
159
- struct var_preset {
160
- char * name ;
159
+ struct rvalue {
161
160
enum { INTEGRAL , ENUMERATOR } type ;
162
161
union {
163
162
long long ivalue ;
164
163
char * svalue ;
165
164
};
165
+ };
166
+
167
+ struct field_access {
168
+ char * name ;
169
+ };
170
+
171
+ struct var_preset {
172
+ struct field_access * atoms ;
173
+ int atom_count ;
174
+ char * full_name ;
175
+ struct rvalue value ;
166
176
bool applied ;
167
177
};
168
178
@@ -1498,6 +1508,35 @@ static int reset_stat_cgroup(void)
1498
1508
return 0 ;
1499
1509
}
1500
1510
1511
+ static int parse_rvalue (const char * val , struct rvalue * rvalue )
1512
+ {
1513
+ long long value ;
1514
+ char * val_end ;
1515
+
1516
+ if (val [0 ] == '-' || isdigit (val [0 ])) {
1517
+ /* must be a number */
1518
+ errno = 0 ;
1519
+ value = strtoll (val , & val_end , 0 );
1520
+ if (errno == ERANGE ) {
1521
+ errno = 0 ;
1522
+ value = strtoull (val , & val_end , 0 );
1523
+ }
1524
+ if (errno || * val_end != '\0' ) {
1525
+ fprintf (stderr , "Failed to parse value '%s'\n" , val );
1526
+ return - EINVAL ;
1527
+ }
1528
+ rvalue -> ivalue = value ;
1529
+ rvalue -> type = INTEGRAL ;
1530
+ } else {
1531
+ /* if not a number, consider it enum value */
1532
+ rvalue -> svalue = strdup (val );
1533
+ if (!rvalue -> svalue )
1534
+ return - ENOMEM ;
1535
+ rvalue -> type = ENUMERATOR ;
1536
+ }
1537
+ return 0 ;
1538
+ }
1539
+
1501
1540
static int process_prog (const char * filename , struct bpf_object * obj , struct bpf_program * prog )
1502
1541
{
1503
1542
const char * base_filename = basename (strdupa (filename ));
@@ -1593,13 +1632,36 @@ static int process_prog(const char *filename, struct bpf_object *obj, struct bpf
1593
1632
return 0 ;
1594
1633
};
1595
1634
1635
+ static int parse_var_atoms (const char * full_var , struct var_preset * preset )
1636
+ {
1637
+ char expr [256 ], * name , * saveptr ;
1638
+
1639
+ snprintf (expr , sizeof (expr ), "%s" , full_var );
1640
+ preset -> atom_count = 0 ;
1641
+ while ((name = strtok_r (preset -> atom_count ? NULL : expr , "." , & saveptr ))) {
1642
+ struct field_access * tmp ;
1643
+ int i = preset -> atom_count ;
1644
+
1645
+ tmp = reallocarray (preset -> atoms , i + 1 , sizeof (* preset -> atoms ));
1646
+ if (!tmp )
1647
+ return - ENOMEM ;
1648
+
1649
+ preset -> atoms = tmp ;
1650
+ preset -> atom_count ++ ;
1651
+
1652
+ preset -> atoms [i ].name = strdup (name );
1653
+ if (!preset -> atoms [i ].name )
1654
+ return - ENOMEM ;
1655
+ }
1656
+ return 0 ;
1657
+ }
1658
+
1596
1659
static int append_var_preset (struct var_preset * * presets , int * cnt , const char * expr )
1597
1660
{
1598
1661
void * tmp ;
1599
1662
struct var_preset * cur ;
1600
- char var [256 ], val [256 ], * val_end ;
1601
- long long value ;
1602
- int n ;
1663
+ char var [256 ], val [256 ];
1664
+ int n , err ;
1603
1665
1604
1666
tmp = realloc (* presets , (* cnt + 1 ) * sizeof (* * presets ));
1605
1667
if (!tmp )
@@ -1614,32 +1676,18 @@ static int append_var_preset(struct var_preset **presets, int *cnt, const char *
1614
1676
return - EINVAL ;
1615
1677
}
1616
1678
1617
- if (val [0 ] == '-' || isdigit (val [0 ])) {
1618
- /* must be a number */
1619
- errno = 0 ;
1620
- value = strtoll (val , & val_end , 0 );
1621
- if (errno == ERANGE ) {
1622
- errno = 0 ;
1623
- value = strtoull (val , & val_end , 0 );
1624
- }
1625
- if (errno || * val_end != '\0' ) {
1626
- fprintf (stderr , "Failed to parse value '%s'\n" , val );
1627
- return - EINVAL ;
1628
- }
1629
- cur -> ivalue = value ;
1630
- cur -> type = INTEGRAL ;
1631
- } else {
1632
- /* if not a number, consider it enum value */
1633
- cur -> svalue = strdup (val );
1634
- if (!cur -> svalue )
1635
- return - ENOMEM ;
1636
- cur -> type = ENUMERATOR ;
1637
- }
1679
+ err = parse_rvalue (val , & cur -> value );
1680
+ if (err )
1681
+ return err ;
1638
1682
1639
- cur -> name = strdup (var );
1640
- if (!cur -> name )
1683
+ cur -> full_name = strdup (var );
1684
+ if (!cur -> full_name )
1641
1685
return - ENOMEM ;
1642
1686
1687
+ err = parse_var_atoms (var , cur );
1688
+ if (err )
1689
+ return err ;
1690
+
1643
1691
return 0 ;
1644
1692
}
1645
1693
@@ -1766,22 +1814,20 @@ const int btf_find_member(const struct btf *btf,
1766
1814
}
1767
1815
1768
1816
static int adjust_var_secinfo (struct btf * btf , const struct btf_type * t ,
1769
- struct btf_var_secinfo * sinfo , const char * var )
1817
+ struct btf_var_secinfo * sinfo , struct var_preset * preset )
1770
1818
{
1771
- char expr [256 ], * saveptr ;
1772
1819
const struct btf_type * base_type , * member_type ;
1773
- int err , member_tid ;
1774
- char * name ;
1820
+ int err , member_tid , i ;
1775
1821
__u32 member_offset = 0 ;
1776
1822
1777
1823
base_type = btf__type_by_id (btf , btf__resolve_type (btf , t -> type ));
1778
- snprintf (expr , sizeof (expr ), "%s" , var );
1779
- strtok_r (expr , "." , & saveptr );
1780
1824
1781
- while ((name = strtok_r (NULL , "." , & saveptr ))) {
1782
- err = btf_find_member (btf , base_type , 0 , name , & member_tid , & member_offset );
1825
+ for (i = 1 ; i < preset -> atom_count ; ++ i ) {
1826
+ err = btf_find_member (btf , base_type , 0 , preset -> atoms [i ].name ,
1827
+ & member_tid , & member_offset );
1783
1828
if (err ) {
1784
- fprintf (stderr , "Could not find member %s for variable %s\n" , name , var );
1829
+ fprintf (stderr , "Could not find member %s for variable %s\n" ,
1830
+ preset -> atoms [i ].name , preset -> atoms [i - 1 ].name );
1785
1831
return err ;
1786
1832
}
1787
1833
member_type = btf__type_by_id (btf , member_tid );
@@ -1799,7 +1845,7 @@ static int set_global_var(struct bpf_object *obj, struct btf *btf,
1799
1845
{
1800
1846
const struct btf_type * base_type ;
1801
1847
void * ptr ;
1802
- long long value = preset -> ivalue ;
1848
+ long long value = preset -> value . ivalue ;
1803
1849
size_t size ;
1804
1850
1805
1851
base_type = btf__type_by_id (btf , btf__resolve_type (btf , sinfo -> type ));
@@ -1813,17 +1859,18 @@ static int set_global_var(struct bpf_object *obj, struct btf *btf,
1813
1859
return - EINVAL ;
1814
1860
}
1815
1861
1816
- if (preset -> type == ENUMERATOR ) {
1862
+ if (preset -> value . type == ENUMERATOR ) {
1817
1863
if (btf_is_any_enum (base_type )) {
1818
- if (enum_value_from_name (btf , base_type , preset -> svalue , & value )) {
1864
+ if (enum_value_from_name (btf , base_type , preset -> value . svalue , & value )) {
1819
1865
fprintf (stderr ,
1820
1866
"Failed to find integer value for enum element %s\n" ,
1821
- preset -> svalue );
1867
+ preset -> value . svalue );
1822
1868
return - EINVAL ;
1823
1869
}
1824
1870
} else {
1825
1871
fprintf (stderr , "Value %s is not supported for type %s\n" ,
1826
- preset -> svalue , btf__name_by_offset (btf , base_type -> name_off ));
1872
+ preset -> value .svalue ,
1873
+ btf__name_by_offset (btf , base_type -> name_off ));
1827
1874
return - EINVAL ;
1828
1875
}
1829
1876
}
@@ -1890,20 +1937,16 @@ static int set_global_vars(struct bpf_object *obj, struct var_preset *presets, i
1890
1937
for (j = 0 ; j < n ; ++ j , ++ sinfo ) {
1891
1938
const struct btf_type * var_type = btf__type_by_id (btf , sinfo -> type );
1892
1939
const char * var_name ;
1893
- int var_len ;
1894
1940
1895
1941
if (!btf_is_var (var_type ))
1896
1942
continue ;
1897
1943
1898
1944
var_name = btf__name_by_offset (btf , var_type -> name_off );
1899
- var_len = strlen (var_name );
1900
1945
1901
1946
for (k = 0 ; k < npresets ; ++ k ) {
1902
1947
struct btf_var_secinfo tmp_sinfo ;
1903
1948
1904
- if (strncmp (var_name , presets [k ].name , var_len ) != 0 ||
1905
- (presets [k ].name [var_len ] != '\0' &&
1906
- presets [k ].name [var_len ] != '.' ))
1949
+ if (strcmp (var_name , presets [k ].atoms [0 ].name ) != 0 )
1907
1950
continue ;
1908
1951
1909
1952
if (presets [k ].applied ) {
@@ -1913,7 +1956,7 @@ static int set_global_vars(struct bpf_object *obj, struct var_preset *presets, i
1913
1956
}
1914
1957
tmp_sinfo = * sinfo ;
1915
1958
err = adjust_var_secinfo (btf , var_type ,
1916
- & tmp_sinfo , presets [ k ]. name );
1959
+ & tmp_sinfo , presets + k );
1917
1960
if (err )
1918
1961
return err ;
1919
1962
@@ -1928,7 +1971,7 @@ static int set_global_vars(struct bpf_object *obj, struct var_preset *presets, i
1928
1971
for (i = 0 ; i < npresets ; ++ i ) {
1929
1972
if (!presets [i ].applied ) {
1930
1973
fprintf (stderr , "Global variable preset %s has not been applied\n" ,
1931
- presets [i ].name );
1974
+ presets [i ].full_name );
1932
1975
}
1933
1976
presets [i ].applied = false;
1934
1977
}
@@ -3062,7 +3105,7 @@ static int handle_replay_mode(void)
3062
3105
3063
3106
int main (int argc , char * * argv )
3064
3107
{
3065
- int err = 0 , i ;
3108
+ int err = 0 , i , j ;
3066
3109
3067
3110
if (argp_parse (& argp , argc , argv , 0 , NULL , NULL ))
3068
3111
return 1 ;
@@ -3121,9 +3164,12 @@ int main(int argc, char **argv)
3121
3164
}
3122
3165
free (env .deny_filters );
3123
3166
for (i = 0 ; i < env .npresets ; ++ i ) {
3124
- free (env .presets [i ].name );
3125
- if (env .presets [i ].type == ENUMERATOR )
3126
- free (env .presets [i ].svalue );
3167
+ free (env .presets [i ].full_name );
3168
+ for (j = 0 ; j < env .presets [i ].atom_count ; ++ j )
3169
+ free (env .presets [i ].atoms [j ].name );
3170
+ free (env .presets [i ].atoms );
3171
+ if (env .presets [i ].value .type == ENUMERATOR )
3172
+ free (env .presets [i ].value .svalue );
3127
3173
}
3128
3174
free (env .presets );
3129
3175
return - err ;
0 commit comments