Blame view

scripts/genksyms/genksyms.c 22.4 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  /* Generate kernel symbol version hashes.
     Copyright 1996, 1997 Linux International.
  
     New implementation contributed by Richard Henderson <rth@tamu.edu>
     Based on original work by Bjorn Ekwall <bj0rn@blox.se>
  
     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
     Free Software Foundation; either version 2 of the License, or (at your
     option) any later version.
  
     This program is distributed in the hope that it will be useful, but
     WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     General Public License for more details.
  
     You should have received a copy of the GNU General Public License
     along with this program; if not, write to the Free Software Foundation,
     Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
  
  #include <stdio.h>
  #include <string.h>
  #include <stdlib.h>
  #include <unistd.h>
  #include <assert.h>
  #include <stdarg.h>
  #ifdef __GNU_LIBRARY__
  #include <getopt.h>
78c041530   Sam Ravnborg   kbuild: Lindent g...
32
  #endif				/* __GNU_LIBRARY__ */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
33
34
  
  #include "genksyms.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35
36
37
38
39
  /*----------------------------------------------------------------------*/
  
  #define HASH_BUCKETS  4096
  
  static struct symbol *symtab[HASH_BUCKETS];
ce5606869   Sam Ravnborg   kbuild: clean-up ...
40
  static FILE *debugfile;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41
42
  
  int cur_line = 1;
ce5606869   Sam Ravnborg   kbuild: clean-up ...
43
  char *cur_filename;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
44

64e6c1e12   Andreas Gruenbacher   genksyms: track s...
45
  static int flag_debug, flag_dump_defs, flag_reference, flag_dump_types,
2ea038917   Sam Ravnborg   Revert "kbuild: s...
46
  	   flag_preserve, flag_warnings;
ce5606869   Sam Ravnborg   kbuild: clean-up ...
47
48
  static const char *arch = "";
  static const char *mod_prefix = "";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49
50
51
52
53
  
  static int errors;
  static int nsyms;
  
  static struct symbol *expansion_trail;
15fde6751   Andreas Gruenbacher   kbuild: support f...
54
  static struct symbol *visited_symbols;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
55

7ec8eda15   Michal Marek   genksyms: Simplif...
56
57
58
59
60
61
62
63
64
  static const struct {
  	int n;
  	const char *name;
  } symbol_types[] = {
  	[SYM_NORMAL]     = { 0, NULL},
  	[SYM_TYPEDEF]    = {'t', "typedef"},
  	[SYM_ENUM]       = {'e', "enum"},
  	[SYM_STRUCT]     = {'s', "struct"},
  	[SYM_UNION]      = {'u', "union"},
e37ddb825   Michal Marek   genksyms: Track c...
65
  	[SYM_ENUM_CONST] = {'E', "enum constant"},
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66
  };
ce5606869   Sam Ravnborg   kbuild: clean-up ...
67
68
  static int equal_list(struct string_list *a, struct string_list *b);
  static void print_list(FILE * f, struct string_list *list);
68eb8563a   Michal Marek   genksyms: Add hel...
69
70
  static struct string_list *concat_list(struct string_list *start, ...);
  static struct string_list *mk_node(const char *string);
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
71
72
  static void print_location(void);
  static void print_type_name(enum symbol_type type, const char *name);
ce5606869   Sam Ravnborg   kbuild: clean-up ...
73

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
74
  /*----------------------------------------------------------------------*/
78c041530   Sam Ravnborg   kbuild: Lindent g...
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
  static const unsigned int crctab32[] = {
  	0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U,
  	0x706af48fU, 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U,
  	0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U,
  	0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU,
  	0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, 0x136c9856U,
  	0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 0x14015c4fU, 0x63066cd9U,
  	0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U,
  	0xa2677172U, 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU,
  	0x35b5a8faU, 0x42b2986cU, 0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U,
  	0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, 0x26d930acU, 0x51de003aU,
  	0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U,
  	0xb8bda50fU, 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U,
  	0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 0x76dc4190U,
  	0x01db7106U, 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x06b6b51fU,
  	0x9fbfe4a5U, 0xe8b8d433U, 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU,
  	0xe10e9818U, 0x7f6a0dbbU, 0x086d3d2dU, 0x91646c97U, 0xe6635c01U,
  	0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, 0x6c0695edU,
  	0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U,
  	0x8bbeb8eaU, 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U,
  	0xfbd44c65U, 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U,
  	0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU,
  	0x346ed9fcU, 0xad678846U, 0xda60b8d0U, 0x44042d73U, 0x33031de5U,
  	0xaa0a4c5fU, 0xdd0d7cc9U, 0x5005713cU, 0x270241aaU, 0xbe0b1010U,
  	0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU,
  	0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U,
  	0x2eb40d81U, 0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U,
  	0x03b6e20cU, 0x74b1d29aU, 0xead54739U, 0x9dd277afU, 0x04db2615U,
  	0x73dc1683U, 0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U,
  	0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, 0xf00f9344U,
  	0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 0xf762575dU, 0x806567cbU,
  	0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU,
  	0x67dd4accU, 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U,
  	0xd6d6a3e8U, 0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U,
  	0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, 0xd80d2bdaU, 0xaf0a1b4cU,
  	0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, 0x316e8eefU,
  	0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U,
  	0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU,
  	0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, 0xb5d0cf31U,
  	0x2cd99e8bU, 0x5bdeae1dU, 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU,
  	0x026d930aU, 0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U,
  	0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U, 0x92d28e9bU,
  	0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 0x86d3d2d4U, 0xf1d4e242U,
  	0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U,
  	0x18b74777U, 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU,
  	0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U, 0xa00ae278U,
  	0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, 0xa7672661U, 0xd06016f7U,
  	0x4969474dU, 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U,
  	0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U,
  	0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U,
  	0xcdd70693U, 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U,
  	0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU,
  	0x2d02ef8dU
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
128
  };
