Blame view

scripts/genksyms/genksyms.c 22.5 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;
2c5925d6b   Michal Marek   genksyms: Do not ...
43
44
  char *cur_filename, *source_file;
  int in_source_file;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
45

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

7ec8eda15   Michal Marek   genksyms: Simplif...
57
58
59
60
61
62
63
64
65
  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...
66
  	[SYM_ENUM_CONST] = {'E', "enum constant"},
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
67
  };
ce5606869   Sam Ravnborg   kbuild: clean-up ...
68
69
  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...
70
71
  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...
72
73
  static void print_location(void);
  static void print_type_name(enum symbol_type type, const char *name);
ce5606869   Sam Ravnborg   kbuild: clean-up ...
74

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
75
  /*----------------------------------------------------------------------*/
78c041530   Sam Ravnborg   kbuild: Lindent g...
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
128
  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
129
  };
ce5606869   Sam Ravnborg   kbuild: clean-up ...
130
  static unsigned long partial_crc32_one(unsigned char c, unsigned long crc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
131
  {
78c041530   Sam Ravnborg   kbuild: Lindent g...
132
  	return crctab32[(crc ^ c) & 0xff] ^ (crc >> 8);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
133
  }
ce5606869   Sam Ravnborg   kbuild: clean-up ...
134
  static unsigned long partial_crc32(const char *s, unsigned long crc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
135
  {
78c041530   Sam Ravnborg   kbuild: Lindent g...
136
137
138
  	while (*s)
  		crc = partial_crc32_one(*s++, crc);
  	return crc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
139
  }
ce5606869   Sam Ravnborg   kbuild: clean-up ...
140
  static unsigned long crc32(const char *s)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
141
  {
78c041530   Sam Ravnborg   kbuild: Lindent g...
142
  	return partial_crc32(s, 0xffffffff) ^ 0xffffffff;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
143
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
144
  /*----------------------------------------------------------------------*/
ce5606869   Sam Ravnborg   kbuild: clean-up ...
145
  static enum symbol_type map_to_ns(enum symbol_type t)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
146
  {
e37ddb825   Michal Marek   genksyms: Track c...
147
148
149
150
151
152
153
154
155
156
  	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...
157
  	return t;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
158
  }
01762c4ec   Michal Marek   genksyms: simplif...
159
  struct symbol *find_symbol(const char *name, enum symbol_type ns, int exact)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
160
  {
78c041530   Sam Ravnborg   kbuild: Lindent g...
161
162
  	unsigned long h = crc32(name) % HASH_BUCKETS;
  	struct symbol *sym;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
163

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

01762c4ec   Michal Marek   genksyms: simplif...
170
171
  	if (exact && sym && sym->type != ns)
  		return NULL;
78c041530   Sam Ravnborg   kbuild: Lindent g...
172
  	return sym;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
173
  }
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
174
175
176
177
178
179
180
181
182
183
184
185
186
187
  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...
188
  static struct symbol *__add_symbol(const char *name, enum symbol_type type,
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
189
190
  			    struct string_list *defn, int is_extern,
  			    int is_reference)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
191
  {
e37ddb825   Michal Marek   genksyms: Track c...
192
  	unsigned long h;
78c041530   Sam Ravnborg   kbuild: Lindent g...
193
  	struct symbol *sym;
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
194
  	enum symbol_status status = STATUS_UNCHANGED;
e37ddb825   Michal Marek   genksyms: Track c...
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
230
  	/* 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...
231

e37ddb825   Michal Marek   genksyms: Track c...
232
  	h = crc32(name) % HASH_BUCKETS;
ce5606869   Sam Ravnborg   kbuild: clean-up ...
233
  	for (sym = symtab[h]; sym; sym = sym->hash_next) {
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
234
235
236
237
238
239
  		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...
240
241
242
243
244
245
246
  				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...
247
248
249
  				sym->is_declared = 1;
  				return sym;
  			} else if (!sym->is_declared) {
5dae9a550   Andreas Gruenbacher   genksyms: allow t...
250
251
252
253
254
255
256
257
258
259
260
261
  				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...
262
  			} else {
78c041530   Sam Ravnborg   kbuild: Lindent g...
263
  				error_with_pos("redefinition of %s", name);
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
264
265
266
  				return sym;
  			}
  			break;
78c041530   Sam Ravnborg   kbuild: Lindent g...
267
  		}
ce5606869   Sam Ravnborg   kbuild: clean-up ...
268
  	}
78c041530   Sam Ravnborg   kbuild: Lindent g...
269

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

78c041530   Sam Ravnborg   kbuild: Lindent g...
295
  	if (flag_debug) {
7ec8eda15   Michal Marek   genksyms: Simplif...
296
297
298
299
300
301
  		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...
302
303
304
305
306
307
308
309
  		if (is_extern)
  			fputs("extern ", debugfile);
  		print_list(debugfile, defn);
  		fputs(">
  ", debugfile);
  	}
  
  	++nsyms;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
310
  	return sym;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
311
  }
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
312
313
314
315
316
  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...
317
  static struct symbol *add_reference_symbol(const char *name, enum symbol_type type,
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
318
319
320
321
  				    struct string_list *defn, int is_extern)
  {
  	return __add_symbol(name, type, defn, is_extern, 1);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
322
  /*----------------------------------------------------------------------*/
ce5606869   Sam Ravnborg   kbuild: clean-up ...
323
  void free_node(struct string_list *node)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
324
  {
78c041530   Sam Ravnborg   kbuild: Lindent g...
325
326
  	free(node->string);
  	free(node);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
327
  }
78c041530   Sam Ravnborg   kbuild: Lindent g...
328
  void free_list(struct string_list *s, struct string_list *e)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
329
  {
78c041530   Sam Ravnborg   kbuild: Lindent g...
330
331
332
333
334
  	while (s != e) {
  		struct string_list *next = s->next;
  		free_node(s);
  		s = next;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
335
  }
68eb8563a   Michal Marek   genksyms: Add hel...
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
363
  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 ...
364
  struct string_list *copy_node(struct string_list *node)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
365
  {
78c041530   Sam Ravnborg   kbuild: Lindent g...
366
  	struct string_list *newnode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
367

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

78c041530   Sam Ravnborg   kbuild: Lindent g...
372
  	return newnode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
373
  }
e37ddb825   Michal Marek   genksyms: Track c...
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
  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 ...
389
  static int equal_list(struct string_list *a, struct string_list *b)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
390
  {
78c041530   Sam Ravnborg   kbuild: Lindent g...
391
392
393
394
395
396
  	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
397

78c041530   Sam Ravnborg   kbuild: Lindent g...
398
  	return !a && !b;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
399
  }
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
400
  #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
b7ed698cc   Ladinu Chandrasinghe   Documentation/: f...
401
  static struct string_list *read_node(FILE *f)
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
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] == '#') {
1ae14703e   Jesper Juhl   genksyms: Use sam...
434
  		size_t n;
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
435

7ec8eda15   Michal Marek   genksyms: Simplif...
436
437
  		for (n = 0; n < ARRAY_SIZE(symbol_types); n++) {
  			if (node.string[0] == symbol_types[n].n) {
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
  				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...
455
456
  		int is_extern = 0, is_override = 0;
  		struct symbol *subsym;
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
457
458
  
  		sym = read_node(f);
5dae9a550   Andreas Gruenbacher   genksyms: allow t...
459
460
461
462
463
464
  		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...
465
466
467
468
469
470
471
472
473
474
475
476
477
478
  		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...
479
  		subsym = add_reference_symbol(xstrdup(sym->string), sym->tag,
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
480
  					      defn, is_extern);
5dae9a550   Andreas Gruenbacher   genksyms: allow t...
481
  		subsym->is_override = is_override;
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
482
483
484
  		free_node(sym);
  	}
  }
ce5606869   Sam Ravnborg   kbuild: clean-up ...
485
  static void print_node(FILE * f, struct string_list *list)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
486
  {
7ec8eda15   Michal Marek   genksyms: Simplif...
487
488
  	if (symbol_types[list->tag].n) {
  		putc(symbol_types[list->tag].n, f);
78c041530   Sam Ravnborg   kbuild: Lindent g...
489
  		putc('#', f);
78c041530   Sam Ravnborg   kbuild: Lindent g...
490
  	}
15fde6751   Andreas Gruenbacher   kbuild: support f...
491
  	fputs(list->string, f);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
492
  }
ce5606869   Sam Ravnborg   kbuild: clean-up ...
493
  static void print_list(FILE * f, struct string_list *list)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
494
  {
78c041530   Sam Ravnborg   kbuild: Lindent g...
495
496
497
  	struct string_list **e, **b;
  	struct string_list *tmp, **tmp2;
  	int elem = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
498

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

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

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

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

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

15fde6751   Andreas Gruenbacher   kbuild: support f...
522
  static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc)
78c041530   Sam Ravnborg   kbuild: Lindent g...
523
  {
15fde6751   Andreas Gruenbacher   kbuild: support f...
524
  	struct string_list *list = sym->defn;
78c041530   Sam Ravnborg   kbuild: Lindent g...
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
554
555
  	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...
556
  		case SYM_ENUM_CONST:
78c041530   Sam Ravnborg   kbuild: Lindent g...
557
  		case SYM_TYPEDEF:
01762c4ec   Michal Marek   genksyms: simplif...
558
  			subsym = find_symbol(cur->string, cur->tag, 0);
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
559
  			/* FIXME: Bad reference files can segfault here. */
78c041530   Sam Ravnborg   kbuild: Lindent g...
560
561
562
563
564
565
566
567
  			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...
568
  				crc = expand_and_crc_sym(subsym, crc);
78c041530   Sam Ravnborg   kbuild: Lindent g...
569
570
571
572
573
574
  			}
  			break;
  
  		case SYM_STRUCT:
  		case SYM_UNION:
  		case SYM_ENUM:
01762c4ec   Michal Marek   genksyms: simplif...
575
  			subsym = find_symbol(cur->string, cur->tag, 0);
78c041530   Sam Ravnborg   kbuild: Lindent g...
576
  			if (!subsym) {
68eb8563a   Michal Marek   genksyms: Add hel...
577
  				struct string_list *n;
78c041530   Sam Ravnborg   kbuild: Lindent g...
578
579
  
  				error_with_pos("expand undefined %s %s",
7ec8eda15   Michal Marek   genksyms: Simplif...
580
  					       symbol_types[cur->tag].name,
78c041530   Sam Ravnborg   kbuild: Lindent g...
581
  					       cur->string);
68eb8563a   Michal Marek   genksyms: Add hel...
582
583
584
585
586
587
  				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...
588
589
590
591
592
593
  				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...
594
  						symbol_types[cur->tag].name,
78c041530   Sam Ravnborg   kbuild: Lindent g...
595
596
  						cur->string);
  				}
7ec8eda15   Michal Marek   genksyms: Simplif...
597
  				crc = partial_crc32(symbol_types[cur->tag].name,
ce5606869   Sam Ravnborg   kbuild: clean-up ...
598
  						    crc);
78c041530   Sam Ravnborg   kbuild: Lindent g...
599
600
601
602
603
604
  				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...
605
  				crc = expand_and_crc_sym(subsym, crc);
78c041530   Sam Ravnborg   kbuild: Lindent g...
606
607
  			}
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
608
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
609
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
610

15fde6751   Andreas Gruenbacher   kbuild: support f...
611
612
613
614
615
616
617
618
619
  	{
  		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...
620
  	return crc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
621
  }
78c041530   Sam Ravnborg   kbuild: Lindent g...
622
  void export_symbol(const char *name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
623
  {
78c041530   Sam Ravnborg   kbuild: Lindent g...
624
  	struct symbol *sym;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
625

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

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

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

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

78c041530   Sam Ravnborg   kbuild: Lindent g...
642
643
644
  		sym = expansion_trail;
  		while (sym != (struct symbol *)-1L) {
  			struct symbol *n = sym->expansion_trail;
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
  
  			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...
662
663
664
  			sym->expansion_trail = 0;
  			sym = n;
  		}
64e6c1e12   Andreas Gruenbacher   genksyms: track s...
665
666
667
  		if (has_changed)
  			fprintf(stderr, "
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
668

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

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

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

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

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

78c041530   Sam Ravnborg   kbuild: Lindent g...
847
  	yyparse();
15fde6751   Andreas Gruenbacher   kbuild: support f...
848
849
850
  	if (flag_dump_types && visited_symbols) {
  		while (visited_symbols != (struct symbol *)-1L) {
  			struct symbol *sym = visited_symbols;
5dae9a550   Andreas Gruenbacher   genksyms: allow t...
851
852
  			if (sym->is_override)
  				fputs("override ", dumpfile);
7ec8eda15   Michal Marek   genksyms: Simplif...
853
854
  			if (symbol_types[sym->type].n) {
  				putc(symbol_types[sym->type].n, dumpfile);
15fde6751   Andreas Gruenbacher   kbuild: support f...
855
856
857
858
  				putc('#', dumpfile);
  			}
  			fputs(sym->name, dumpfile);
  			putc(' ', dumpfile);
3b40d3812   Andreas Gruenbacher   kbuild: genksyms:...
859
860
  			if (sym->is_extern)
  				fputs("extern ", dumpfile);
15fde6751   Andreas Gruenbacher   kbuild: support f...
861
862
863
864
865
866
867
868
  			print_list(dumpfile, sym->defn);
  			putc('
  ', dumpfile);
  
  			visited_symbols = sym->visited;
  			sym->visited = NULL;
  		}
  	}
78c041530   Sam Ravnborg   kbuild: Lindent g...
869
870
871
872
873
874
875
876
  	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
877
  }