This source file includes following definitions.
- add_hash
- cmp_hash
- sort_hash
- hash
- process_file
- main
- load_from_file
- cut_export_token
- find_last_token
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <math.h>
5
6 #include <string.h>
7 #include <fcntl.h>
8 #include <sys/stat.h>
9
10 char* load_from_file(const char* filename);
11 void cut_export_token( char* sym );
12 char* find_last_token(char* sym );
13
14 #define MAX_SYM 2048
15
16 typedef struct
17 {
18 unsigned int hash;
19 char symbol[257];
20 int count;
21 } hash_val;
22
23 hash_val hash_vals[MAX_SYM];
24 int hash_idx = 0;
25
26 void add_hash(unsigned int val, char *sym)
27 {
28 int i;
29 for (i=0; i<hash_idx; i++)
30 {
31 if (hash_vals[i].hash == val)
32 {
33 hash_vals[i].count++;
34 fprintf(stderr,"Hash collision for 0x%08x (%s and %s)\n",val, sym, hash_vals[i].symbol);
35 exit(-3);
36 }
37 }
38
39 hash_vals[hash_idx].hash = val;
40 hash_vals[hash_idx].count = 1;
41 strcpy(hash_vals[hash_idx].symbol,sym);
42 hash_idx++;
43 }
44
45 int cmp_hash(const void *a, const void *b)
46 {
47 hash_val *ha = (hash_val*)a;
48 hash_val *hb = (hash_val*)b;
49 if (ha->hash < hb->hash) return -1;
50 else if (ha->hash > hb->hash) return 1;
51 else return 0;
52 }
53
54 void sort_hash()
55 {
56 qsort(hash_vals,hash_idx,sizeof(hash_val),cmp_hash);
57 }
58
59 unsigned int hash(unsigned char *str)
60 {
61 unsigned int hash = 5381;
62 int c;
63
64
65 while ((c = *str++) != 0)
66 hash = ((hash << 5) + hash) ^ c;
67
68 return hash;
69 }
70
71 int process_file(const char *name, FILE *out_txt)
72 {
73 char *cursym;
74
75 char *cur = load_from_file(name);
76
77 if (cur == 0)
78 {
79 printf("makeexport: file not found '%s'\n", name);
80 return 0;
81 }
82
83
84 for(;*cur; )
85 {
86 for(; *cur==9 || *cur==' '; cur++)
87 ;
88 if (*cur=='(') {
89 for(cur++; *cur && *cur!=')'; cur++);
90 for(; *cur==9 || *cur==' ' || *cur==')'; cur++);
91 }
92
93 int is_address = 0;
94 if (*cur=='&')
95 {
96 is_address = 1;
97 for(cur++; *cur==9 || *cur==' '; cur++);
98 }
99
100 cursym=cur;
101 for(; (*cur>='A' && *cur<='Z') ||
102 (*cur>='a' && *cur<='z') ||
103 (*cur>='0' && *cur<='9') ||
104 *cur=='_';
105 cur++);
106
107 if (cursym!=cur) {
108 char symbol[256], full_symbol[257];
109 int size=cur-cursym;
110
111 if ( size>255) {size=255;}
112 memcpy(symbol,cursym,size);
113 symbol[size]=0;
114 full_symbol[0] = 0;
115 if (is_address) strcpy(full_symbol,"&");
116 strcat(full_symbol,symbol);
117 cut_export_token(symbol);
118
119 unsigned int hash_val = hash((unsigned char*)symbol);
120 add_hash(hash_val,full_symbol);
121 fprintf(out_txt,"%08x %s\n",hash_val,symbol);
122 for(; size>=0; size--)
123 {
124 if ( symbol[size]>='a' && symbol[size]<='z')
125 symbol[size]-=0x20;
126 }
127 }
128
129 for(; *cur && *cur!=10; cur++);
130 for(; *cur==10; cur++);
131 }
132
133 return 1;
134 }
135
136
137
138
139
140
141
142
143 int main( int argc, char **argv )
144 {
145 if ( argc < 5 )
146 {
147 printf("#error Not enough arguments for export list maker.\n");
148 exit(-1);
149 }
150
151 FILE* out_h = fopen(argv[1],"wb");
152 FILE* out_txt = fopen(argv[2],"wb");
153 FILE* out_hash = fopen(argv[3],"wb");
154
155 if (!out_h)
156 {
157 printf("#error Error creation exportlist.h.\n");
158 exit(-1);
159 }
160 if (!out_txt)
161 {
162 printf("#error Error creation exportlist.txt.\n");
163 exit(-1);
164 }
165
166 fprintf(out_h,"//Auto generated file. Do not edit the contents of this file.\n");
167 fprintf(out_h,"//Update the modules/module_exportlist.c file\n\n");
168 fprintf(out_h,"#ifndef MODULE_EXPORTLIST_H\n");
169 fprintf(out_h,"#define MODULE_EXPORTLIST_H\n\n");
170
171
172 char* build = BUILD_NUMBER;
173 char* e;
174 int build_num=0;
175 int mult=10000;
176 for ( ; *build; build++) {
177 if ( *build<'0' || *build>'9') continue;
178 build_num += mult*strtol(build, &e, 0);
179 if ( mult==1 ) break;
180 build=e;
181 mult/=100;
182 }
183 if ( *build )
184 fprintf(out_h,"#define CHDK_BUILD_NUM %d\n\n",build_num);
185
186 if (!process_file(argv[4], out_txt)) exit(-1);
187 if (!process_file(argv[5], out_txt)) exit(-1);
188
189 int n;
190 sort_hash();
191 fprintf(out_hash,"// This is an automatically generated file. DO NOT EDIT!\n");
192 fprintf(out_hash, "\n#include \"module_hash.h\"\n\n");
193 fprintf(out_hash, "// Address references so that symbol table will compile and link.\n// Don't need correct signatures here, just the name for linking.\n");
194 for (n=0; n<hash_idx; n++)
195 {
196 if (hash_vals[n].symbol[0] == '&')
197 {
198 fprintf(out_hash,"extern int %s;\n",hash_vals[n].symbol+1);
199 }
200 else
201 {
202 fprintf(out_hash,"extern void %s(void);\n",hash_vals[n].symbol);
203 }
204 }
205 fprintf(out_hash, "\n// Symbol hash table for resolving exported symbol references\nsym_hash symbol_hash_table[] =\n{\n");
206 for (n=0; n<hash_idx; n++)
207 {
208 fprintf(out_hash,"{ 0x%08x, %s },\n",hash_vals[n].hash,hash_vals[n].symbol);
209 }
210 fprintf(out_hash, "};\n");
211
212 if (hash_idx>=1)
213 fprintf(out_h,"#define EXPORTLIST_COUNT %d\n\n",hash_idx);
214 else {
215 fprintf(out_h,"#error Malformed export list. Only %d valid records\n\n",hash_idx);
216 exit(-2);
217 }
218 fprintf(out_h,"#endif\n");
219
220 fclose(out_h);
221 fclose(out_txt);
222 fclose(out_hash);
223
224 return 0;
225 }
226
227
228
229 char* load_from_file(const char *filename)
230 {
231 int f, size;
232 static struct stat st;
233 char *buf = 0;
234
235 f = open(filename, O_RDONLY, 0777);
236 if (f>=0) {
237 size = (stat((char*)filename, &st)==0)?st.st_size:0;
238 if (size) {
239 buf = (char*)malloc(size+1);
240 if (buf) {
241 size = read(f, buf, size);
242 buf[size]=0;
243 }
244 }
245 close(f);
246 }
247 return buf;
248 }
249
250 void cut_export_token( char* sym )
251 {
252 const char* token="_EXPORTEDSYM_";
253 int sizetoken = strlen(token);
254 char* src, *fin;
255
256 fin=sym+strlen(sym)-sizetoken;
257 for(;sym<=fin;sym++) {
258 if (!memcmp(sym,token,sizetoken)) {
259 for (src=sym+strlen(token); *src; src++,sym++)
260 *sym=*src;
261 *sym=0;
262 return;
263 }
264 }
265 }
266
267 char* find_last_token(char* sym )
268 {
269 char* token=sym;
270
271 for (;*sym;sym++)
272 {
273 if ( *sym==' ' && sym[1]>' ')
274 token=sym+1;
275 }
276 return token;
277 }