[PATCH] kbuild: fix modpost when used with O=

From: Sam Ravnborg (sam_at_ravnborg.org)
Date: 03/12/04

  • Next message: Rajesh Venkatasubramanian: "Re: anon_vma RFC2"
    Date:	Fri, 12 Mar 2004 22:02:32 +0100
    To: Andrew Morton <akpm@osdl.org>, Rusty Russell <rusty@rustcorp.com.au>
    
    

    modpost or to be more specific sumversion.c was not behaving
    correct when used with O= and MODULE_VERSION was used.
    Previously it failed to use local .h when calculation
    the md-sum in case of a O= build.

    The following patch introduces the following:
    - A generic get_next_line()
    - Check that the topmost part of the directory matches
    - Using strrch when checking for file with suffix .o
    - Use NOFAIL for allocations in sumversion
    - Avoid memory leak in new_module

    The generic get_next_line will pay off when Andreas
    implmentation of storing symbil addresses in a seperate
    file is introduced.

            Sam

    kbuild-fix-modpost.patch

    diff -Nru a/scripts/modpost.c b/scripts/modpost.c
    --- a/scripts/modpost.c Fri Mar 12 21:54:55 2004
    +++ b/scripts/modpost.c Fri Mar 12 21:54:55 2004
    @@ -11,6 +11,7 @@
      * Usage: modpost vmlinux module1.o module2.o ...
      */
     
    +#include <ctype.h>
     #include "modpost.h"
     
     /* Are we using CONFIG_MODVERSIONS? */
    @@ -44,8 +45,6 @@
             va_end(arglist);
     }
     
    -#define NOFAIL(ptr) do_nofail((ptr), __FILE__, __LINE__, #ptr)
    -
     void *do_nofail(void *ptr, const char *file, int line, const char *expr)
     {
             if (!ptr) {
    @@ -63,21 +62,19 @@
     new_module(char *modname)
     {
             struct module *mod;
    - char *p;
    - size_t len;
    + char *p, *s;
             
             mod = NOFAIL(malloc(sizeof(*mod)));
             memset(mod, 0, sizeof(*mod));
             p = NOFAIL(strdup(modname));
     
    - len = strlen(p);
    -
             /* strip trailing .o */
    - if (len > 2 && p[len-2] == '.' && p[len-1] == 'o')
    - p[len -2] = '\0';
    + if ((s = strrchr(p, '.')) != NULL)
    + if (strcmp(s, ".o") == 0)
    + *s = '\0';
     
             /* add to list */
    - mod->name = NOFAIL(strdup(p));
    + mod->name = p;
             mod->next = modules;
             modules = mod;
     
    @@ -207,6 +204,42 @@
             if (map == MAP_FAILED)
                     return NULL;
             return map;
    +}
    +
    +/*
    + Return a copy of the next line in a mmap'ed file.
    + spaces in the beginning of the line is trimmed away.
    + Return a pointer to a static buffer.
    +*/
    +char*
    +get_next_line(unsigned long *pos, void *file, unsigned long size)
    +{
    + static char line[4096];
    + int skip = 1;
    + size_t len = 0;
    + char *p = (char *)file + *pos;
    + char *s = line;
    +
    + for (; *pos < size ; (*pos)++)
    + {
    + if (skip && isspace(*p)) {
    + p++;
    + continue;
    + }
    + skip = 0;
    + if (*p != '\n' && (*pos < size)) {
    + len++;
    + *s++ = *p++;
    + if (len > 4095)
    + break; /* Too long, stop */
    + } else {
    + /* End of string */
    + *s = '\0';
    + return line;
    + }
    + }
    + /* End of buffer */
    + return NULL;
     }
     
     void
    diff -Nru a/scripts/modpost.h b/scripts/modpost.h
    --- a/scripts/modpost.h Fri Mar 12 21:54:55 2004
    +++ b/scripts/modpost.h Fri Mar 12 21:54:55 2004
    @@ -53,6 +53,9 @@
     
     #endif
     
    +#define NOFAIL(ptr) do_nofail((ptr), __FILE__, __LINE__, #ptr)
    +void *do_nofail(void *ptr, const char *file, int line, const char *expr);
    +
     struct buffer {
             char *p;
             int pos;
    @@ -95,4 +98,5 @@
                             unsigned long modinfo_offset);
     
     void *grab_file(const char *filename, unsigned long *size);
    +char* get_next_line(unsigned long *pos, void *file, unsigned long size);
     void release_file(void *file, unsigned long size);
    diff -Nru a/scripts/sumversion.c b/scripts/sumversion.c
    --- a/scripts/sumversion.c Fri Mar 12 21:54:55 2004
    +++ b/scripts/sumversion.c Fri Mar 12 21:54:55 2004
    @@ -323,12 +323,12 @@
      * figure out source file. */
     static int parse_source_files(const char *objfile, struct md4_ctx *md)
     {
    - char *cmd, *file, *p, *end;
    + char *cmd, *file, *line, *dir;
             const char *base;
    - unsigned long flen;
    - int dirlen, ret = 0;
    + unsigned long flen, pos = 0;
    + int dirlen, ret = 0, check_files = 0;
     
    - cmd = malloc(strlen(objfile) + sizeof("..cmd"));
    + cmd = NOFAIL(malloc(strlen(objfile) + sizeof("..cmd")));
     
             base = strrchr(objfile, '/');
             if (base) {
    @@ -339,6 +339,9 @@
                     dirlen = 0;
                     sprintf(cmd, ".%s.cmd", objfile);
             }
    + dir = NOFAIL(malloc(dirlen + 1));
    + strncpy(dir, objfile, dirlen);
    + dir[dirlen] = '\0';
     
             file = grab_file(cmd, &flen);
             if (!file) {
    @@ -357,48 +360,38 @@
     
                Sum all files in the same dir or subdirs.
             */
    - /* Strictly illegal: file is not nul terminated. */
    - p = strstr(file, "\ndeps_");
    - if (!p) {
    - fprintf(stderr, "Warning: could not find deps_ line in %s\n",
    - cmd);
    - goto out_file;
    - }
    - p = strstr(p, ":=");
    - if (!p) {
    - fprintf(stderr, "Warning: could not find := line in %s\n",
    - cmd);
    - goto out_file;
    - }
    - p += strlen(":=");
    - p += strspn(p, " \\\n");
    -
    - end = strstr(p, "\n\n");
    - if (!end) {
    - fprintf(stderr, "Warning: could not find end line in %s\n",
    - cmd);
    - goto out_file;
    - }
    -
    - while (p < end) {
    - unsigned int len;
    + while ((line = get_next_line(&pos, file, flen)) != NULL) {
    + char* p = line;
    + if (strncmp(line, "deps_", sizeof("deps_")-1) == 0) {
    + check_files = 1;
    + continue;
    + }
    + if (!check_files)
    + continue;
    +
    + /* Continue until line does not end with '\' */
    + if ( *(p + strlen(p)-1) != '\\')
    + break;
    + /* Terminate line at first space, to get rid of final ' \' */
    + while (*p) {
    + if isspace(*p) {
    + *p = '\0';
    + break;
    + }
    + p++;
    + }
     
    - len = strcspn(p, " \\\n");
    - if (memcmp(objfile, p, dirlen) == 0) {
    - char source[len + 1];
    -
    - memcpy(source, p, len);
    - source[len] = '\0';
    - printf("parsing %s\n", source);
    - if (!parse_file(source, md)) {
    + /* Check if this file is in same dir as objfile */
    + if ((strstr(line, dir)+strlen(dir)-1) == strrchr(line, '/')) {
    + if (!parse_file(line, md)) {
                                     fprintf(stderr,
                                             "Warning: could not open %s: %s\n",
    - source, strerror(errno));
    + line, strerror(errno));
                                     goto out_file;
                             }
    +
                     }
    - p += len;
    - p += strspn(p, " \\\n");
    +
             }
     
             /* Everyone parsed OK */
    @@ -406,6 +399,7 @@
     out_file:
             release_file(file, flen);
     out:
    + free(dir);
             free(cmd);
             return ret;
     }
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/


  • Next message: Rajesh Venkatasubramanian: "Re: anon_vma RFC2"

    Relevant Pages

    • [patch 1/22] Add __early_param for all arches
      ... files changed, 67 insertions, 2 deletionsdiff -puN include/linux/init.h~core include/linux/init.h ... * Early command line parameters. ... void; extern void softirq_init; +/* Stuff for the command line. ... To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/ ...
      (Linux-Kernel)
    • [PATCH] vmalloc might sleep
      ... diff -u -p -r1.2 vmalloc.c ... void *vmalloc_32 ... War is real, war is primarily not about defeat or ... send the line "unsubscribe linux-kernel" in ...
      (Linux-Kernel)
    • [PATCH 2.6.14-rc2] fix incorrect mm->hiwater_vm and mm->hiwater_rss
      ... diff -ru a/kernel/exit.c b/kernel/exit.c ... -void update_mem_hiwater(struct task_struct *tsk) ... +void update_mem_hiwater ... send the line "unsubscribe linux-kernel" in ...
      (Linux-Kernel)
    • kbuild: Fix warnings in binoffset.c
      ... # This is a BitKeeper generated diff -Nru style patch. ... # fix warnings in scripts/binoffset.c ... +void search_pattern ... send the line "unsubscribe linux-kernel" in ...
      (Linux-Kernel)
    • [PATCH] kern.ident + uname -i
      ... I send you this diff in order that I may gather some concensus on ... objections I'll probably commit it, since it's not a major thing, ... retrieving revision 1.51 ... typedef void; ...
      (freebsd-hackers)