linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH] kbuild support for %.symtypes files
@ 2006-05-09 18:37 Andreas Gruenbacher
  2006-06-10 20:33 ` Sam Ravnborg
  2006-06-24 21:54 ` Sam Ravnborg
  0 siblings, 2 replies; 4+ messages in thread
From: Andreas Gruenbacher @ 2006-05-09 18:37 UTC (permalink / raw)
  To: linux-kernel, Sam Ravnborg; +Cc: Jon Masters

[-- Attachment #1: Type: text/plain, Size: 1705 bytes --]

Hello,

here is a patch that adds a new -T option to genksyms for generating dumps of 
the type definition that makes up the symbol version hashes. This allows to 
trace modversion changes back to what caused them. The dump format is the 
name of the type defined, followed by its definition (which is almost C):

  s#list_head struct list_head { s#list_head * next , * prev ; }

The s#, u#, e#, and t# prefixes stand for struct, union, enum, and typedef.  
The exported symbols do not define types, and thus do not have an x# prefix:

  nfs4_acl_get_whotype int nfs4_acl_get_whotype ( char * , t#u32 )

The symbol type defintion of a single file can be generated with:

  make fs/jbd/journal.symtypes

If KBUILD_SYMTYPES is defined, all the *.symtypes of all object files that 
export symbols are generated.

The single *.symtypes files can be combined into a single file after a kernel 
build with a script like the following:

for f in $(find -name '*.symtypes' | sort); do
    f=${f#./}
    echo "/* ${f%.symtypes}.o */"
    cat $f
    echo
done \
| sed -e '\:UNKNOWN:d' \
      -e 's:[,;] }:}:g' \
      -e 's:\([[({]\) :\1:g' \
      -e 's: \([])},;]\):\1:g' \
      -e 's: $::' \
      $f \
| awk '
/^.#/   { if (defined[$1] == $0) {
            print $1
            next
          }
          defined[$1] = $0
        }
        { print }
'

When the kernel ABI changes, diffing individual *.symtype files, or the 
combined files, against each other will show which symbol changes caused the 
ABI changes. This can save a tremendous amount of time.

I've been discussing this patch with Jon, and I think the patch makes more 
sense upstream than in a vendor kernel only. Comments?

Thanks,
Andreas

[-- Attachment #2: symtypes.diff --]
[-- Type: text/x-diff, Size: 7129 bytes --]

Dump the types that make up modversions

Signed-off-by: Andreas Gruenbacher <agruen@suse.de>

Index: linux-2.6.16/scripts/Makefile.build
===================================================================
--- linux-2.6.16.orig/scripts/Makefile.build
+++ linux-2.6.16/scripts/Makefile.build
@@ -140,6 +140,15 @@ cmd_cc_i_c       = $(CPP) $(c_flags)   -
 %.i: %.c FORCE
 	$(call if_changed_dep,cc_i_c)
 
+quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@
+cmd_cc_symtypes_c	   = \
+		$(CPP) -D__GENKSYMS__ $(c_flags) $<			\
+		| $(GENKSYMS) -T $@ >/dev/null;				\
+		test -s $@ || rm -f $@
+
+%.symtypes : %.c FORCE
+	$(call if_changed_dep,cc_symtypes_c)
+
 # C (.c) files
 # The C file is compiled and updated dependency information is generated.
 # (See cmd_cc_o_c + relevant part of rule_cc_o_c)
@@ -166,7 +175,8 @@ cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D
 cmd_modversions =							\
 	if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then	\
 		$(CPP) -D__GENKSYMS__ $(c_flags) $<			\
-		| $(GENKSYMS) -a $(ARCH)				\
+		| $(GENKSYMS) $(if $(KBUILD_SYMTYPES),			\
+			      -T $(@D)/$(@F:.o=.symtypes)) -a $(ARCH)	\
 		> $(@D)/.tmp_$(@F:.o=.ver);				\
 									\
 		$(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) 		\
Index: linux-2.6.16/scripts/genksyms/genksyms.c
===================================================================
--- linux-2.6.16.orig/scripts/genksyms/genksyms.c
+++ linux-2.6.16/scripts/genksyms/genksyms.c
@@ -42,7 +42,7 @@ static FILE *debugfile;
 int cur_line = 1;
 char *cur_filename;
 
-static int flag_debug, flag_dump_defs, flag_warnings;
+static int flag_debug, flag_dump_defs, flag_dump_types, flag_warnings;
 static const char *arch = "";
 static const char *mod_prefix = "";
 
@@ -50,6 +50,7 @@ static int errors;
 static int nsyms;
 
 static struct symbol *expansion_trail;
+static struct symbol *visited_symbols;
 
 static const char *const symbol_type_name[] = {
 	"normal", "typedef", "enum", "struct", "union"
@@ -176,6 +177,7 @@ struct symbol *add_symbol(const char *na
 	sym->type = type;
 	sym->defn = defn;
 	sym->expansion_trail = NULL;
+	sym->visited = NULL;
 	sym->is_extern = is_extern;
 
 	sym->hash_next = symtab[h];
@@ -236,26 +238,11 @@ static int equal_list(struct string_list
 
 static void print_node(FILE * f, struct string_list *list)
 {
-	switch (list->tag) {
-	case SYM_STRUCT:
-		putc('s', f);
-		goto printit;
-	case SYM_UNION:
-		putc('u', f);
-		goto printit;
-	case SYM_ENUM:
-		putc('e', f);
-		goto printit;
-	case SYM_TYPEDEF:
-		putc('t', f);
-		goto printit;
-
-	      printit:
+	if (list->tag != SYM_NORMAL) {
+		putc(symbol_type_name[list->tag][0], f);
 		putc('#', f);
-	case SYM_NORMAL:
-		fputs(list->string, f);
-		break;
 	}
+	fputs(list->string, f);
 }
 
 static void print_list(FILE * f, struct string_list *list)
@@ -287,9 +274,9 @@ static void print_list(FILE * f, struct 
 	}
 }
 
-static unsigned long expand_and_crc_list(struct string_list *list,
-					 unsigned long crc)
+static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc)
 {
+	struct string_list *list = sym->defn;
 	struct string_list **e, **b;
 	struct string_list *tmp, **tmp2;
 	int elem = 1;
@@ -332,7 +319,7 @@ static unsigned long expand_and_crc_list
 			} else {
 				subsym->expansion_trail = expansion_trail;
 				expansion_trail = subsym;
-				crc = expand_and_crc_list(subsym->defn, crc);
+				crc = expand_and_crc_sym(subsym, crc);
 			}
 			break;
 
@@ -382,12 +369,22 @@ static unsigned long expand_and_crc_list
 			} else {
 				subsym->expansion_trail = expansion_trail;
 				expansion_trail = subsym;
-				crc = expand_and_crc_list(subsym->defn, crc);
+				crc = expand_and_crc_sym(subsym, crc);
 			}
 			break;
 		}
 	}
 
+	{
+		static struct symbol **end = &visited_symbols;
+
+		if (!sym->visited) {
+			*end = sym;
+			end = &sym->visited;
+			sym->visited = (struct symbol *)-1L;
+		}
+	}
+
 	return crc;
 }
 
