From 85bd2fddd68e757da8e1af98f857f61a3c9ce647 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Mon, 26 Feb 2007 15:33:52 +0100 Subject: kbuild: fix section mismatch check for vmlinux vmlinux does not contain relocation entries which is used by the section mismatch checks. Reported by: Atsushi Nemoto Use the individual objects as inputs to overcome this limitation. In modpost check the .o files and skip non-ELF files. Signed-off-by: Sam Ravnborg --- scripts/mod/modpost.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) (limited to 'scripts/mod') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 65bdfdb5687..1912c752e42 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -333,10 +333,10 @@ void release_file(void *file, unsigned long size) munmap(file, size); } -static void parse_elf(struct elf_info *info, const char *filename) +static int parse_elf(struct elf_info *info, const char *filename) { unsigned int i; - Elf_Ehdr *hdr = info->hdr; + Elf_Ehdr *hdr; Elf_Shdr *sechdrs; Elf_Sym *sym; @@ -346,9 +346,18 @@ static void parse_elf(struct elf_info *info, const char *filename) exit(1); } info->hdr = hdr; - if (info->size < sizeof(*hdr)) - goto truncated; - + if (info->size < sizeof(*hdr)) { + /* file too small, assume this is an empty .o file */ + return 0; + } + /* Is this a valid ELF file? */ + if ((hdr->e_ident[EI_MAG0] != ELFMAG0) || + (hdr->e_ident[EI_MAG1] != ELFMAG1) || + (hdr->e_ident[EI_MAG2] != ELFMAG2) || + (hdr->e_ident[EI_MAG3] != ELFMAG3)) { + /* Not an ELF file - silently ignore it */ + return 0; + } /* Fix endianness in ELF header */ hdr->e_shoff = TO_NATIVE(hdr->e_shoff); hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx); @@ -371,8 +380,10 @@ static void parse_elf(struct elf_info *info, const char *filename) = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; const char *secname; - if (sechdrs[i].sh_offset > info->size) - goto truncated; + if (sechdrs[i].sh_offset > info->size) { + fatal("%s is truncated. sechdrs[i].sh_offset=%u > sizeof(*hrd)=%ul\n", filename, (unsigned int)sechdrs[i].sh_offset, sizeof(*hdr)); + return 0; + } secname = secstrings + sechdrs[i].sh_name; if (strcmp(secname, ".modinfo") == 0) { info->modinfo = (void *)hdr + sechdrs[i].sh_offset; @@ -407,10 +418,7 @@ static void parse_elf(struct elf_info *info, const char *filename) sym->st_value = TO_NATIVE(sym->st_value); sym->st_size = TO_NATIVE(sym->st_size); } - return; - - truncated: - fatal("%s is truncated.\n", filename); + return 1; } static void parse_elf_finish(struct elf_info *info) @@ -1089,7 +1097,8 @@ static void read_symbols(char *modname) struct elf_info info = { }; Elf_Sym *sym; - parse_elf(&info, modname); + if (!parse_elf(&info, modname)) + return; mod = new_module(modname); -- cgit v1.2.3 From aae5f662a32c35b1a962627535acb588d48ff5f9 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Mon, 26 Feb 2007 16:45:41 +0100 Subject: kbuild: whitelist section mismatch in init/main.c In init/main.c we have a reference from rest_init() to .init.text which is intentional. Rename the function 'init' to 'kernel_init' to make it a kernel wide unique symbol and whitelist the reference. Signed-off-by: Sam Ravnborg --- init/main.c | 6 +++--- scripts/mod/modpost.c | 15 ++++++++++++++- 2 files changed, 17 insertions(+), 4 deletions(-) (limited to 'scripts/mod') diff --git a/init/main.c b/init/main.c index a92989e7836..7a92b4ca3aa 100644 --- a/init/main.c +++ b/init/main.c @@ -82,7 +82,7 @@ #warning gcc-4.1.0 is known to miscompile the kernel. A different compiler version is recommended. #endif -static int init(void *); +static int kernel_init(void *); extern void init_IRQ(void); extern void fork_init(unsigned long); @@ -435,7 +435,7 @@ static void __init setup_command_line(char *command_line) static void noinline rest_init(void) __releases(kernel_lock) { - kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND); + kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND); numa_default_policy(); unlock_kernel(); @@ -772,7 +772,7 @@ static int noinline init_post(void) panic("No init found. Try passing init= option to kernel."); } -static int __init init(void * unused) +static int __init kernel_init(void * unused) { lock_kernel(); /* diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 1912c752e42..be0827f734c 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -589,7 +589,7 @@ static int strrcmp(const char *s, const char *sub) * the pattern is identified by: * tosec = .init.text | .exit.text | .init.data * fromsec = .data - * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one + * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one, *_console * * Pattern 3: * Some symbols belong to init section but still it is ok to reference @@ -599,6 +599,14 @@ static int strrcmp(const char *s, const char *sub) * For ex. symbols marking the init section boundaries. * This pattern is identified by * refsymname = __init_begin, _sinittext, _einittext + * Pattern 4: + * During the early init phase we have references from .init.text to + * .text we have an intended section mismatch - do not warn about it. + * See kernel_init() in init/main.c + * tosec = .init.text + * fromsec = .text + * atsym = kernel_init + * Some symbols belong to init section but still it is ok to reference **/ static int secref_whitelist(const char *modname, const char *tosec, const char *fromsec, const char *atsym, @@ -668,6 +676,11 @@ static int secref_whitelist(const char *modname, const char *tosec, if (strcmp(refsymname, *s) == 0) return 1; } + /* Check for pattern 4 */ + if ((strcmp(tosec, ".init.text") == 0) && + (strcmp(fromsec, ".text") == 0) && + (strcmp(refsymname, "kernel_init") == 0)) + return 1; return 0; } -- cgit v1.2.3 From 9bf8cb9b7908383752b1842eae78269f7e16d9fb Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Mon, 26 Feb 2007 17:49:06 +0100 Subject: kbuild: fix warnings from .pci_fixup section Now where we do not pass vmlinux to modpost we started to see section mismatch warnings from .pci_fixup. Refactored code a little to include these in the whitelist again. Signed-off-by: Sam Ravnborg --- scripts/mod/modpost.c | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) (limited to 'scripts/mod') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index be0827f734c..e1f2b31cf34 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -592,6 +592,14 @@ static int strrcmp(const char *s, const char *sub) * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one, *_console * * Pattern 3: + * Whitelist all references from .pci_fixup* section to .init.text + * This is part of the PCI init when built-in + * + * Pattern 4: + * Whitelist all refereces from .text.head to .init.data + * Whitelist all refereces from .text.head to .init.text + * + * Pattern 5: * Some symbols belong to init section but still it is ok to reference * these from non-init sections as these symbols don't have any memory * allocated for them and symbol address and value are same. So even @@ -599,7 +607,8 @@ static int strrcmp(const char *s, const char *sub) * For ex. symbols marking the init section boundaries. * This pattern is identified by * refsymname = __init_begin, _sinittext, _einittext - * Pattern 4: + * + * Pattern 6: * During the early init phase we have references from .init.text to * .text we have an intended section mismatch - do not warn about it. * See kernel_init() in init/main.c @@ -657,26 +666,23 @@ static int secref_whitelist(const char *modname, const char *tosec, if (f1 && f2) return 1; - /* Whitelist all references from .pci_fixup section if vmlinux - * Whitelist all refereces from .text.head to .init.data if vmlinux - * Whitelist all refereces from .text.head to .init.text if vmlinux - */ - if (is_vmlinux(modname)) { - if ((strcmp(fromsec, ".pci_fixup") == 0) && - (strcmp(tosec, ".init.text") == 0)) - return 1; - - if ((strcmp(fromsec, ".text.head") == 0) && - ((strcmp(tosec, ".init.data") == 0) || - (strcmp(tosec, ".init.text") == 0))) - return 1; + /* Check for pattern 3 */ + if ((strncmp(fromsec, ".pci_fixup", strlen(".pci_fixup")) == 0) && + (strcmp(tosec, ".init.text") == 0)) + return 1; - /* Check for pattern 3 */ - for (s = pat3refsym; *s; s++) - if (strcmp(refsymname, *s) == 0) - return 1; - } /* Check for pattern 4 */ + if ((strcmp(fromsec, ".text.head") == 0) && + ((strcmp(tosec, ".init.data") == 0) || + (strcmp(tosec, ".init.text") == 0))) + return 1; + + /* Check for pattern 5 */ + for (s = pat3refsym; *s; s++) + if (strcmp(refsymname, *s) == 0) + return 1; + + /* Check for pattern 6 */ if ((strcmp(tosec, ".init.text") == 0) && (strcmp(fromsec, ".text") == 0) && (strcmp(refsymname, "kernel_init") == 0)) -- cgit v1.2.3 From a61b2dfd1823506dbf1f9b046e0b09237ec1b985 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Mon, 26 Feb 2007 19:46:52 +0100 Subject: kbuild: fix segmentation fault in modpost If modpost was called manually with filenames without '/' then modpost would segfault. Signed-off-by: Sam Ravnborg --- scripts/mod/modpost.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'scripts/mod') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index e1f2b31cf34..281abb77e03 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1345,6 +1345,7 @@ static void add_depends(struct buffer *b, struct module *mod, buf_printf(b, "__attribute__((section(\".modinfo\"))) =\n"); buf_printf(b, "\"depends="); for (s = mod->unres; s; s = s->next) { + const char *p; if (!s->module) continue; @@ -1352,8 +1353,11 @@ static void add_depends(struct buffer *b, struct module *mod, continue; s->module->seen = 1; - buf_printf(b, "%s%s", first ? "" : ",", - strrchr(s->module->name, '/') + 1); + if ((p = strrchr(s->module->name, '/')) != NULL) + p++; + else + p = s->module->name; + buf_printf(b, "%s%s", first ? "" : ",", p); first = 0; } buf_printf(b, "\";\n"); -- cgit v1.2.3 From 5a4910fbbeef14cc91daa41086449a1a4acebc96 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Tue, 27 Feb 2007 09:14:58 +0100 Subject: kbuild: whitelist logo references from .text to .init.data drivers/video/logo has references from .text to .init.data but function is only used during early init. So reference is OK and we do not want to warn about them => whitelist the reference. Signed-off-by: Sam Ravnborg --- scripts/mod/modpost.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'scripts/mod') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 281abb77e03..5f2ecd51bde 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -616,6 +616,15 @@ static int strrcmp(const char *s, const char *sub) * fromsec = .text * atsym = kernel_init * Some symbols belong to init section but still it is ok to reference + * + * Pattern 7: + * Logos used in drivers/video/logo reside in __initdata but the + * funtion that references them are EXPORT_SYMBOL() so cannot be + * marker __init. So we whitelist them here. + * The pattern is: + * tosec = .init.data + * fromsec = .text* + * refsymname = logo_ **/ static int secref_whitelist(const char *modname, const char *tosec, const char *fromsec, const char *atsym, @@ -687,6 +696,12 @@ static int secref_whitelist(const char *modname, const char *tosec, (strcmp(fromsec, ".text") == 0) && (strcmp(refsymname, "kernel_init") == 0)) return 1; + + /* Check for pattern 7 */ + if ((strcmp(tosec, ".init.data") == 0) && + (strncmp(fromsec, ".text", strlen(".text")) == 0) && + (strncmp(refsymname, "logo_", strlen("logo_")) == 0)) + return 1; return 0; } -- cgit v1.2.3 From dc24f0e708c8a6a27b5b967a2599c04973054398 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Fri, 9 Mar 2007 19:59:06 +0100 Subject: kbuild: remove dependency on input.h from file2alias Almost all definitions used by file2alias was already present in mod_devicetable.h. Added the last definition and killed the input.h usage. The errornous include was pointed out by: Jan Engelhardt Signed-off-by: Sam Ravnborg Cc: Jan Engelhardt Cc: Deepak Saxena --- include/linux/input.h | 4 ++++ include/linux/mod_devicetable.h | 1 + scripts/mod/file2alias.c | 21 +++++++++++---------- 3 files changed, 16 insertions(+), 10 deletions(-) (limited to 'scripts/mod') diff --git a/include/linux/input.h b/include/linux/input.h index bde65c8a351..13d510c3a5a 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -1010,6 +1010,10 @@ struct input_dev { #error "EV_MAX and INPUT_DEVICE_ID_EV_MAX do not match" #endif +#if KEY_MIN_INTERESTING != INPUT_DEVICE_ID_KEY_MIN_INTERESTING +#error "KEY_MIN_INTERESTING and INPUT_DEVICE_ID_KEY_MIN_INTERESTING do not match" +#endif + #if KEY_MAX != INPUT_DEVICE_ID_KEY_MAX #error "KEY_MAX and INPUT_DEVICE_ID_KEY_MAX do not match" #endif diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index e96b2dee10b..af04a555b52 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -262,6 +262,7 @@ struct i2c_device_id { /* Input */ #define INPUT_DEVICE_ID_EV_MAX 0x1f +#define INPUT_DEVICE_ID_KEY_MIN_INTERESTING 0x71 #define INPUT_DEVICE_ID_KEY_MAX 0x1ff #define INPUT_DEVICE_ID_REL_MAX 0x0f #define INPUT_DEVICE_ID_ABS_MAX 0x3f diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index b2f73ffb40b..ed1244dd58d 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -37,7 +37,6 @@ typedef unsigned char __u8; * even potentially has different endianness and word sizes, since * we handle those differences explicitly below */ #include "../../include/linux/mod_devicetable.h" -#include "../../include/linux/input.h" #define ADD(str, sep, cond, field) \ do { \ @@ -416,31 +415,33 @@ static int do_input_entry(const char *filename, struct input_device_id *id, sprintf(alias + strlen(alias), "-e*"); if (id->flags & INPUT_DEVICE_ID_MATCH_EVBIT) - do_input(alias, id->evbit, 0, EV_MAX); + do_input(alias, id->evbit, 0, INPUT_DEVICE_ID_EV_MAX); sprintf(alias + strlen(alias), "k*"); if (id->flags & INPUT_DEVICE_ID_MATCH_KEYBIT) - do_input(alias, id->keybit, KEY_MIN_INTERESTING, KEY_MAX); + do_input(alias, id->keybit, + INPUT_DEVICE_ID_KEY_MIN_INTERESTING, + INPUT_DEVICE_ID_KEY_MAX); sprintf(alias + strlen(alias), "r*"); if (id->flags & INPUT_DEVICE_ID_MATCH_RELBIT) - do_input(alias, id->relbit, 0, REL_MAX); + do_input(alias, id->relbit, 0, INPUT_DEVICE_ID_REL_MAX); sprintf(alias + strlen(alias), "a*"); if (id->flags & INPUT_DEVICE_ID_MATCH_ABSBIT) - do_input(alias, id->absbit, 0, ABS_MAX); + do_input(alias, id->absbit, 0, INPUT_DEVICE_ID_ABS_MAX); sprintf(alias + strlen(alias), "m*"); if (id->flags & INPUT_DEVICE_ID_MATCH_MSCIT) - do_input(alias, id->mscbit, 0, MSC_MAX); + do_input(alias, id->mscbit, 0, INPUT_DEVICE_ID_MSC_MAX); sprintf(alias + strlen(alias), "l*"); if (id->flags & INPUT_DEVICE_ID_MATCH_LEDBIT) - do_input(alias, id->ledbit, 0, LED_MAX); + do_input(alias, id->ledbit, 0, INPUT_DEVICE_ID_LED_MAX); sprintf(alias + strlen(alias), "s*"); if (id->flags & INPUT_DEVICE_ID_MATCH_SNDBIT) - do_input(alias, id->sndbit, 0, SND_MAX); + do_input(alias, id->sndbit, 0, INPUT_DEVICE_ID_SND_MAX); sprintf(alias + strlen(alias), "f*"); if (id->flags & INPUT_DEVICE_ID_MATCH_FFBIT) - do_input(alias, id->ffbit, 0, FF_MAX); + do_input(alias, id->ffbit, 0, INPUT_DEVICE_ID_FF_MAX); sprintf(alias + strlen(alias), "w*"); if (id->flags & INPUT_DEVICE_ID_MATCH_SWBIT) - do_input(alias, id->swbit, 0, SW_MAX); + do_input(alias, id->swbit, 0, INPUT_DEVICE_ID_SW_MAX); return 1; } -- cgit v1.2.3 From 2a11665945d510e1a4df8dc44dc3668b01945ade Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Sat, 7 Oct 2006 05:35:32 -0600 Subject: kbuild: distinguish between errors and warnings in modpost Some of modpost's warnings are fatal, and some are not. Adopt the compiler distinction between errors and warnings by calling merror() for fatal diagnostics and warn() for non-fatal ones. merror() was used as replacemtn for error() to avoid clash with glibc Signed-off-by: Matthew Wilcox Signed-off-by: Sam Ravnborg --- scripts/mod/modpost.c | 22 +++++++++++++++++++--- scripts/mod/modpost.h | 1 + 2 files changed, 20 insertions(+), 3 deletions(-) (limited to 'scripts/mod') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 5f2ecd51bde..b10b69b56a3 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -55,6 +55,17 @@ void warn(const char *fmt, ...) va_end(arglist); } +void merror(const char *fmt, ...) +{ + va_list arglist; + + fprintf(stderr, "ERROR: "); + + va_start(arglist, fmt); + vfprintf(stderr, fmt, arglist); + va_end(arglist); +} + static int is_vmlinux(const char *modname) { const char *myname; @@ -1307,9 +1318,14 @@ static int add_versions(struct buffer *b, struct module *mod) exp = find_symbol(s->name); if (!exp || exp->module == mod) { if (have_vmlinux && !s->weak) { - warn("\"%s\" [%s.ko] undefined!\n", - s->name, mod->name); - err = warn_unresolved ? 0 : 1; + if (warn_unresolved) { + warn("\"%s\" [%s.ko] undefined!\n", + s->name, mod->name); + } else { + merror("\"%s\" [%s.ko] undefined!\n", + s->name, mod->name); + err = 1; + } } continue; } diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index d398c61e55e..0858caa9c03 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -145,3 +145,4 @@ void release_file(void *file, unsigned long size); void fatal(const char *fmt, ...); void warn(const char *fmt, ...); +void merror(const char *fmt, ...); -- cgit v1.2.3 From 4be40e22233cfe6254bbf039ec09a5d7bff2ad14 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Tue, 20 Mar 2007 21:30:23 +0100 Subject: kbuild: do not emit src version warning for non-modules modpost is now called with .o files that are not modules. So do not warn if there is no corresponding .mod file listing .o files (in .tmp_versions/). Signed-off-by: Sam Ravnborg --- scripts/mod/sumversion.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'scripts/mod') diff --git a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c index 8a2875689e4..6873d5af80d 100644 --- a/scripts/mod/sumversion.c +++ b/scripts/mod/sumversion.c @@ -397,10 +397,9 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen) (int) strlen(basename) - 2, basename); file = grab_file(filelist, &len); - if (!file) { - warn("could not find versions for %s\n", filelist); + if (!file) + /* not a module or .mod file missing - ignore */ return; - } sources = strchr(file, '\n'); if (!sources) { -- cgit v1.2.3 From 66bd32e443203735b00f22bede637ec98f3070ca Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 29 Apr 2007 20:40:53 +0200 Subject: kbuild: remove stale comment in modpost.c Signed-off-by: Sam Ravnborg --- scripts/mod/modpost.c | 1 - 1 file changed, 1 deletion(-) (limited to 'scripts/mod') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index b10b69b56a3..b81157cf452 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -626,7 +626,6 @@ static int strrcmp(const char *s, const char *sub) * tosec = .init.text * fromsec = .text * atsym = kernel_init - * Some symbols belong to init section but still it is ok to reference * * Pattern 7: * Logos used in drivers/video/logo reside in __initdata but the -- cgit v1.2.3 From b4d5171ac7d9806b1ea61903ff954cd9620135bf Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sun, 29 Apr 2007 20:53:01 +0200 Subject: kbuild: ignore section mismatch warning for references from .paravirtprobe to .init.text Added on request from: Rusty Russell Signed-off-by: Sam Ravnborg Cc: Rusty Russell --- scripts/mod/modpost.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'scripts/mod') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index b81157cf452..628f393ecaa 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -635,6 +635,13 @@ static int strrcmp(const char *s, const char *sub) * tosec = .init.data * fromsec = .text* * refsymname = logo_ + * + * Pattern 8: + * Symbols contained in .paravirtprobe may safely reference .init.text. + * The pattern is: + * tosec = .init.text + * fromsec = .paravirtprobe + * **/ static int secref_whitelist(const char *modname, const char *tosec, const char *fromsec, const char *atsym, @@ -712,6 +719,12 @@ static int secref_whitelist(const char *modname, const char *tosec, (strncmp(fromsec, ".text", strlen(".text")) == 0) && (strncmp(refsymname, "logo_", strlen("logo_")) == 0)) return 1; + + /* Check for pattern 8 */ + if ((strcmp(tosec, ".init.text") == 0) && + (strcmp(fromsec, ".paravirtprobe") == 0)) + return 1; + return 0; } -- cgit v1.2.3