From mboxrd@z Thu Jan 1 00:00:00 1970 From: jim.cromie@gmail.com (Jim Cromie) Date: Mon, 9 Apr 2012 23:09:45 -0600 Subject: =?UTF-8?q?=5BPATCH=202/3=5D=20bug=2Eh=3A=20add=20test/demo=20module?= In-Reply-To: <1334034585-16651-1-git-send-email-jim.cromie@gmail.com> References: <1334034585-16651-1-git-send-email-jim.cromie@gmail.com> Message-ID: <1334034585-16651-3-git-send-email-jim.cromie@gmail.com> To: kernelnewbies@lists.kernelnewbies.org List-Id: kernelnewbies.lists.kernelnewbies.org add drivers/misc/build-asserts.c to test BUILD_BUG_DECL. BUILD_BUG_DECL works as intended, but __attribute((unused)) appears to be ineffective in the macro: cmp_ints() run at __init time is able to reference the storage w/o warnings (no section complaints, even though those functions are not explicitly marked as __init - I guess thats inferred..). cmp_ints() run from mod-param getter/setter callbacks pukes badly. I guess this is to be expected, since __initdata is dropped once boot is complete. But why no compile warnings ?? root at voyage:~# cat /sys/module/build_asserts/parameters/* build_asserts.cbint_get: got bufp:c65cd000='' kp:c8bb967c build_asserts.cbint_get: kp-name:cbint build_asserts.cbint_get: kp-arg:c8bb9113 build_asserts.cbint_get: kp-ops:c8bb973c build_asserts.cbint_get: kp-ops-set:c8bb9179 build_asserts.cbint_get: kp-ops-get:c8bb9000 build_asserts.cbint_get: cbint_get me:c8bb9000 BUG: unable to handle kernel paging request at c8bbb000 IP: [] cbint_get+0xd8/0x113 [build_asserts] *pde = 06c76067 *pte = 00000000 Oops: 0000 [#1] PREEMPT Modules linked in: build_asserts scx200_gpio scx200_hrt pc8736x_gpio nsc_gpio pc87360 hwmon_vid scx200_acb acx_mac80211(O) arc4 rtl8180 mac80211 eeprom_93cx6 scx200 cfg80211 ohci_hcd pata_sc1200 [last unloaded: build_asserts] Pid: 1364, comm: cat Tainted: G O 3.4.0-rc1-ske+ #24 EIP: 0060:[] EFLAGS: 00010282 CPU: 0 EIP is at cbint_get+0xd8/0x113 [build_asserts] EAX: 00000035 EBX: c65cd000 ECX: c7450000 EDX: 00000003 ESI: c8bb967c EDI: c65cd000 EBP: c7451efc ESP: c7451ee0 DS: 007b ES: 007b FS: 0000 GS: 00e0 SS: 0068 CR0: 8005003b CR2: c8bbb000 CR3: 066b7000 CR4: 00000000 DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000 DR6: ffff0ff0 DR7: 00000400 Process cat (pid: 1364, ti=c7450000 task=c6524f80 task.ti=c7450000) Stack: c8bb945e c8bb96bc c8bb9000 c65cd000 c8bb967c ffffffff c675c270 c7451f10 c012f536 c675c270 c8bb9790 c012f503 c7451f24 c012f35b c6507740 c60deb40 c043eb28 c7451f70 c02010d5 c6753680 00000000 c7451f44 c027fe90 c6753680 Call Trace: [] ? 0xc8bb8fff [] param_attr_show+0x33/0x57 [] ? __kernel_param_unlock+0x14/0x14 [] module_attr_show+0x21/0x26 [] sysfs_read_file+0x9e/0x154 [] ? security_file_permission+0x27/0x2b [] ? rw_verify_area+0xd0/0xf2 [] vfs_read+0x8d/0xd3 [] ? sysfs_open_file+0x1fa/0x1fa [] sys_read+0x42/0x63 [] syscall_call+0x7/0xb Code: 04 24 3a 94 bb c8 89 44 24 08 e8 89 7c 87 f7 c7 44 24 08 00 90 bb c8 c7 44 24 04 bc 96 bb c8 c7 04 24 5e 94 bb c8 e8 6d 7c 87 f7 00 b0 bb c8 c7 44 24 04 bc 96 bb c8 89 44 24 0c 89 44 24 08 EIP: [] cbint_get+0xd8/0x113 [build_asserts] SS:ESP 0068:c7451ee0 CR2: 00000000c8bbb000 ---[ end trace bfbcc6aee803d03b ]--- Signed-off-by: Jim Cromie --- drivers/misc/Makefile | 2 + drivers/misc/build-asserts.c | 239 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 241 insertions(+), 0 deletions(-) create mode 100644 drivers/misc/build-asserts.c diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 3e1d801..5aff6bb 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -49,3 +49,5 @@ obj-y += carma/ obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/ obj-$(CONFIG_MAX8997_MUIC) += max8997-muic.o + +obj-m += build-asserts.o diff --git a/drivers/misc/build-asserts.c b/drivers/misc/build-asserts.c new file mode 100644 index 0000000..4a051b5 --- /dev/null +++ b/drivers/misc/build-asserts.c @@ -0,0 +1,239 @@ + +#define pr_fmt(fmt) KBUILD_MODNAME ".%s: " fmt, __FUNCTION__ + +#include +#include +#include +#include +#include + +int a[] = {1,2,3,4}; +int b[] = {1,2,3,5}; +int c[] = {3,5}; +long d[] = {1,2}; + +const char *names[] = { "bart", "lisa", "homer", "marge" }; + +struct bridge { + int member_ids[4]; + char *names[4]; + char *snacks[3]; // hungry ? +} clubs[4]; + +BUILD_BUG_DECL(foo, ARRAY_SIZE(a) != ARRAY_SIZE(b)); +BUILD_BUG_DECL(buz, sizeof(a) != sizeof(b)); // good +// BUILD_BUG_DECL(a, sizeof(a) != sizeof(d)); // brittle +BUILD_BUG_DECL(b, ARRAY_SIZE(a) != ARRAY_SIZE(names)); // good, on different types + +// BUILD_BUG_DECL(d, ARRAY_SIZE(a) != ARRAY_SIZE(d)); // compile err, correct +// BUILD_BUG_DECL(bonk, sizeof(a) != sizeof(names)); // breaks, correct +// BUILD_BUG_DECL(ac, sizeof(a) != sizeof(c)); // err + + +BUILD_BUG_DECL(joe, ARRAY_SIZE(a) != ARRAY_SIZE(clubs)); +BUILD_BUG_DECL(bob, ARRAY_SIZE(a) != ARRAY_SIZE(clubs[0].member_ids)); +BUILD_BUG_DECL(mike, ARRAY_SIZE(a) != ARRAY_SIZE(clubs[0].names)); + +// BUILD_BUG_DECL(sue, ARRAY_SIZE(a) != ARRAY_SIZE(clubs[0].snacks)); +// cant use typeof like this +// BUILD_BUG_DECL(ike, typeof(clubs[0].snacks) != typeof(clubs[0].names)); + +union { + int a; + long b; + char c; + char *s; + int arr[4]; +} pba; + +// these cause warning at file scope, but ok inside fn. +// warning: variably modified ?field? at file scope [enabled by default] +// BUILD_BUG_DECL(x, (void*)&pba.a != (void*)&pba.b); +// BUILD_BUG_DECL(y, (void*)&pba.a != (void*)&pba.c); + +int cmp_ints(int sz, int *arg1, int *arg2) +{ + int i; + + // NG: compiler doesnt know the arrays passed. + // BUILD_BUG_DECL(y, ARRAY_SIZE(*arg1) != ARRAY_SIZE(*arg2)); + + pr_notice("all equal ?\n"); + for (i=0; i] cbint_get+0xd8/0x113 [build_asserts] +*pde = 06c76067 *pte = 00000000 +Oops: 0000 [#1] PREEMPT +Modules linked in: build_asserts scx200_gpio scx200_hrt pc8736x_gpio nsc_gpio pc87360 hwmon_vid scx200_acb acx_mac80211(O) arc4 rtl8180 mac80211 eeprom_93cx6 scx200 cfg80211 ohci_hcd pata_sc1200 [last unloaded: build_asserts] + +Pid: 1364, comm: cat Tainted: G O 3.4.0-rc1-ske+ #24 +EIP: 0060:[] EFLAGS: 00010282 CPU: 0 +EIP is at cbint_get+0xd8/0x113 [build_asserts] +EAX: 00000035 EBX: c65cd000 ECX: c7450000 EDX: 00000003 +ESI: c8bb967c EDI: c65cd000 EBP: c7451efc ESP: c7451ee0 + DS: 007b ES: 007b FS: 0000 GS: 00e0 SS: 0068 +CR0: 8005003b CR2: c8bbb000 CR3: 066b7000 CR4: 00000000 +DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000 +DR6: ffff0ff0 DR7: 00000400 +Process cat (pid: 1364, ti=c7450000 task=c6524f80 task.ti=c7450000) +Stack: + c8bb945e c8bb96bc c8bb9000 c65cd000 c8bb967c ffffffff c675c270 c7451f10 + c012f536 c675c270 c8bb9790 c012f503 c7451f24 c012f35b c6507740 c60deb40 + c043eb28 c7451f70 c02010d5 c6753680 00000000 c7451f44 c027fe90 c6753680 +Call Trace: + [] ? 0xc8bb8fff + [] param_attr_show+0x33/0x57 + [] ? __kernel_param_unlock+0x14/0x14 + [] module_attr_show+0x21/0x26 + [] sysfs_read_file+0x9e/0x154 + [] ? security_file_permission+0x27/0x2b + [] ? rw_verify_area+0xd0/0xf2 + [] vfs_read+0x8d/0xd3 + [] ? sysfs_open_file+0x1fa/0x1fa + [] sys_read+0x42/0x63 + [] syscall_call+0x7/0xb + + */ + +int decl_user(void) +{ + // BUILD_BUG_DECL(ac, sizeof(a) != sizeof(c)); // errors, properly + + // no complaints testing the union from here. + BUILD_BUG_DECL(x, (void*)&pba.a != (void*)&pba.c); + // fine for use inside a struct + BUILD_BUG_DECL(y, ARRAY_SIZE(clubs[1].names) + != ARRAY_SIZE(clubs[0].member_ids)); + + return 0; +} + +// not usable as a mod-param, boot-only I guess +// also, gives unused warning at compile ? +static int __init bar_setup(char *str) +{ + pr_notice("bar setup: %s\n", str); + decl_user(); + use_cmp_ints(); + return 1; +} +__setup("bar=", bar_setup); + +static int cbvar = 0; +static int cbint_set(const char *val, const struct kernel_param *kp) +{ + int i; + int err = param_set_int(val, kp); + + pr_notice("err: %d val:%s", err, val); + if (err) + return err; + + i = BUILD_BUG_DECL_mike[0].BUILD_BUG_DECL_mike[0]; + pr_notice("access mike? %d, %d\n", i, + BUILD_BUG_DECL_mike[0].BUILD_BUG_DECL_mike[0]); + + return 0; +} +static int cbint_get(char *buffer, const struct kernel_param *kp) +{ + int i; + + pr_notice("got bufp:%p='%s' kp:%p\n", buffer, buffer, kp); + pr_notice("kp-name:%s\n", kp->name); + pr_notice("kp-arg:%p\n", kp->arg); + pr_notice("kp-ops:%p\n", kp->ops); + pr_notice("kp-ops-set:%p\n", kp->ops->set); + pr_notice("kp-ops-get:%p\n", kp->ops->get); + pr_notice("cbint_get me:%p\n", &cbint_get); + + i = BUILD_BUG_DECL_mike[0].BUILD_BUG_DECL_mike[0]; + pr_notice("access mike? %d, %d\n", i, + BUILD_BUG_DECL_mike[0].BUILD_BUG_DECL_mike[0]); + + strcpy(buffer, "hello from cbint_get"); + return strlen(buffer); +} +static struct kernel_param_ops cbint_ops = { + .set = cbint_set, + .get = cbint_get, // need one, no default provided +}; +module_param_cb(cbint, &cbint_ops, "cbint-arg", 0644); + +static int fooint; +module_param_named(foo, fooint, int, 0644); + +void myexit(void) +{ + pr_notice("bye\n"); +} + +module_init(use_cmp_ints); +module_exit(myexit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("jim.cromie at gmail.com"); +MODULE_DESCRIPTION("test BUILD_BUG_DECL"); -- 1.7.8.1