Commit 57146c8a authored by Kai Germaschewski's avatar Kai Germaschewski

kbuild: [PATCH] adapt genksyms for current kbuild

By Rusty Russell.

o generate output in a form feasible as linker script instead of 
  munging it with sed during the build
o remove checksum version 1 support
o remove prefix support
parent 46bd1da6
......@@ -150,13 +150,7 @@ void *__symbol_get(const char *symbol);
void *__symbol_get_gpl(const char *symbol);
#define symbol_get(x) ((typeof(&x))(__symbol_get(MODULE_SYMBOL_PREFIX #x)))
#ifdef __GENKSYMS__
/* genksyms doesn't handle GPL-only symbols yet */
#define EXPORT_SYMBOL_GPL EXPORT_SYMBOL
#else
#ifndef __GENKSYMS__
#ifdef CONFIG_MODVERSIONS
/* Mark the CRC weak since genksyms apparently decides not to
* generate a checksums for some symbols */
......@@ -188,7 +182,7 @@ void *__symbol_get_gpl(const char *symbol);
#endif
/* We don't mangle the actual symbol anymore, so no need for
* special casing EXPORT_SYMBOL_NOVERS */
* special casing EXPORT_SYMBOL_NOVERS. FIXME: Deprecated */
#define EXPORT_SYMBOL_NOVERS(sym) EXPORT_SYMBOL(sym)
struct module_ref
......
......@@ -90,8 +90,7 @@ define rule_vcc_o_c
mv $(@D)/.tmp_$(@F) $@; \
else \
$(CPP) -D__GENKSYMS__ $(c_flags) $< \
| $(GENKSYMS) -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) \
| sed -n 's/\#define __ver_\([^ ]*\)[ ]*\([^ ]*\)/__crc_\1 = 0x\2 ;/gp' \
| $(GENKSYMS) \
> $(@D)/.tmp_$(@F:.o=.ver); \
\
$(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \
......
......@@ -4,7 +4,8 @@
New implementation contributed by Richard Henderson <rth@tamu.edu>
Based on original work by Bjorn Ekwall <bj0rn@blox.se>
This file is part of the Linux modutils.
This file was part of the Linux modutils 2.4.22: moved back into the
kernel sources by Rusty Russell/Kai Germaschewski.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
......@@ -32,22 +33,20 @@
/*----------------------------------------------------------------------*/
#define HASH_BUCKETS 4099
#define HASH_BUCKETS 4096
static struct symbol *symtab[HASH_BUCKETS];
FILE *outfile, *debugfile;
FILE *debugfile;
int cur_line = 1;
char *cur_filename, *output_directory;
int flag_debug, flag_dump_defs, flag_warnings;
int checksum_version = 1, kernel_version = version(2,0,0);
static int errors;
static int nsyms;
static struct symbol *expansion_trail;
static const char *crc_prefix = "";
static const char * const symbol_type_name[] = {
"normal", "typedef", "enum", "struct", "union"
......@@ -355,9 +354,7 @@ expand_and_crc_list(struct string_list *list, unsigned long crc)
case SYM_TYPEDEF:
subsym = find_symbol(cur->string, cur->tag);
if (checksum_version == 1)
crc = expand_and_crc_list(subsym->defn, crc);
else if (subsym->expansion_trail)
if (subsym->expansion_trail)
{
if (flag_dump_defs)
fprintf(debugfile, "%s ", cur->string);
......@@ -458,43 +455,13 @@ export_symbol(const char *name)
if (flag_dump_defs)
fputs(">\n", debugfile);
if (checksum_version > 1)
{
fprintf(outfile, "#define __ver_%s\t%s%08lx\n", name,
crc_prefix, crc);
fprintf(outfile, "#define %s\t_set_ver(%s)\n", name, name);
}
else
{
fprintf(outfile, "#define %s\t_set_ver(%s, %s%08lx)\n", name, name,
crc_prefix, crc);
}
/* Used as a linker script. */
printf("__crc_%s = 0x%08lx ;\n", name, crc);
}
}
/*----------------------------------------------------------------------*/
static int
parse_kernel_version(char * p)
{
int a, b, c;
a = strtoul(p, &p, 10);
if (*p != '.')
return -1;
b = strtoul(p+1, &p, 10);
if (*p != '.')
return -1;
c = strtoul(p+1, &p, 10);
if (*p != '\0')
return -1;
kernel_version = a << 16 | b << 8 | c;
return 0;
}
void
error(const char *fmt, ...)
{
......@@ -533,7 +500,7 @@ error_with_pos(const char *fmt, ...)
void genksyms_usage(void)
{
fputs("Usage:\n"
"genksyms [-dDwqhV] [-k kernel_version] [-p prefix] > .../linux/module/*.ver\n"
"genksyms [-dDwqhV] > /path/to/.tmp_obj.ver\n"
"\n"
" -d, --debug Increment the debug level (repeatable)\n"
" -D, --dump Dump expanded symbol defs (for debugging only)\n"
......@@ -541,10 +508,6 @@ void genksyms_usage(void)
" -q, --quiet Disable warnings (default)\n"
" -h, --help Print this message\n"
" -V, --version Print the release version\n"
" -k ver\n"
" --kernel ver Set the kernel version for which we are compiling\n"
" -p string\n"
" --prefix string Set a mangling prefix for all symbols\n"
, stderr);
}
......@@ -558,8 +521,6 @@ main(int argc, char **argv)
{"warnings", 0, 0, 'w'},
{"quiet", 0, 0, 'q'},
{"dump", 0, 0, 'D'},
{"kernel", 1, 0, 'k'},
{"prefix", 1, 0, 'p'},
{"version", 0, 0, 'V'},
{"help", 0, 0, 'h'},
{0, 0, 0, 0}
......@@ -579,20 +540,11 @@ main(int argc, char **argv)
flag_warnings = 0;
break;
case 'V':
fputs("genksyms version " MODUTILS_VERSION "\n", stderr);
fputs("genksyms version 2.5.60\n", stderr);
break;
case 'D':
flag_dump_defs = 1;
break;
case 'k':
if (parse_kernel_version(optarg)) {
fprintf( stderr, "unrecognised kernel version : %s\n", optarg);
return -1;
}
break;
case 'p':
crc_prefix = optarg;
break;
case 'h':
genksyms_usage();
return 0;
......@@ -601,27 +553,6 @@ main(int argc, char **argv)
return 1;
}
if (kernel_version >= version(2,1,18))
{
if (optind != argc) {
genksyms_usage();
return 1;
}
/* For newer kernels, eliminate some irrelevant constructs. */
checksum_version = 2;
outfile = stdout;
}
else
{
if (optind+1 != argc) {
genksyms_usage();
return 1;
}
output_directory = argv[optind];
}
{
extern int yydebug;
extern int yy_flex_debug;
......@@ -635,11 +566,6 @@ main(int argc, char **argv)
yyparse();
if (checksum_version == 1)
{
fputs("#endif\n#endif\n", outfile);
}
if (flag_debug)
{
fprintf(debugfile, "Hash table occupancy %d/%d = %g\n",
......
......@@ -454,7 +454,7 @@ int yy_flex_debug = 1;
static yyconst short int yy_rule_linenum[13] =
{ 0,
69, 70, 71, 74, 77, 78, 79, 85, 86, 87,
92, 95
89, 92
} ;
/* The intent behind this definition is that it'll catch
......@@ -473,7 +473,7 @@ char *yytext;
New implementation contributed by Richard Henderson <rth@tamu.edu>
Based on original work by Bjorn Ekwall <bj0rn@blox.se>
This file is part of the Linux modutils.
Taken from Linux modutils 2.4.22.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
......@@ -820,26 +820,23 @@ YY_RULE_SETUP
#line 87 "scripts/genksyms/lex.l"
return REAL;
YY_BREAK
/* Version 1 checksums didn't recognize ellipsis as a token, but we
need it for proper parsing. We'll take care of backward compatibility
by altering the text of the token in the second stage lexer. */
case 11:
YY_RULE_SETUP
#line 92 "scripts/genksyms/lex.l"
#line 89 "scripts/genksyms/lex.l"
return DOTS;
YY_BREAK
/* All other tokens are single characters. */
case 12:
YY_RULE_SETUP
#line 95 "scripts/genksyms/lex.l"
#line 92 "scripts/genksyms/lex.l"
return yytext[0];
YY_BREAK
case 13:
YY_RULE_SETUP
#line 98 "scripts/genksyms/lex.l"
#line 95 "scripts/genksyms/lex.l"
ECHO;
YY_BREAK
#line 843 "scripts/genksyms/lex.c"
#line 840 "scripts/genksyms/lex.c"
case YY_STATE_EOF(INITIAL):
case YY_STATE_EOF(V2_TOKENS):
yyterminate();
......@@ -1723,7 +1720,7 @@ int main()
return 0;
}
#endif
#line 98 "scripts/genksyms/lex.l"
#line 95 "scripts/genksyms/lex.l"
/* Bring in the keyword recognizer. */
......@@ -1764,7 +1761,6 @@ yylex(void)
if (lexstate == ST_NOTSTARTED)
{
if (checksum_version > 1)
BEGIN(V2_TOKENS);
next_node = xmalloc(sizeof(*next_node));
next_node->next = NULL;
......@@ -1791,93 +1787,6 @@ repeat:
cur_filename = memcpy(xmalloc(e-file+1), file, e-file+1);
cur_line = atoi(yytext+2);
/* Linux kernels 2.1.18 and above (roughly) get to ignore the
hackery below. */
if (checksum_version == 1)
{
static const char symtab_begin[] = "linux/symtab_begin.h";
static const char symtab_end[] = "linux/symtab_end.h";
/* When building 2.0 kernels, we are only given the output directory
and we're supposed to deduce the output filename from the cpp
output. */
if (outfile == NULL)
{
char buffer[PATH_MAX], *dot, *p, *q, *f;
dot = strrchr(file, '.');
f = strrchr(file, '/');
if (dot) *dot = '\0';
f = (f ? f+1 : file);
snprintf(buffer, sizeof(buffer), "%s/%s.ver", output_directory, f);
if ((outfile = fopen(buffer, "w")) == NULL)
{
perror(buffer);
exit(1);
}
fputs("/* This file is generated by genksyms DO NOT EDIT! */\n"
"#if (defined(CONFIG_MODVERSIONS) || defined(MODVERSIONS))"
" && !defined(__GENKSYMS__)\n", outfile);
q = buffer;
*q++ = '_';
for (p = f; *p ; ++p, ++q)
*q = (*p == '.' ? '_' : toupper(*p));
memcpy(q, "_VER_", 6);
fprintf(outfile, "#ifndef %s\n", buffer);
fprintf(outfile, "#define %s\n", buffer);
if (dot) *dot = '.';
}
/* For 2.0 kernels, symbol tables are constructed in big initialized
arrays that begin by including <linux/symtab_begin.h> and end by
including <linux/symtab_end.h>. We're going to transmute this
little bit o' nastiness into something that, from the perspective
of the grammar, resembles the 2.1 scheme in the following
fashion:
When we see a file name with a suffix matching symtab_begin we
should be in ST_EXPRESSION, having already seen the "= {" bits.
We get the grammar back to top-level in two stages, by returning
EXPRESSION_PHRASE then ';' as we move through ST_TABLE_1 to
ST_TABLE_2 eating the tokens we find that were contained in
symtab_begin.h. The body of the work is done in ST_TABLE_{2,5,6}
by transmuting X to EXPORT_SYMBOL and ',' to ';'. We return
to normal mode when we see a file name with a suffix matching
symtab_end.h.
This is not particularly pretty, but it is better than either
truely parsing expressions or some other bit o hackery to always
recognize and record "X" tokens for later perusal. */
if (e-file > sizeof(symtab_begin)
&& strcmp(e-sizeof(symtab_begin)+1, symtab_begin) == 0)
{
if (lexstate != ST_TABLE_1)
{
lexstate = ST_TABLE_1;
return EXPRESSION_PHRASE;
}
}
else if (e-file > sizeof(symtab_end)
&& strcmp(e-sizeof(symtab_end)+1, symtab_end) == 0)
lexstate = ST_TABLE_3;
else if (lexstate == ST_TABLE_1)
{
lexstate = ST_TABLE_2;
return ';';
}
else if (lexstate == ST_TABLE_3)
lexstate = ST_TABLE_4;
}
goto repeat;
}
......@@ -1911,10 +1820,7 @@ repeat:
goto fini;
case EXPORT_SYMBOL_KEYW:
if (checksum_version > 1)
goto fini;
else
token = IDENT;
}
}
if (!suppress_type_lookup)
......@@ -1946,11 +1852,6 @@ repeat:
break;
case DOTS:
if (checksum_version == 1)
{
_APP(". . .", 5);
break;
}
default:
APP;
break;
......
......@@ -4,7 +4,7 @@
New implementation contributed by Richard Henderson <rth@tamu.edu>
Based on original work by Bjorn Ekwall <bj0rn@blox.se>
This file is part of the Linux modutils.
Taken from Linux modutils 2.4.22.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
......@@ -86,9 +86,6 @@ MC_TOKEN ([~%^&*+=|<>/-]=)|(&&)|("||")|(->)|(<<)|(>>)
<V2_TOKENS>{INT} return INT;
<V2_TOKENS>{REAL} return REAL;
/* Version 1 checksums didn't recognize ellipsis as a token, but we
need it for proper parsing. We'll take care of backward compatibility
by altering the text of the token in the second stage lexer. */
"..." return DOTS;
/* All other tokens are single characters. */
......@@ -135,7 +132,6 @@ yylex(void)
if (lexstate == ST_NOTSTARTED)
{
if (checksum_version > 1)
BEGIN(V2_TOKENS);
next_node = xmalloc(sizeof(*next_node));
next_node->next = NULL;
......@@ -162,93 +158,6 @@ repeat:
cur_filename = memcpy(xmalloc(e-file+1), file, e-file+1);
cur_line = atoi(yytext+2);
/* Linux kernels 2.1.18 and above (roughly) get to ignore the
hackery below. */
if (checksum_version == 1)
{
static const char symtab_begin[] = "linux/symtab_begin.h";
static const char symtab_end[] = "linux/symtab_end.h";
/* When building 2.0 kernels, we are only given the output directory
and we're supposed to deduce the output filename from the cpp
output. */
if (outfile == NULL)
{
char buffer[PATH_MAX], *dot, *p, *q, *f;
dot = strrchr(file, '.');
f = strrchr(file, '/');
if (dot) *dot = '\0';
f = (f ? f+1 : file);
snprintf(buffer, sizeof(buffer), "%s/%s.ver", output_directory, f);
if ((outfile = fopen(buffer, "w")) == NULL)
{
perror(buffer);
exit(1);
}
fputs("/* This file is generated by genksyms DO NOT EDIT! */\n"
"#if (defined(CONFIG_MODVERSIONS) || defined(MODVERSIONS))"
" && !defined(__GENKSYMS__)\n", outfile);
q = buffer;
*q++ = '_';
for (p = f; *p ; ++p, ++q)
*q = (*p == '.' ? '_' : toupper(*p));
memcpy(q, "_VER_", 6);
fprintf(outfile, "#ifndef %s\n", buffer);
fprintf(outfile, "#define %s\n", buffer);
if (dot) *dot = '.';
}
/* For 2.0 kernels, symbol tables are constructed in big initialized
arrays that begin by including <linux/symtab_begin.h> and end by
including <linux/symtab_end.h>. We're going to transmute this
little bit o' nastiness into something that, from the perspective
of the grammar, resembles the 2.1 scheme in the following
fashion:
When we see a file name with a suffix matching symtab_begin we
should be in ST_EXPRESSION, having already seen the "= {" bits.
We get the grammar back to top-level in two stages, by returning
EXPRESSION_PHRASE then ';' as we move through ST_TABLE_1 to
ST_TABLE_2 eating the tokens we find that were contained in
symtab_begin.h. The body of the work is done in ST_TABLE_{2,5,6}
by transmuting X to EXPORT_SYMBOL and ',' to ';'. We return
to normal mode when we see a file name with a suffix matching
symtab_end.h.
This is not particularly pretty, but it is better than either
truely parsing expressions or some other bit o hackery to always
recognize and record "X" tokens for later perusal. */
if (e-file > sizeof(symtab_begin)
&& strcmp(e-sizeof(symtab_begin)+1, symtab_begin) == 0)
{
if (lexstate != ST_TABLE_1)
{
lexstate = ST_TABLE_1;
return EXPRESSION_PHRASE;
}
}
else if (e-file > sizeof(symtab_end)
&& strcmp(e-sizeof(symtab_end)+1, symtab_end) == 0)
lexstate = ST_TABLE_3;
else if (lexstate == ST_TABLE_1)
{
lexstate = ST_TABLE_2;
return ';';
}
else if (lexstate == ST_TABLE_3)
lexstate = ST_TABLE_4;
}
goto repeat;
}
......@@ -282,10 +191,7 @@ repeat:
goto fini;
case EXPORT_SYMBOL_KEYW:
if (checksum_version > 1)
goto fini;
else
token = IDENT;
}
}
if (!suppress_type_lookup)
......@@ -317,11 +223,6 @@ repeat:
break;
case DOTS:
if (checksum_version == 1)
{
_APP(". . .", 5);
break;
}
default:
APP;
break;
......
This diff is collapsed.
......@@ -179,7 +179,6 @@ decl_specifier:
storage_class_specifier
{ /* Version 2 checksumming ignores storage class, as that
is really irrelevant to the linkage. */
if (checksum_version > 1)
remove_node($1);
$$ = $1;
}
......@@ -356,15 +355,13 @@ direct_m_abstract_declarator:
| IDENT
{ /* For version 2 checksums, we don't want to remember
private parameter names. */
if (checksum_version > 1)
remove_node($1);
$$ = $1;
}
/* This wasn't really a typedef name but an identifier that
shadows one. */
| TYPE
{ if (checksum_version > 1)
remove_node($1);
{ remove_node($1);
$$ = $1;
}
| direct_m_abstract_declarator '(' parameter_declaration_clause ')'
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment