Skip to content

Commit 2b1bd50

Browse files
committed
modpost: improve error messages in device_id_check()
The first error message in device_id_check() is obscure and can be misleading because the cause of the error is unlikely to be found in the struct definition in mod_devicetable.h. This type of error occurs when an array is passed to an incorrect type of MODULE_DEVICE_TABLE(). [Example 1] static const struct acpi_device_id foo_ids[] = { { "FOO" }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, foo_ids); Currently, modpost outputs a meaningless suggestion: ERROR: modpost: ...: sizeof(struct of_device_id)=200 is not a modulo of the size of section __mod_device_table__of__<identifier>=64. Fix definition of struct of_device_id in mod_devicetable.h The root cause here is that MODULE_DEVICE_TABLE(of, ...) is used instead of the correct MODULE_DEVICE_TABLE(acpi, ...). This commit provides a more intuitive error message: ERROR: modpost: ...: type mismatch between foo_ids[] and MODULE_DEVICE_TABLE(of, ...) The second error message, related to a missing terminator, is too verbose. [Example 2] static const struct acpi_device_id foo_ids[] = { { "FOO" }, }; MODULE_DEVICE_TABLE(acpi, foo_ids); The current error message is overly long, and does not pinpoint the incorrect array: ...: struct acpi_device_id is 32 bytes. The last of 1 is: 0x46 0x4f 0x4f 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 ERROR: modpost: ...: struct acpi_device_id is not terminated with a NULL entry! This commit changes it to a more concise error message, sufficient to identify the incorrect array: ERROR: modpost: ...: foo_ids[] is not terminated with a NULL entry Lastly, this commit squashes device_id_check() into do_table() and changes fatal() into error(), allowing modpost to continue processing other modules. Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
1 parent 054a9cd commit 2b1bd50

File tree

1 file changed

+18
-37
lines changed

1 file changed

+18
-37
lines changed

scripts/mod/file2alias.c

Lines changed: 18 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -176,40 +176,6 @@ static inline void add_guid(char *str, guid_t guid)
176176
guid.b[12], guid.b[13], guid.b[14], guid.b[15]);
177177
}
178178

179-
/**
180-
* Check that sizeof(device_id type) are consistent with size of section
181-
* in .o file. If in-consistent then userspace and kernel does not agree
182-
* on actual size which is a bug.
183-
* Also verify that the final entry in the table is all zeros.
184-
* Ignore both checks if build host differ from target host and size differs.
185-
**/
186-
static void device_id_check(const char *modname, const char *device_id,
187-
unsigned long size, unsigned long id_size,
188-
void *symval)
189-
{
190-
int i;
191-
192-
if (size % id_size || size < id_size) {
193-
fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo of the size of section __mod_device_table__%s__<identifier>=%lu.\n"
194-
"Fix definition of struct %s_device_id in mod_devicetable.h\n",
195-
modname, device_id, id_size, device_id, size, device_id);
196-
}
197-
/* Verify last one is a terminator */
198-
for (i = 0; i < id_size; i++ ) {
199-
if (*(uint8_t*)(symval+size-id_size+i)) {
200-
fprintf(stderr,
201-
"%s: struct %s_device_id is %lu bytes. The last of %lu is:\n",
202-
modname, device_id, id_size, size / id_size);
203-
for (i = 0; i < id_size; i++ )
204-
fprintf(stderr,"0x%02x ",
205-
*(uint8_t*)(symval+size-id_size+i) );
206-
fprintf(stderr,"\n");
207-
fatal("%s: struct %s_device_id is not terminated with a NULL entry!\n",
208-
modname, device_id);
209-
}
210-
}
211-
}
212-
213179
/* USB is special because the bcdDevice can be matched against a numeric range */
214180
/* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipNinN" */
215181
static void do_usb_entry(void *symval,
@@ -1420,15 +1386,29 @@ static bool sym_is(const char *name, unsigned namelen, const char *symbol)
14201386
return memcmp(name, symbol, namelen) == 0;
14211387
}
14221388

1423-
static void do_table(void *symval, unsigned long size,
1389+
static void do_table(const char *name, void *symval, unsigned long size,
14241390
unsigned long id_size,
14251391
const char *device_id,
14261392
void (*do_entry)(struct module *mod, void *symval),
14271393
struct module *mod)
14281394
{
14291395
unsigned int i;
14301396

1431-
device_id_check(mod->name, device_id, size, id_size, symval);
1397+
if (size % id_size || size < id_size) {
1398+
error("%s: type mismatch between %s[] and MODULE_DEVICE_TABLE(%s, ...)\n",
1399+
mod->name, name, device_id);
1400+
return;
1401+
}
1402+
1403+
/* Verify the last entry is a terminator */
1404+
for (i = size - id_size; i < size; i++) {
1405+
if (*(uint8_t *)(symval + i)) {
1406+
error("%s: %s[] is not terminated with a NULL entry\n",
1407+
mod->name, name);
1408+
return;
1409+
}
1410+
}
1411+
14321412
/* Leave last one: it's the terminator. */
14331413
size -= id_size;
14341414

@@ -1524,6 +1504,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
15241504
if (!name)
15251505
return;
15261506
typelen = name - type;
1507+
name += strlen("__");
15271508

15281509
/* Handle all-NULL symbols allocated into .bss */
15291510
if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) {
@@ -1537,7 +1518,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
15371518
const struct devtable *p = &devtable[i];
15381519

15391520
if (sym_is(type, typelen, p->device_id)) {
1540-
do_table(symval, sym->st_size, p->id_size,
1521+
do_table(name, symval, sym->st_size, p->id_size,
15411522
p->device_id, p->do_entry, mod);
15421523
break;
15431524
}

0 commit comments

Comments
 (0)