From 6f03423f497e35451a8ba901bd1fafaddec7ca27 Mon Sep 17 00:00:00 2001 From: Paul Cacheux Date: Fri, 3 Nov 2023 16:09:36 +0100 Subject: [PATCH 1/2] program: support multiple int sizes for LINUX_HAS_SYSCALL_WRAPPER This follows what libbpf does for kconfig values in general. Signed-off-by: Paul Cacheux --- collection.go | 20 ++++++++++++++++---- testdata/kconfig-eb.elf | Bin 2032 -> 2056 bytes testdata/kconfig-el.elf | Bin 2032 -> 2056 bytes testdata/kconfig.c | 2 +- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/collection.go b/collection.go index ac7108e62..432eb3f61 100644 --- a/collection.go +++ b/collection.go @@ -626,17 +626,29 @@ func resolveKconfig(m *MapSpec) error { internal.NativeEndian.PutUint32(data[vsi.Offset:], kv.Kernel()) case "LINUX_HAS_SYSCALL_WRAPPER": - if integer, ok := v.Type.(*btf.Int); !ok || integer.Size != 4 { - return fmt.Errorf("variable %s must be a 32 bits integer, got %s", n, v.Type) + integer, ok := v.Type.(*btf.Int) + if !ok { + return fmt.Errorf("variable %s must be an integer, got %s", n, v.Type) } - var value uint32 = 1 + var value uint8 = 1 if err := haveSyscallWrapper(); errors.Is(err, ErrNotSupported) { value = 0 } else if err != nil { return fmt.Errorf("unable to derive a value for LINUX_HAS_SYSCALL_WRAPPER: %w", err) } - internal.NativeEndian.PutUint32(data[vsi.Offset:], value) + switch integer.Size { + case 1: + data[vsi.Offset] = value + case 2: + internal.NativeEndian.PutUint16(data[vsi.Offset:], uint16(value)) + case 4: + internal.NativeEndian.PutUint32(data[vsi.Offset:], uint32(value)) + case 8: + internal.NativeEndian.PutUint64(data[vsi.Offset:], uint64(value)) + default: + return fmt.Errorf("variable %s must be a 8, 16, 32, or 64 bits integer, got %s", n, v.Type) + } default: // Catch CONFIG_*. configs[n] = configInfo{ diff --git a/testdata/kconfig-eb.elf b/testdata/kconfig-eb.elf index 776c8485f2707e667ca9d2ee4e8bc1da268a9180..c1f1494f2724c6118f72f386fec5fa27c389cbb7 100644 GIT binary patch delta 234 zcmeys-ytwTkBOCIqJaZr;lx5E&MyoM3?Te&;+#1yj6enuFtRW(Z~*DUd|)mEH;`fi z;=BA18YIdEB7gv>lz|7#0_p?O&nD+EUSy4T%FoZ4yn#h}ayXM9Bg5o$rW#%gpsX|y zCowRXFirl*A~TtXd9&gJpa?S*11W|#K+KBZGqP-cz?{#>m^?XvbwA^V$pUQcjK3z& nU^8dDF!=(TJ!8XU0d_kk7KX_I?DmWalP3T<%p8+1uqyxnAATzn delta 195 zcmeAW_`p9wkBQ~OL<5J30Rj^nggKuuFff4di-~jQnD7A^K)?jW*ZCoAkQf(;00I^u z<_5DM><5!;7%xr^X40PAz*Nm>F!>MDZN&>fd1fdEDZK;4tVsMXn}0CpGctNl&S2fo zIAgK~TRY>E$s5?r8Fx&6!Di2xFY~qvmv#T>PeVF`$T>${% CF)G~v diff --git a/testdata/kconfig-el.elf b/testdata/kconfig-el.elf index 8cd4ebd29609d21cc986855559f7d55da598d6f3..f8eb619225c329332f51d82c84c0baba84c20017 100644 GIT binary patch delta 222 zcmeys-ytwTgNcK6qLv$D;lx6D&MyoM3?Te&;><;MjEq1Q2Ll7kVIU0zeB3~S35f4P zXnr8Yzy%_JfCY$oz$^v^kiKV=Ga0Y2#yjQb=S<$fB0V{rNsy6YaynBbqs8QhOxKkj zK-Dq>X%K#c#AgMvSr|9pV$Ne^OrGq?x}R~wWKOnr#$S^svY9hpn0%7Wp0QyvC%gUR e`K%n11K2HC6F}BaHe?l^ynr3(A?C@a*wp}-bSr@X delta 186 zcmeAW_`p9wgXsgyL@l?80Rj^n1UR2CFff4di-|KA>G3fESs;8JLh}PD1}+c*1S~+z z4Q4^u4<=VKUYQ)sq&>NTse;j9@=vDgN*AE=%s?81?;!D6f$T2~n?EtE$t&5+8Fx&6$Y#%&F Date: Tue, 7 Nov 2023 11:02:36 +0000 Subject: [PATCH 2/2] program: reuse kconfig package for LINUX_HAS_SYSCALL_WRAPPER Export a function from the kconfig package which allows writing an integer into a slice based on a btf.Int. Signed-off-by: Lorenz Bauer --- collection.go | 15 +++------------ internal/kconfig/kconfig.go | 17 +++++++++++++++-- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/collection.go b/collection.go index 432eb3f61..a5532220f 100644 --- a/collection.go +++ b/collection.go @@ -630,24 +630,15 @@ func resolveKconfig(m *MapSpec) error { if !ok { return fmt.Errorf("variable %s must be an integer, got %s", n, v.Type) } - var value uint8 = 1 + var value uint64 = 1 if err := haveSyscallWrapper(); errors.Is(err, ErrNotSupported) { value = 0 } else if err != nil { return fmt.Errorf("unable to derive a value for LINUX_HAS_SYSCALL_WRAPPER: %w", err) } - switch integer.Size { - case 1: - data[vsi.Offset] = value - case 2: - internal.NativeEndian.PutUint16(data[vsi.Offset:], uint16(value)) - case 4: - internal.NativeEndian.PutUint32(data[vsi.Offset:], uint32(value)) - case 8: - internal.NativeEndian.PutUint64(data[vsi.Offset:], uint64(value)) - default: - return fmt.Errorf("variable %s must be a 8, 16, 32, or 64 bits integer, got %s", n, v.Type) + if err := kconfig.PutInteger(data[vsi.Offset:], integer, value); err != nil { + return fmt.Errorf("set LINUX_HAS_SYSCALL_WRAPPER: %w", err) } default: // Catch CONFIG_*. diff --git a/internal/kconfig/kconfig.go b/internal/kconfig/kconfig.go index d95e7eb0e..fa5308578 100644 --- a/internal/kconfig/kconfig.go +++ b/internal/kconfig/kconfig.go @@ -250,7 +250,20 @@ func putValueNumber(data []byte, typ btf.Type, value string) error { return fmt.Errorf("cannot parse value: %w", err) } - switch size { + return PutInteger(data, integer, n) +} + +// PutInteger writes n into data. +// +// integer determines how much is written into data and what the valid values +// are. +func PutInteger(data []byte, integer *btf.Int, n uint64) error { + // This function should match set_kcfg_value_num in libbpf. + if integer.Encoding == btf.Bool && n > 1 { + return fmt.Errorf("invalid boolean value: %d", n) + } + + switch integer.Size { case 1: data[0] = byte(n) case 2: @@ -260,7 +273,7 @@ func putValueNumber(data []byte, typ btf.Type, value string) error { case 8: internal.NativeEndian.PutUint64(data, uint64(n)) default: - return fmt.Errorf("size (%d) is not valid, expected: 1, 2, 4 or 8", size) + return fmt.Errorf("size (%d) is not valid, expected: 1, 2, 4 or 8", integer.Size) } return nil