@@ -406,7 +403,7 @@ void export_symbol(const char *name)
 
 		expansion_trail = (struct symbol *)-1L;
 
-		crc = expand_and_crc_list(sym->defn, 0xffffffff) ^ 0xffffffff;
+		crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff;
 
 		sym = expansion_trail;
 		while (sym != (struct symbol *)-1L) {
@@ -464,6 +461,7 @@ static void genksyms_usage(void)
 
 int main(int argc, char **argv)
 {
+	FILE *dumpfile = NULL;
 	int o;
 
 #ifdef __GNU_LIBRARY__
@@ -473,15 +471,16 @@ int main(int argc, char **argv)
 		{"warnings", 0, 0, 'w'},
 		{"quiet", 0, 0, 'q'},
 		{"dump", 0, 0, 'D'},
+		{"dump-types", 1, 0, 'T'},
 		{"version", 0, 0, 'V'},
 		{"help", 0, 0, 'h'},
 		{0, 0, 0, 0}
 	};
 
-	while ((o = getopt_long(argc, argv, "a:dwqVDk:p:",
+	while ((o = getopt_long(argc, argv, "a:dwqVDT:k:p:",
 				&long_opts[0], NULL)) != EOF)
 #else				/* __GNU_LIBRARY__ */
-	while ((o = getopt(argc, argv, "a:dwqVDk:p:")) != EOF)
+	while ((o = getopt(argc, argv, "a:dwqVDT:k:p:")) != EOF)
 #endif				/* __GNU_LIBRARY__ */
 		switch (o) {
 		case 'a':
@@ -502,6 +501,14 @@ int main(int argc, char **argv)
 		case 'D':
 			flag_dump_defs = 1;
 			break;
+		case 'T':
+			flag_dump_types = 1;
+			dumpfile = fopen(optarg, "w");
+			if (!dumpfile) {
+				perror(optarg);
+				return 1;
+			}
+			break;
 		case 'h':
 			genksyms_usage();
 			return 0;
@@ -524,6 +531,24 @@ int main(int argc, char **argv)
 
 	yyparse();
 
+	if (flag_dump_types && visited_symbols) {
+		while (visited_symbols != (struct symbol *)-1L) {
+			struct symbol *sym = visited_symbols;
+
+			if (sym->type != SYM_NORMAL) {
+				putc(symbol_type_name[sym->type][0], dumpfile);
+				putc('#', dumpfile);
+			}
+			fputs(sym->name, dumpfile);
+			putc(' ', dumpfile);
+			print_list(dumpfile, sym->defn);
+			putc('\n', dumpfile);
+
+			visited_symbols = sym->visited;
+			sym->visited = NULL;
+		}
+	}
+
 	if (flag_debug) {
 		fprintf(debugfile, "Hash table occupancy %d/%d = %g\n",
 			nsyms, HASH_BUCKETS,
Index: linux-2.6.16/scripts/genksyms/genksyms.h
===================================================================
--- linux-2.6.16.orig/scripts/genksyms/genksyms.h
+++ linux-2.6.16/scripts/genksyms/genksyms.h
@@ -41,6 +41,7 @@ struct symbol {
 	enum symbol_type type;
 	struct string_list *defn;
 	struct symbol *expansion_trail;
+	struct symbol *visited;
 	int is_extern;
 };
 
Index: linux-2.6.16/Makefile
===================================================================
--- linux-2.6.16.orig/Makefile
+++ linux-2.6.16/Makefile
@@ -961,7 +961,8 @@ clean: archclean $(clean-dirs)
 	$(call cmd,rmfiles)
 	@find . $(RCS_FIND_IGNORE) \
 	 	\( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
-		-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \) \
+		-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
+		-o -name '*.symtypes' \) \
 		-type f -print | xargs rm -f
 
 # mrproper - Delete all generated files, including .config
@@ -1303,6 +1304,8 @@ endif
 	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
 %.o: %.S prepare scripts FORCE
 	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+%.symtypes: %.c prepare scripts FORCE
+	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
 
 # Modules
 / %/: prepare scripts FORCE

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFC PATCH] kbuild support for %.symtypes files
  2006-05-09 18:37 [RFC PATCH] kbuild support for %.symtypes files Andreas Gruenbacher
@ 2006-06-10 20:33 ` Sam Ravnborg
  2006-06-12 16:32   ` Andreas Gruenbacher
  2006-06-24 21:54 ` Sam Ravnborg
  1 sibling, 1 reply; 4+ messages in thread
From: Sam Ravnborg @ 2006-06-10 20:33 UTC (permalink / raw)
  To: Andreas Gruenbacher; +Cc: linux-kernel, Jon Masters

On Tue, May 09, 2006 at 08:37:30PM +0200, Andreas Gruenbacher wrote:
> Hello,
> 
> here is a patch that adds a new -T option to genksyms for generating dumps of 
> the type definition that makes up the symbol version hashes. This allows to 
> trace modversion changes back to what caused them. The dump format is the 
> name of the type defined, followed by its definition (which is almost C):
> 
>   s#list_head struct list_head { s#list_head * next , * prev ; }
Reading something just a little more complex than the above was very
difficult. So I went on and updated your patch to spit out something
almost 'C' alike with proper indention and a few newlines too.

The list_head struct looks like this now:

struct#list_head  struct list_head {
	struct# list_head * next , * prev;
};

The real win is for structs with 20+ members, they are now divided up in
several lines.
See attached patch.

Changes:
o print_node properly idents symbols (added putident)
o close file before exit
o ident cmd_cc_symtypes_c in Makefile.build

Patch is not yet committed, awaiting feedback from you first.

	Sam

diff --git a/Makefile b/Makefile
index 1b2fd97..f0b7c96 100644
--- a/Makefile
+++ b/Makefile
@@ -948,7 +948,8 @@ clean: archclean $(clean-dirs)
 	$(call cmd,rmfiles)
 	@find . $(RCS_FIND_IGNORE) \
 	 	\( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
-		-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \) \
+		-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
+		-o -name '*.symtypes' \) \
 		-type f -print | xargs rm -f
 
 # mrproper - Delete all generated files, including .config
@@ -1290,6 +1291,8 @@ endif
 	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
 %.o: %.S prepare scripts FORCE
 	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+%.symtypes: %.c prepare scripts FORCE
+	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
 
 # Modules
 / %/: prepare scripts FORCE
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 53e53a2..99ec1c3 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -140,6 +140,15 @@ cmd_cc_i_c       = $(CPP) $(c_flags)   -
 %.i: %.c FORCE
 	$(call if_changed_dep,cc_i_c)
 
+quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@
+      cmd_cc_symtypes_c = \
+		$(CPP) -D__GENKSYMS__ $(c_flags) $<			\
+		| $(GENKSYMS) -T $@ >/dev/null;				\
+		test -s $@ || rm -f $@
+
+%.symtypes: %.c FORCE
+	$(call if_changed_dep,cc_symtypes_c)
+
 # C (.c) files
 # The C file is compiled and updated dependency information is generated.
 # (See cmd_cc_o_c + relevant part of rule_cc_o_c)
@@ -166,7 +175,8 @@ cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D
 cmd_modversions =							\
 	if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then	\
 		$(CPP) -D__GENKSYMS__ $(c_flags) $<			\
-		| $(GENKSYMS) -a $(ARCH)				\
+		| $(GENKSYMS) $(if $(KBUILD_SYMTYPES),			\
+			      -T $(@D)/$(@F:.o=.symtypes)) -a $(ARCH)	\
 		> $(@D)/.tmp_$(@F:.o=.ver);				\
 									\
 		$(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) 		\
diff --git a/scripts/genksyms/genksyms.c b/scripts/genksyms/genksyms.c
index 5b0344e..33ffebf 100644
--- a/scripts/genksyms/genksyms.c
+++ b/scripts/genksyms/genksyms.c
@@ -42,7 +42,7 @@ static FILE *debugfile;
 int cur_line = 1;
 char *cur_filename;
 
-static int flag_debug, flag_dump_defs, flag_warnings;
+static int flag_debug, flag_dump_defs, flag_dump_types, flag_warnings;
 static const char *arch = "";
 static const char *mod_prefix = "";
 
@@ -50,6 +50,7 @@ static int errors;
 static int nsyms;
 
 static struct symbol *expansion_trail;
+static struct symbol *visited_symbols;
 
 static const char *const symbol_type_name[] = {
 	"normal", "typedef", "enum", "struct", "union"
@@ -176,6 +177,7 @@ struct symbol *add_symbol(const char *na
 	sym->type = type;
 	sym->defn = defn;
 	sym->expansion_trail = NULL;
+	sym->visited = NULL;
 	sym->is_extern = is_extern;
 
 	sym->hash_next = symtab[h];
@@ -233,28 +235,50 @@ static int equal_list(struct string_list
 
 	return !a && !b;
 }
+static void putident(int l, FILE *f)
+{
+	while (l--)
+		fputc('\t', f);
+}
 
-static void print_node(FILE * f, struct string_list *list)
+static void print_node(FILE * f, struct string_list *list, int *ident)
 {
-	switch (list->tag) {
-	case SYM_STRUCT:
-		putc('s', f);
-		goto printit;
-	case SYM_UNION:
-		putc('u', f);
-		goto printit;
-	case SYM_ENUM:
-		putc('e', f);
-		goto printit;
-	case SYM_TYPEDEF:
-		putc('t', f);
-		goto printit;
-
-	      printit:
+	static int newline = 1;
+	if (list->tag != SYM_NORMAL) {
+		if (newline) {
+			putident(*ident, f);
+			newline = 0;
+		} else {
+			putc(' ', f);
+		}
+		fputs(symbol_type_name[list->tag], f);
 		putc('#', f);
-	case SYM_NORMAL:
-		fputs(list->string, f);
-		break;
+	}
+	switch (list->string[0]) {
+		case '{':
+			fputs(" {\n", f);
+			(*ident)++;
+			newline = 1;
+			break;
+		case '}':
+			(*ident)--;
+			putident(*ident, f);
+			fputc('}', f);
+			newline = 0;
+			break;
+		case ';':
+			fputs(";\n", f);
+			newline = 1;
+			break;
+		default:
+			if (newline) {
+				putident(*ident, f);
+				newline = 0;
+			} else {
+				putc(' ', f);
+			}
+			fputs(list->string, f);
+			break;
 	}
 }
 
@@ -263,6 +287,7 @@ static void print_list(FILE * f, struct 
 	struct string_list **e, **b;
 	struct string_list *tmp, **tmp2;
 	int elem = 1;
+	int ident = 0;
 
 	if (list == NULL) {
 		fputs("(nil)", f);
@@ -282,14 +307,13 @@ static void print_list(FILE * f, struct 
 		*(tmp2--) = list;
 
 	while (b != e) {
-		print_node(f, *b++);
-		putc(' ', f);
+		print_node(f, *b++, &ident);
 	}
 }
 
-static unsigned long expand_and_crc_list(struct string_list *list,
-					 unsigned long crc)
+static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc)
 {
+	struct string_list *list = sym->defn;
 	struct string_list **e, **b;
 	struct string_list *tmp, **tmp2;
 	int elem = 1;
@@ -332,7 +356,7 @@ static unsigned long expand_and_crc_list
 			} else {
 				subsym->expansion_trail = expansion_trail;
 				expansion_trail = subsym;
-				crc = expand_and_crc_list(subsym->defn, crc);
+				crc = expand_and_crc_sym(subsym, crc);
 			}
 			break;
 
@@ -382,12 +406,22 @@ static unsigned long expand_and_crc_list
 			} else {
 				subsym->expansion_trail = expansion_trail;
 				expansion_trail = subsym;
-				crc = expand_and_crc_list(subsym->defn, crc);
+				crc = expand_and_crc_sym(subsym, crc);
 			}
 			break;
 		}
 	}
 
+	{
+		static struct symbol **end = &visited_symbols;
+
+		if (!sym->visited) {
+			*end = sym;
+			end = &sym->visited;
+			sym->visited = (struct symbol *)-1L;
+		}
+	}
+
 	return crc;
 }
 
@@ -406,7 +440,7 @@ void export_symbol(const char *name)
 
 		expansion_trail = (struct symbol *)-1L;
 
-		crc = expand_and_crc_list(sym->defn, 0xffffffff) ^ 0xffffffff;
+		crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff;
 
 		sym = expansion_trail;
 		while (sym != (struct symbol *)-1L) {
@@ -464,6 +498,7 @@ #endif				/* __GNU_LIBRARY__ */
 
 int main(int argc, char **argv)
 {
+	FILE *dumpfile = NULL;
 	int o;
 
 #ifdef __GNU_LIBRARY__
@@ -473,15 +508,16 @@ #ifdef __GNU_LIBRARY__
 		{"warnings", 0, 0, 'w'},
 		{"quiet", 0, 0, 'q'},
 		{"dump", 0, 0, 'D'},
+		{"dump-types", 1, 0, 'T'},
 		{"version", 0, 0, 'V'},
 		{"help", 0, 0, 'h'},
 		{0, 0, 0, 0}
 	};
 
-	while ((o = getopt_long(argc, argv, "a:dwqVDk:p:",
+	while ((o = getopt_long(argc, argv, "a:dwqVDT:k:p:",
 				&long_opts[0], NULL)) != EOF)
 #else				/* __GNU_LIBRARY__ */
-	while ((o = getopt(argc, argv, "a:dwqVDk:p:")) != EOF)
+	while ((o = getopt(argc, argv, "a:dwqVDT:k:p:")) != EOF)
 #endif				/* __GNU_LIBRARY__ */
 		switch (o) {
 		case 'a':
@@ -502,6 +538,14 @@ #endif				/* __GNU_LIBRARY__ */
 		case 'D':
 			flag_dump_defs = 1;
 			break;
+		case 'T':
+			flag_dump_types = 1;
+			dumpfile = fopen(optarg, "w");
+			if (!dumpfile) {
+				perror(optarg);
+				return 1;
+			}
+			break;
 		case 'h':
 			genksyms_usage();
 			return 0;
@@ -524,6 +568,28 @@ #endif				/* __GNU_LIBRARY__ */
 
 	yyparse();
 
+	if (flag_dump_types) {
+		if (visited_symbols) {
+			while (visited_symbols != (struct symbol *)-1L) {
+				struct symbol *sym = visited_symbols;
+
+				if (sym->type != SYM_NORMAL) {
+					fputs(symbol_type_name[sym->type],
+					     dumpfile);
+					putc('#', dumpfile);
+				}
+				fputs(sym->name, dumpfile);
+				putc(' ', dumpfile);
+				print_list(dumpfile, sym->defn);
+				fputs(";\n\n", dumpfile);
+
+				visited_symbols = sym->visited;
+				sym->visited = NULL;
+			}
+		}
+		fclose(dumpfile);
+	}
+
 	if (flag_debug) {
 		fprintf(debugfile, "Hash table occupancy %d/%d = %g\n",
 			nsyms, HASH_BUCKETS,
diff --git a/scripts/genksyms/genksyms.h b/scripts/genksyms/genksyms.h
index ab6f34f..2668287 100644
--- a/scripts/genksyms/genksyms.h
+++ b/scripts/genksyms/genksyms.h
@@ -41,6 +41,7 @@ struct symbol {
 	enum symbol_type type;
 	struct string_list *defn;
 	struct symbol *expansion_trail;
+	struct symbol *visited;
 	int is_extern;
 };
 

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [RFC PATCH] kbuild support for %.symtypes files
  2006-06-10 20:33 ` Sam Ravnborg
@ 2006-06-12 16:32   ` Andreas Gruenbacher
  0 siblings, 0 replies; 4+ messages in thread
From: Andreas Gruenbacher @ 2006-06-12 16:32 UTC (permalink / raw)
  To: Sam Ravnborg; +Cc: linux-kernel, Jon Masters

On Saturday, 10 June 2006 22:33, Sam Ravnborg wrote:
> On Tue, May 09, 2006 at 08:37:30PM +0200, Andreas Gruenbacher wrote:
> > Hello,
> >
> > here is a patch that adds a new -T option to genksyms for generating
> > dumps of the type definition that makes up the symbol version hashes.
> > This allows to trace modversion changes back to what caused them. The
> > dump format is the name of the type defined, followed by its definition
> > (which is almost C):
> >
> >   s#list_head struct list_head { s#list_head * next , * prev ; }
>
> Reading something just a little more complex than the above was very
> difficult. So I went on and updated your patch to spit out something
> almost 'C' alike with proper indention and a few newlines too.
>
> The list_head struct looks like this now:
>
> struct#list_head  struct list_head {
> 	struct# list_head * next , * prev;
> };
>
> The real win is for structs with 20+ members, they are now divided up in
> several lines.

Please let's not beautify the output: this would make diffing and grepping 
harder. It's easy to pipe the simple, line oriented format through a 
formatting filter if necessary.

The output could be made more readable by converting the "x#" prefix to C 
keywords (struct, union, etc.). I didn't do this because that would introduce 
parse problems, and constructing dependency graphs from the dump files would 
become tricky.

Andreas

-- 
Andreas Gruenbacher <agruen@suse.de>
Novell / SUSE Labs

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFC PATCH] kbuild support for %.symtypes files
  2006-05-09 18:37 [RFC PATCH] kbuild support for %.symtypes files Andreas Gruenbacher
  2006-06-10 20:33 ` Sam Ravnborg
@ 2006-06-24 21:54 ` Sam Ravnborg
  1 sibling, 0 replies; 4+ messages in thread
From: Sam Ravnborg @ 2006-06-24 21:54 UTC (permalink / raw)
  To: Andreas Gruenbacher; +Cc: linux-kernel, Jon Masters

On Tue, May 09, 2006 at 08:37:30PM +0200, Andreas Gruenbacher wrote:
> Hello,
> 
> here is a patch that adds a new -T option to genksyms for generating dumps of 
> the type definition that makes up the symbol version hashes. This allows to 
> trace modversion changes back to what caused them. The dump format is the 
> name of the type defined, followed by its definition (which is almost C):

Applid as is. But please take a closer look at the output format.
Making it human readable somewho is desireable - even it the parsing
needs a bit more effort then.

	Sam

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2006-06-24 21:54 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-05-09 18:37 [RFC PATCH] kbuild support for %.symtypes files Andreas Gruenbacher
2006-06-10 20:33 ` Sam Ravnborg
2006-06-12 16:32   ` Andreas Gruenbacher
2006-06-24 21:54 ` Sam Ravnborg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).