ce5606869   Sam Ravnborg   kbuild: clean-up ...
129
  static unsigned long partial_crc32_one(unsigned char c, unsigned long crc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
130
  {
78c041530   Sam Ravnborg   kbuild: Lindent g...
131
  	return crctab32[(crc ^ c) & 0xff] ^ (crc >> 8);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
132
  }
ce5606869   Sam Ravnborg   kbuild: clean-up ...
133
  static unsigned long partial_crc32(const char *s, unsigned long crc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
134
  {
78c041530   Sam Ravnborg   kbuild: Lindent g...
135
136
137
  	while (*s)
  		crc = partial_crc32_one(*s++, crc);
  	return crc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
138
  }
ce5606869   Sam Ravnborg   kbuild: clean-up ...
139
  static unsigned long crc32(const char *s)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140
  {
78c041530   Sam Ravnborg   kbuild: Lindent g...
141
  	return partial_crc32(s, 0xffffffff) ^ 0xffffffff;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
142
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
143
  /*----------------------------------------------------------------------*/
ce5606869   Sam Ravnborg   kbuild: clean-up ...
144
  static enum symbol_type map_to_ns(enum symbol_type t)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
145
  {
e37ddb825   Michal Marek   genksyms: Track c...
146
147
148
149
150
151
152
153
154
155
  	switch (t) {
  	case SYM_ENUM_CONST:
  	case SYM_NORMAL:
  	case SYM_TYPEDEF:
  		return SYM_NORMAL;
  	case SYM_ENUM:
  	case SYM_STRUCT:
  	case SYM_UNION:
  		return SYM_STRUCT;
  	}
78c041530   Sam Ravnborg   kbuild: Lindent g...
156
  	return t;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157
  }
01762c4ec   Michal Marek   genksyms: simplif...
158
  struct symbol *find_symbol(const char *name, enum symbol_type ns, int exact)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
159
  {
78c041530   Sam Ravnborg   kbuild: Lindent g...
160
161
  	unsigned long h = crc32(name) % HASH_BUCKETS;
  	struct symbol *sym;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
162

78c041530   Sam Ravnborg   kbuild: Lindent g...
163
  	for (sym = symtab[h]; sym; sym = sym->hash_next)
ce5606869   Sam Ravnborg   kbuild: clean-up ...
164
  		if (map_to_ns(sym->type) == map_to_ns(ns) &&
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
165
166
  		    strcmp(name, sym->name) == 0 &&
  		    sym->is_declared)
78c041530   Sam Ravnborg   kbuild: Lindent g...
167
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168

01762c4ec   Michal Marek   genksyms: simplif...
169
170
  	if (exact && sym && sym->type != ns)
  		return NULL;
78c041530   Sam Ravnborg   kbuild: Lindent g...
171
  	return sym;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172
  }
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
173
174
175
176
177
178
179
180
181
182
183
184
185
186
  static int is_unknown_symbol(struct symbol *sym)
  {
  	struct string_list *defn;
  
  	return ((sym->type == SYM_STRUCT ||
  		 sym->type == SYM_UNION ||
  		 sym->type == SYM_ENUM) &&
  		(defn = sym->defn)  && defn->tag == SYM_NORMAL &&
  			strcmp(defn->string, "}") == 0 &&
  		(defn = defn->next) && defn->tag == SYM_NORMAL &&
  			strcmp(defn->string, "UNKNOWN") == 0 &&
  		(defn = defn->next) && defn->tag == SYM_NORMAL &&
  			strcmp(defn->string, "{") == 0);
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
187
  static struct symbol *__add_symbol(const char *name, enum symbol_type type,
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
188
189
  			    struct string_list *defn, int is_extern,
  			    int is_reference)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
190
  {
e37ddb825   Michal Marek   genksyms: Track c...
191
  	unsigned long h;
78c041530   Sam Ravnborg   kbuild: Lindent g...
192
  	struct symbol *sym;
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
193
  	enum symbol_status status = STATUS_UNCHANGED;
e37ddb825   Michal Marek   genksyms: Track c...
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
  	/* The parser adds symbols in the order their declaration completes,
  	 * so it is safe to store the value of the previous enum constant in
  	 * a static variable.
  	 */
  	static int enum_counter;
  	static struct string_list *last_enum_expr;
  
  	if (type == SYM_ENUM_CONST) {
  		if (defn) {
  			free_list(last_enum_expr, NULL);
  			last_enum_expr = copy_list_range(defn, NULL);
  			enum_counter = 1;
  		} else {
  			struct string_list *expr;
  			char buf[20];
  
  			snprintf(buf, sizeof(buf), "%d", enum_counter++);
  			if (last_enum_expr) {
  				expr = copy_list_range(last_enum_expr, NULL);
  				defn = concat_list(mk_node("("),
  						   expr,
  						   mk_node(")"),
  						   mk_node("+"),
  						   mk_node(buf), NULL);
  			} else {
  				defn = mk_node(buf);
  			}
  		}
  	} else if (type == SYM_ENUM) {
  		free_list(last_enum_expr, NULL);
  		last_enum_expr = NULL;
  		enum_counter = 0;
  		if (!name)
  			/* Anonymous enum definition, nothing more to do */
  			return NULL;
  	}
78c041530   Sam Ravnborg   kbuild: Lindent g...
230

e37ddb825   Michal Marek   genksyms: Track c...
231
  	h = crc32(name) % HASH_BUCKETS;
ce5606869   Sam Ravnborg   kbuild: clean-up ...
232
  	for (sym = symtab[h]; sym; sym = sym->hash_next) {
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
233
234
235
236
237
238
  		if (map_to_ns(sym->type) == map_to_ns(type) &&
  		    strcmp(name, sym->name) == 0) {
  			if (is_reference)
  				/* fall through */ ;
  			else if (sym->type == type &&
  				 equal_list(sym->defn, defn)) {
5dae9a550   Andreas Gruenbacher   genksyms: allow t...
239
240
241
242
243
244
245
  				if (!sym->is_declared && sym->is_override) {
  					print_location();
  					print_type_name(type, name);
  					fprintf(stderr, " modversion is "
  						"unchanged
  ");
  				}
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
246
247
248
  				sym->is_declared = 1;
  				return sym;
  			} else if (!sym->is_declared) {
5dae9a550   Andreas Gruenbacher   genksyms: allow t...
249
250
251
252
253
254
255
256
257
258
259
260
  				if (sym->is_override && flag_preserve) {
  					print_location();
  					fprintf(stderr, "ignoring ");
  					print_type_name(type, name);
  					fprintf(stderr, " modversion change
  ");
  					sym->is_declared = 1;
  					return sym;
  				} else {
  					status = is_unknown_symbol(sym) ?
  						STATUS_DEFINED : STATUS_MODIFIED;
  				}
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
261
  			} else {
78c041530   Sam Ravnborg   kbuild: Lindent g...
262
  				error_with_pos("redefinition of %s", name);
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
263
264
265
  				return sym;
  			}
  			break;
78c041530   Sam Ravnborg   kbuild: Lindent g...
266
  		}
ce5606869   Sam Ravnborg   kbuild: clean-up ...
267
  	}
78c041530   Sam Ravnborg   kbuild: Lindent g...
268

64e6c1e12   Andreas Gruenbacher   genksyms: track s...
269
270
271
272
273
274
275
276
277
278
279
  	if (sym) {
  		struct symbol **psym;
  
  		for (psym = &symtab[h]; *psym; psym = &(*psym)->hash_next) {
  			if (*psym == sym) {
  				*psym = sym->hash_next;
  				break;
  			}
  		}
  		--nsyms;
  	}
78c041530   Sam Ravnborg   kbuild: Lindent g...
280
281
282
283
284
  	sym = xmalloc(sizeof(*sym));
  	sym->name = name;
  	sym->type = type;
  	sym->defn = defn;
  	sym->expansion_trail = NULL;
15fde6751   Andreas Gruenbacher   kbuild: support f...
285
  	sym->visited = NULL;
78c041530   Sam Ravnborg   kbuild: Lindent g...
286
287
288
289
  	sym->is_extern = is_extern;
  
  	sym->hash_next = symtab[h];
  	symtab[h] = sym;
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
290
291
  	sym->is_declared = !is_reference;
  	sym->status = status;
5dae9a550   Andreas Gruenbacher   genksyms: allow t...
292
  	sym->is_override = 0;
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
293

78c041530   Sam Ravnborg   kbuild: Lindent g...
294
  	if (flag_debug) {
7ec8eda15   Michal Marek   genksyms: Simplif...
295
296
297
298
299
300
  		if (symbol_types[type].name)
  			fprintf(debugfile, "Defn for %s %s == <",
  				symbol_types[type].name, name);
  		else
  			fprintf(debugfile, "Defn for type%d %s == <",
  				type, name);
78c041530   Sam Ravnborg   kbuild: Lindent g...
301
302
303
304
305
306
307
308
  		if (is_extern)
  			fputs("extern ", debugfile);
  		print_list(debugfile, defn);
  		fputs(">
  ", debugfile);
  	}
  
  	++nsyms;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
309
  	return sym;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
310
  }
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
311
312
313
314
315
  struct symbol *add_symbol(const char *name, enum symbol_type type,
  			  struct string_list *defn, int is_extern)
  {
  	return __add_symbol(name, type, defn, is_extern, 0);
  }
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
316
  static struct symbol *add_reference_symbol(const char *name, enum symbol_type type,
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
317
318
319
320
  				    struct string_list *defn, int is_extern)
  {
  	return __add_symbol(name, type, defn, is_extern, 1);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
321
  /*----------------------------------------------------------------------*/
ce5606869   Sam Ravnborg   kbuild: clean-up ...
322
  void free_node(struct string_list *node)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
323
  {
78c041530   Sam Ravnborg   kbuild: Lindent g...
324
325
  	free(node->string);
  	free(node);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
326
  }
78c041530   Sam Ravnborg   kbuild: Lindent g...
327
  void free_list(struct string_list *s, struct string_list *e)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
328
  {
78c041530   Sam Ravnborg   kbuild: Lindent g...
329
330
331
332
333
  	while (s != e) {
  		struct string_list *next = s->next;
  		free_node(s);
  		s = next;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
334
  }
68eb8563a   Michal Marek   genksyms: Add hel...
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
  static struct string_list *mk_node(const char *string)
  {
  	struct string_list *newnode;
  
  	newnode = xmalloc(sizeof(*newnode));
  	newnode->string = xstrdup(string);
  	newnode->tag = SYM_NORMAL;
  	newnode->next = NULL;
  
  	return newnode;
  }
  
  static struct string_list *concat_list(struct string_list *start, ...)
  {
  	va_list ap;
  	struct string_list *n, *n2;
  
  	if (!start)
  		return NULL;
  	for (va_start(ap, start); (n = va_arg(ap, struct string_list *));) {
  		for (n2 = n; n2->next; n2 = n2->next)
  			;
  		n2->next = start;
  		start = n;
  	}
  	va_end(ap);
  	return start;
  }
ce5606869   Sam Ravnborg   kbuild: clean-up ...
363
  struct string_list *copy_node(struct string_list *node)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
364
  {
78c041530   Sam Ravnborg   kbuild: Lindent g...
365
  	struct string_list *newnode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
366

78c041530   Sam Ravnborg   kbuild: Lindent g...
367
368
369
  	newnode = xmalloc(sizeof(*newnode));
  	newnode->string = xstrdup(node->string);
  	newnode->tag = node->tag;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
370

78c041530   Sam Ravnborg   kbuild: Lindent g...
371
  	return newnode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
372
  }
e37ddb825   Michal Marek   genksyms: Track c...
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
  struct string_list *copy_list_range(struct string_list *start,
  				    struct string_list *end)
  {
  	struct string_list *res, *n;
  
  	if (start == end)
  		return NULL;
  	n = res = copy_node(start);
  	for (start = start->next; start != end; start = start->next) {
  		n->next = copy_node(start);
  		n = n->next;
  	}
  	n->next = NULL;
  	return res;
  }
ce5606869   Sam Ravnborg   kbuild: clean-up ...
388
  static int equal_list(struct string_list *a, struct string_list *b)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
389
  {
78c041530   Sam Ravnborg   kbuild: Lindent g...
390
391
392
393
394
395
  	while (a && b) {
  		if (a->tag != b->tag || strcmp(a->string, b->string))
  			return 0;
  		a = a->next;
  		b = b->next;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
396

78c041530   Sam Ravnborg   kbuild: Lindent g...
397
  	return !a && !b;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
398
  }
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
399
  #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
400
  static struct string_list *read_node(FILE *f)
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
  {
  	char buffer[256];
  	struct string_list node = {
  		.string = buffer,
  		.tag = SYM_NORMAL };
  	int c;
  
  	while ((c = fgetc(f)) != EOF) {
  		if (c == ' ') {
  			if (node.string == buffer)
  				continue;
  			break;
  		} else if (c == '
  ') {
  			if (node.string == buffer)
  				return NULL;
  			ungetc(c, f);
  			break;
  		}
  		if (node.string >= buffer + sizeof(buffer) - 1) {
  			fprintf(stderr, "Token too long
  ");
  			exit(1);
  		}
  		*node.string++ = c;
  	}
  	if (node.string == buffer)
  		return NULL;
  	*node.string = 0;
  	node.string = buffer;
  
  	if (node.string[1] == '#') {
  		int n;
7ec8eda15   Michal Marek   genksyms: Simplif...
434
435
  		for (n = 0; n < ARRAY_SIZE(symbol_types); n++) {
  			if (node.string[0] == symbol_types[n].n) {
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
  				node.tag = n;
  				node.string += 2;
  				return copy_node(&node);
  			}
  		}
  		fprintf(stderr, "Unknown type %c
  ", node.string[0]);
  		exit(1);
  	}
  	return copy_node(&node);
  }
  
  static void read_reference(FILE *f)
  {
  	while (!feof(f)) {
  		struct string_list *defn = NULL;
  		struct string_list *sym, *def;
5dae9a550   Andreas Gruenbacher   genksyms: allow t...
453
454
  		int is_extern = 0, is_override = 0;
  		struct symbol *subsym;
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
455
456
  
  		sym = read_node(f);
5dae9a550   Andreas Gruenbacher   genksyms: allow t...
457
458
459
460
461
462
  		if (sym && sym->tag == SYM_NORMAL &&
  		    !strcmp(sym->string, "override")) {
  			is_override = 1;
  			free_node(sym);
  			sym = read_node(f);
  		}
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
463
464
465
466
467
468
469
470
471
472
473
474
475
476
  		if (!sym)
  			continue;
  		def = read_node(f);
  		if (def && def->tag == SYM_NORMAL &&
  		    !strcmp(def->string, "extern")) {
  			is_extern = 1;
  			free_node(def);
  			def = read_node(f);
  		}
  		while (def) {
  			def->next = defn;
  			defn = def;
  			def = read_node(f);
  		}
5dae9a550   Andreas Gruenbacher   genksyms: allow t...
477
  		subsym = add_reference_symbol(xstrdup(sym->string), sym->tag,
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
478
  					      defn, is_extern);
5dae9a550   Andreas Gruenbacher   genksyms: allow t...
479
  		subsym->is_override = is_override;
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
480
481
482
  		free_node(sym);
  	}
  }
ce5606869   Sam Ravnborg   kbuild: clean-up ...
483
  static void print_node(FILE * f, struct string_list *list)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
484
  {
7ec8eda15   Michal Marek   genksyms: Simplif...
485
486
  	if (symbol_types[list->tag].n) {
  		putc(symbol_types[list->tag].n, f);
78c041530   Sam Ravnborg   kbuild: Lindent g...
487
  		putc('#', f);
78c041530   Sam Ravnborg   kbuild: Lindent g...
488
  	}
15fde6751   Andreas Gruenbacher   kbuild: support f...
489
  	fputs(list->string, f);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
490
  }
ce5606869   Sam Ravnborg   kbuild: clean-up ...
491
  static void print_list(FILE * f, struct string_list *list)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
492
  {
78c041530   Sam Ravnborg   kbuild: Lindent g...
493
494
495
  	struct string_list **e, **b;
  	struct string_list *tmp, **tmp2;
  	int elem = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
496

78c041530   Sam Ravnborg   kbuild: Lindent g...
497
498
499
500
  	if (list == NULL) {
  		fputs("(nil)", f);
  		return;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
501

78c041530   Sam Ravnborg   kbuild: Lindent g...
502
503
504
  	tmp = list;
  	while ((tmp = tmp->next) != NULL)
  		elem++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
505

78c041530   Sam Ravnborg   kbuild: Lindent g...
506
507
508
  	b = alloca(elem * sizeof(*e));
  	e = b + elem;
  	tmp2 = e - 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
509

78c041530   Sam Ravnborg   kbuild: Lindent g...
510
511
512
  	(*tmp2--) = list;
  	while ((list = list->next) != NULL)
  		*(tmp2--) = list;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
513

78c041530   Sam Ravnborg   kbuild: Lindent g...
514
515
516
517
518
  	while (b != e) {
  		print_node(f, *b++);
  		putc(' ', f);
  	}
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
519

15fde6751   Andreas Gruenbacher   kbuild: support f...
520
  static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc)
78c041530   Sam Ravnborg   kbuild: Lindent g...
521
  {
15fde6751   Andreas Gruenbacher   kbuild: support f...
522
  	struct string_list *list = sym->defn;
78c041530   Sam Ravnborg   kbuild: Lindent g...
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
  	struct string_list **e, **b;
  	struct string_list *tmp, **tmp2;
  	int elem = 1;
  
  	if (!list)
  		return crc;
  
  	tmp = list;
  	while ((tmp = tmp->next) != NULL)
  		elem++;
  
  	b = alloca(elem * sizeof(*e));
  	e = b + elem;
  	tmp2 = e - 1;
  
  	*(tmp2--) = list;
  	while ((list = list->next) != NULL)
  		*(tmp2--) = list;
  
  	while (b != e) {
  		struct string_list *cur;
  		struct symbol *subsym;
  
  		cur = *(b++);
  		switch (cur->tag) {
  		case SYM_NORMAL:
  			if (flag_dump_defs)
  				fprintf(debugfile, "%s ", cur->string);
  			crc = partial_crc32(cur->string, crc);
  			crc = partial_crc32_one(' ', crc);
  			break;
e37ddb825   Michal Marek   genksyms: Track c...
554
  		case SYM_ENUM_CONST:
78c041530   Sam Ravnborg   kbuild: Lindent g...
555
  		case SYM_TYPEDEF:
01762c4ec   Michal Marek   genksyms: simplif...
556
  			subsym = find_symbol(cur->string, cur->tag, 0);
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
557
  			/* FIXME: Bad reference files can segfault here. */
78c041530   Sam Ravnborg   kbuild: Lindent g...
558
559
560
561
562
563
564
565
  			if (subsym->expansion_trail) {
  				if (flag_dump_defs)
  					fprintf(debugfile, "%s ", cur->string);
  				crc = partial_crc32(cur->string, crc);
  				crc = partial_crc32_one(' ', crc);
  			} else {
  				subsym->expansion_trail = expansion_trail;
  				expansion_trail = subsym;
15fde6751   Andreas Gruenbacher   kbuild: support f...
566
  				crc = expand_and_crc_sym(subsym, crc);
78c041530   Sam Ravnborg   kbuild: Lindent g...
567
568
569
570
571
572
  			}
  			break;
  
  		case SYM_STRUCT:
  		case SYM_UNION:
  		case SYM_ENUM:
01762c4ec   Michal Marek   genksyms: simplif...
573
  			subsym = find_symbol(cur->string, cur->tag, 0);
78c041530   Sam Ravnborg   kbuild: Lindent g...
574
  			if (!subsym) {
68eb8563a   Michal Marek   genksyms: Add hel...
575
  				struct string_list *n;
78c041530   Sam Ravnborg   kbuild: Lindent g...
576
577
  
  				error_with_pos("expand undefined %s %s",
7ec8eda15   Michal Marek   genksyms: Simplif...
578
  					       symbol_types[cur->tag].name,
78c041530   Sam Ravnborg   kbuild: Lindent g...
579
  					       cur->string);
68eb8563a   Michal Marek   genksyms: Add hel...
580
581
582
583
584
585
  				n = concat_list(mk_node
  						(symbol_types[cur->tag].name),
  						mk_node(cur->string),
  						mk_node("{"),
  						mk_node("UNKNOWN"),
  						mk_node("}"), NULL);
78c041530   Sam Ravnborg   kbuild: Lindent g...
586
587
588
589
590
591
  				subsym =
  				    add_symbol(cur->string, cur->tag, n, 0);
  			}
  			if (subsym->expansion_trail) {
  				if (flag_dump_defs) {
  					fprintf(debugfile, "%s %s ",
7ec8eda15   Michal Marek   genksyms: Simplif...
592
  						symbol_types[cur->tag].name,
78c041530   Sam Ravnborg   kbuild: Lindent g...
593
594
  						cur->string);
  				}
7ec8eda15   Michal Marek   genksyms: Simplif...
595
  				crc = partial_crc32(symbol_types[cur->tag].name,
ce5606869   Sam Ravnborg   kbuild: clean-up ...
596
  						    crc);
78c041530   Sam Ravnborg   kbuild: Lindent g...
597
598
599
600
601
602
  				crc = partial_crc32_one(' ', crc);
  				crc = partial_crc32(cur->string, crc);
  				crc = partial_crc32_one(' ', crc);
  			} else {
  				subsym->expansion_trail = expansion_trail;
  				expansion_trail = subsym;
15fde6751   Andreas Gruenbacher   kbuild: support f...
603
  				crc = expand_and_crc_sym(subsym, crc);
78c041530   Sam Ravnborg   kbuild: Lindent g...
604
605
  			}
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
606
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
607
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
608

15fde6751   Andreas Gruenbacher   kbuild: support f...
609
610
611
612
613
614
615
616
617
  	{
  		static struct symbol **end = &visited_symbols;
  
  		if (!sym->visited) {
  			*end = sym;
  			end = &sym->visited;
  			sym->visited = (struct symbol *)-1L;
  		}
  	}
78c041530   Sam Ravnborg   kbuild: Lindent g...
618
  	return crc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
619
  }
78c041530   Sam Ravnborg   kbuild: Lindent g...
620
  void export_symbol(const char *name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
621
  {
78c041530   Sam Ravnborg   kbuild: Lindent g...
622
  	struct symbol *sym;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
623

01762c4ec   Michal Marek   genksyms: simplif...
624
  	sym = find_symbol(name, SYM_NORMAL, 0);
78c041530   Sam Ravnborg   kbuild: Lindent g...
625
626
627
628
  	if (!sym)
  		error_with_pos("export undefined symbol %s", name);
  	else {
  		unsigned long crc;
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
629
  		int has_changed = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
630

78c041530   Sam Ravnborg   kbuild: Lindent g...
631
632
  		if (flag_dump_defs)
  			fprintf(debugfile, "Export %s == <", name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
633

78c041530   Sam Ravnborg   kbuild: Lindent g...
634
  		expansion_trail = (struct symbol *)-1L;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
635

64e6c1e12   Andreas Gruenbacher   genksyms: track s...
636
637
  		sym->expansion_trail = expansion_trail;
  		expansion_trail = sym;
15fde6751   Andreas Gruenbacher   kbuild: support f...
638
  		crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
639

78c041530   Sam Ravnborg   kbuild: Lindent g...
640
641
642
  		sym = expansion_trail;
  		while (sym != (struct symbol *)-1L) {
  			struct symbol *n = sym->expansion_trail;
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
  
  			if (sym->status != STATUS_UNCHANGED) {
  				if (!has_changed) {
  					print_location();
  					fprintf(stderr, "%s: %s: modversion "
  						"changed because of changes "
  						"in ", flag_preserve ? "error" :
  						       "warning", name);
  				} else
  					fprintf(stderr, ", ");
  				print_type_name(sym->type, sym->name);
  				if (sym->status == STATUS_DEFINED)
  					fprintf(stderr, " (became defined)");
  				has_changed = 1;
  				if (flag_preserve)
  					errors++;
  			}
78c041530   Sam Ravnborg   kbuild: Lindent g...
660
661
662
  			sym->expansion_trail = 0;
  			sym = n;
  		}
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
663
664
665
  		if (has_changed)
  			fprintf(stderr, "
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
666

78c041530   Sam Ravnborg   kbuild: Lindent g...
667
668
669
  		if (flag_dump_defs)
  			fputs(">
  ", debugfile);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
670

2ea038917   Sam Ravnborg   Revert "kbuild: s...
671
672
673
  		/* Used as a linker script. */
  		printf("%s__crc_%s = 0x%08lx ;
  ", mod_prefix, name, crc);
78c041530   Sam Ravnborg   kbuild: Lindent g...
674
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
675
676
677
  }
  
  /*----------------------------------------------------------------------*/
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
678
679
680
681
682
683
684
685
  
  static void print_location(void)
  {
  	fprintf(stderr, "%s:%d: ", cur_filename ? : "<stdin>", cur_line);
  }
  
  static void print_type_name(enum symbol_type type, const char *name)
  {
7ec8eda15   Michal Marek   genksyms: Simplif...
686
687
  	if (symbol_types[type].name)
  		fprintf(stderr, "%s %s", symbol_types[type].name, name);
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
688
689
690
  	else
  		fprintf(stderr, "%s", name);
  }
78c041530   Sam Ravnborg   kbuild: Lindent g...
691
  void error_with_pos(const char *fmt, ...)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
692
  {
78c041530   Sam Ravnborg   kbuild: Lindent g...
693
  	va_list args;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
694

78c041530   Sam Ravnborg   kbuild: Lindent g...
695
  	if (flag_warnings) {
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
696
  		print_location();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
697

78c041530   Sam Ravnborg   kbuild: Lindent g...
698
699
700
701
702
  		va_start(args, fmt);
  		vfprintf(stderr, fmt, args);
  		va_end(args);
  		putc('
  ', stderr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
703

78c041530   Sam Ravnborg   kbuild: Lindent g...
704
705
  		errors++;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
706
  }
ce5606869   Sam Ravnborg   kbuild: clean-up ...
707
  static void genksyms_usage(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
708
  {
2ea038917   Sam Ravnborg   Revert "kbuild: s...
709
710
711
712
  	fputs("Usage:
  " "genksyms [-adDTwqhV] > /path/to/.tmp_obj.ver
  " "
  "
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
713
  #ifdef __GNU_LIBRARY__
36091fd34   Mike Frysinger   kbuild: fixup gen...
714
715
  	      "  -a, --arch            Select architecture
  "
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
716
717
718
719
  	      "  -d, --debug           Increment the debug level (repeatable)
  "
  	      "  -D, --dump            Dump expanded symbol defs (for debugging only)
  "
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
720
721
722
723
724
725
  	      "  -r, --reference file  Read reference symbols from a file
  "
  	      "  -T, --dump-types file Dump expanded types into file
  "
  	      "  -p, --preserve        Preserve reference modversions or fail
  "
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
726
727
728
729
730
731
732
733
  	      "  -w, --warnings        Enable warnings
  "
  	      "  -q, --quiet           Disable warnings (default)
  "
  	      "  -h, --help            Print this message
  "
  	      "  -V, --version         Print the release version
  "
78c041530   Sam Ravnborg   kbuild: Lindent g...
734
  #else				/* __GNU_LIBRARY__ */
36091fd34   Mike Frysinger   kbuild: fixup gen...
735
736
  	      "  -a                    Select architecture
  "
78c041530   Sam Ravnborg   kbuild: Lindent g...
737
738
739
740
  	      "  -d                    Increment the debug level (repeatable)
  "
  	      "  -D                    Dump expanded symbol defs (for debugging only)
  "
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
741
742
743
744
745
746
  	      "  -r file               Read reference symbols from a file
  "
  	      "  -T file               Dump expanded types into file
  "
  	      "  -p                    Preserve reference modversions or fail
  "
78c041530   Sam Ravnborg   kbuild: Lindent g...
747
748
749
750
751
752
753
754
755
  	      "  -w                    Enable warnings
  "
  	      "  -q                    Disable warnings (default)
  "
  	      "  -h                    Print this message
  "
  	      "  -V                    Print the release version
  "
  #endif				/* __GNU_LIBRARY__ */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
756
757
  	      , stderr);
  }
78c041530   Sam Ravnborg   kbuild: Lindent g...
758
  int main(int argc, char **argv)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
759
  {
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
760
  	FILE *dumpfile = NULL, *ref_file = NULL;
78c041530   Sam Ravnborg   kbuild: Lindent g...
761
  	int o;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
762
763
  
  #ifdef __GNU_LIBRARY__
78c041530   Sam Ravnborg   kbuild: Lindent g...
764
765
766
767
768
769
  	struct option long_opts[] = {
  		{"arch", 1, 0, 'a'},
  		{"debug", 0, 0, 'd'},
  		{"warnings", 0, 0, 'w'},
  		{"quiet", 0, 0, 'q'},
  		{"dump", 0, 0, 'D'},
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
770
  		{"reference", 1, 0, 'r'},
15fde6751   Andreas Gruenbacher   kbuild: support f...
771
  		{"dump-types", 1, 0, 'T'},
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
772
  		{"preserve", 0, 0, 'p'},
78c041530   Sam Ravnborg   kbuild: Lindent g...
773
774
775
776
  		{"version", 0, 0, 'V'},
  		{"help", 0, 0, 'h'},
  		{0, 0, 0, 0}
  	};
2ea038917   Sam Ravnborg   Revert "kbuild: s...
777
  	while ((o = getopt_long(argc, argv, "a:dwqVDr:T:ph",
78c041530   Sam Ravnborg   kbuild: Lindent g...
778
779
  				&long_opts[0], NULL)) != EOF)
  #else				/* __GNU_LIBRARY__ */
2ea038917   Sam Ravnborg   Revert "kbuild: s...
780
  	while ((o = getopt(argc, argv, "a:dwqVDr:T:ph")) != EOF)
78c041530   Sam Ravnborg   kbuild: Lindent g...
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
  #endif				/* __GNU_LIBRARY__ */
  		switch (o) {
  		case 'a':
  			arch = optarg;
  			break;
  		case 'd':
  			flag_debug++;
  			break;
  		case 'w':
  			flag_warnings = 1;
  			break;
  		case 'q':
  			flag_warnings = 0;
  			break;
  		case 'V':
  			fputs("genksyms version 2.5.60
  ", stderr);
  			break;
  		case 'D':
  			flag_dump_defs = 1;
  			break;
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
802
803
804
805
806
807
808
809
  		case 'r':
  			flag_reference = 1;
  			ref_file = fopen(optarg, "r");
  			if (!ref_file) {
  				perror(optarg);
  				return 1;
  			}
  			break;
15fde6751   Andreas Gruenbacher   kbuild: support f...
810
811
812
813
814
815
816
817
  		case 'T':
  			flag_dump_types = 1;
  			dumpfile = fopen(optarg, "w");
  			if (!dumpfile) {
  				perror(optarg);
  				return 1;
  			}
  			break;
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
818
819
820
  		case 'p':
  			flag_preserve = 1;
  			break;
78c041530   Sam Ravnborg   kbuild: Lindent g...
821
822
823
824
825
826
827
  		case 'h':
  			genksyms_usage();
  			return 0;
  		default:
  			genksyms_usage();
  			return 1;
  		}
f606ddf42   Adrian Bunk   remove the v850 port
828
  	if ((strcmp(arch, "h8300") == 0) || (strcmp(arch, "blackfin") == 0))
78c041530   Sam Ravnborg   kbuild: Lindent g...
829
830
831
832
833
834
835
836
837
838
839
  		mod_prefix = "_";
  	{
  		extern int yydebug;
  		extern int yy_flex_debug;
  
  		yydebug = (flag_debug > 1);
  		yy_flex_debug = (flag_debug > 2);
  
  		debugfile = stderr;
  		/* setlinebuf(debugfile); */
  	}
c64152bfd   Alexander Beregalov   genksyms: close r...
840
  	if (flag_reference) {
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
841
  		read_reference(ref_file);
c64152bfd   Alexander Beregalov   genksyms: close r...
842
843
  		fclose(ref_file);
  	}
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
844

78c041530   Sam Ravnborg   kbuild: Lindent g...
845
  	yyparse();
15fde6751   Andreas Gruenbacher   kbuild: support f...
846
847
848
  	if (flag_dump_types && visited_symbols) {
  		while (visited_symbols != (struct symbol *)-1L) {
  			struct symbol *sym = visited_symbols;
5dae9a550   Andreas Gruenbacher   genksyms: allow t...
849
850
  			if (sym->is_override)
  				fputs("override ", dumpfile);
7ec8eda15   Michal Marek   genksyms: Simplif...
851
852
  			if (symbol_types[sym->type].n) {
  				putc(symbol_types[sym->type].n, dumpfile);
15fde6751   Andreas Gruenbacher   kbuild: support f...
853
854
855
856
  				putc('#', dumpfile);
  			}
  			fputs(sym->name, dumpfile);
  			putc(' ', dumpfile);
3b40d3812   Andreas Gruenbacher   kbuild: genksyms:...
857
858
  			if (sym->is_extern)
  				fputs("extern ", dumpfile);
15fde6751   Andreas Gruenbacher   kbuild: support f...
859
860
861
862
863
864
865
866
  			print_list(dumpfile, sym->defn);
  			putc('
  ', dumpfile);
  
  			visited_symbols = sym->visited;
  			sym->visited = NULL;
  		}
  	}
78c041530   Sam Ravnborg   kbuild: Lindent g...
867
868
869
870
871
872
873
874
  	if (flag_debug) {
  		fprintf(debugfile, "Hash table occupancy %d/%d = %g
  ",
  			nsyms, HASH_BUCKETS,
  			(double)nsyms / (double)HASH_BUCKETS);
  	}
  
  	return errors != 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
875
  }