~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/tools/winedump/main.c

Version: ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~ [ wine-1.0-rc5 ] ~ [ wine-1.0-rc4 ] ~ [ wine-1.0-rc3 ] ~ [ wine-1.0-rc2 ] ~ [ wine-1.0-rc1 ] ~ [ wine-0.9.61 ] ~ [ wine-0.9.60 ] ~ [ wine-0.9.59 ] ~ [ wine-0.9.58 ] ~ [ wine-0.9.57 ] ~ [ wine-0.9.56 ] ~ [ wine-0.9.55 ] ~ [ wine-0.9.54 ] ~ [ wine-0.9.53 ] ~ [ wine-0.9.52 ] ~ [ wine-0.9.51 ] ~ [ wine-0.9.50 ] ~ [ wine-0.9.49 ] ~ [ wine-0.9.48 ] ~ [ wine-0.9.47 ] ~ [ wine-0.9.46 ] ~ [ wine-0.9.45 ] ~ [ wine-0.9.44 ] ~ [ wine-0.9.43 ] ~ [ wine-0.9.42 ] ~ [ wine-0.9.41 ] ~ [ wine-0.9.40 ] ~ [ wine-0.9.39 ] ~ [ wine-0.9.38 ] ~ [ wine-0.9.37 ] ~ [ wine-0.9.36 ] ~ [ wine-0.9.35 ] ~ [ wine-0.9.34 ] ~ [ wine-0.9.33 ] ~ [ wine-0.9.32 ] ~ [ wine-0.9.31 ] ~ [ wine-0.9.30 ] ~ [ wine-0.9.29 ] ~ [ wine-0.9.28 ] ~ [ wine-0.9.27 ] ~ [ wine-0.9.26 ] ~ [ wine-0.9.25 ] ~ [ wine-0.9.24 ] ~ [ wine-0.9.23 ] ~ [ wine-0.9.22 ] ~ [ wine-0.9.21 ] ~ [ wine-0.9.20 ] ~ [ wine-0.9.19 ] ~ [ wine-0.9.18 ] ~ [ wine-0.9.17 ] ~ [ wine-0.9.16 ] ~ [ wine-0.9.15 ] ~ [ wine-0.9.14 ] ~ [ wine-0.9.13 ] ~ [ wine-0.9.12 ] ~ [ wine-0.9.11 ] ~ [ wine-0.9.10 ] ~ [ wine-0.9.9 ] ~ [ wine-0.9.8 ] ~ [ wine-0.9.7 ] ~ [ wine-0.9.6 ] ~ [ wine-0.9.5 ] ~ [ wine-0.9.4 ] ~ [ wine-0.9.3 ] ~ [ wine-0.9.2 ] ~ [ wine-0.9.1 ] ~ [ wine-0.9 ] ~ [ wine20050930 ] ~ [ wine20050830 ] ~ [ wine20050725 ] ~ [ wine20050628 ] ~ [ wine20050524 ] ~ [ wine20050419 ] ~ [ wine20050310 ] ~ [ wine20050211 ] ~ [ wine20050111 ] ~ [ wine20041201 ] ~ [ wine20041019 ] ~ [ wine20040914 ] ~ [ wine20040813 ] ~ [ wine20040716 ] ~ [ wine20040615 ] ~ [ wine20040505 ] ~ [ wine20040408 ] ~ [ wine20040309 ] ~ [ wine20040213 ] ~ [ wine20040121 ] ~ [ wine20031212 ] ~ [ wine20031118 ] ~ [ wine20031016 ] ~ [ wine20030911 ] ~ [ wine20030813 ] ~ [ wine20030709 ] ~ [ wine20030618 ] ~ [ wine20030508 ] ~ [ wine20030408 ] ~ [ wine20030318 ] ~ [ wine20030219 ] ~ [ wine20030115 ] ~ [ wine20021219 ] ~ [ wine20021125 ] ~ [ wine20021031 ] ~ [ wine20021007 ] ~ [ wine20020904 ] ~ [ wine20020804 ] ~ [ wine20020710 ] ~ [ wine20020605 ] ~ [ wine20020509 ] ~ [ wine20020411 ] ~ [ wine20020310 ] ~ [ wine20020228 ] ~ [ wine20011226 ] ~ [ wine20011108 ] ~ [ wine20011004 ] ~ [ wine20010824 ] ~ [ wine20010731 ] ~ [ wine20010629 ] ~ [ wine20010510 ] ~ [ wine20010418 ] ~ [ wine20010326 ] ~ [ wine20010305 ] ~ [ wine20010216 ] ~ [ wine20010112 ] ~ [ wine20001222 ] ~ [ wine20001202 ] ~ [ wine20001026 ] ~ [ wine20001002 ] ~ [ wine20000909 ] ~ [ wine20000821 ] ~ [ wine20000801 ] ~ [ wine20000716 ] ~ [ wine20000326 ] ~ [ wine20000227 ] ~ [ wine20000130 ] ~ [ wine20000109 ] ~

  1 /*
  2  *  Option processing and main()
  3  *
  4  *  Copyright 2000 Jon Griffiths
  5  *
  6  * This library is free software; you can redistribute it and/or
  7  * modify it under the terms of the GNU Lesser General Public
  8  * License as published by the Free Software Foundation; either
  9  * version 2.1 of the License, or (at your option) any later version.
 10  *
 11  * This library is distributed in the hope that it will be useful,
 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 14  * Lesser General Public License for more details.
 15  *
 16  * You should have received a copy of the GNU Lesser General Public
 17  * License along with this library; if not, write to the Free Software
 18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 19  */
 20 
 21 #include "config.h"
 22 #include "wine/port.h"
 23 
 24 #include "winedump.h"
 25 
 26 _globals globals; /* All global variables */
 27 
 28 
 29 static void do_include (const char *arg)
 30 {
 31   char *newIncludes;
 32 
 33   if (!globals.directory)
 34     globals.directory = strdup(arg);
 35   else {
 36     newIncludes = str_create (3,globals.directory," ",arg);
 37     free(globals.directory);
 38     globals.directory = newIncludes;
 39   }
 40   globals.do_code = 1;
 41 }
 42 
 43 
 44 static inline const char* strip_ext (const char *str)
 45 {
 46   int len = strlen(str);
 47   if (len>4 && strcmp(str+len-4,".dll") == 0)
 48     return str_substring (str, str+len-4);
 49   else
 50     return strdup (str);
 51 }
 52 
 53 
 54 static void do_name (const char *arg)
 55 {
 56   globals.dll_name = strip_ext (arg);
 57 }
 58 
 59 
 60 static void do_spec (const char *arg)
 61 {
 62     if (globals.mode != NONE) fatal("Only one mode can be specified\n");
 63     globals.mode = SPEC;
 64 }
 65 
 66 
 67 static void do_demangle (const char *arg)
 68 {
 69     if (globals.mode != NONE) fatal("Only one mode can be specified\n");
 70     globals.mode = DMGL;
 71     globals.do_code = 1;
 72 }
 73 
 74 
 75 static void do_dump (const char *arg)
 76 {
 77     if (globals.mode != NONE) fatal("Only one mode can be specified\n");
 78     globals.mode = DUMP;
 79     globals.do_code = 1;
 80 }
 81 
 82 
 83 static void do_code (void)
 84 {
 85   globals.do_code = 1;
 86 }
 87 
 88 
 89 static void do_trace (void)
 90 {
 91   globals.do_trace = 1;
 92   globals.do_code = 1;
 93 }
 94 
 95 
 96 static void do_forward (const char *arg)
 97 {
 98   globals.forward_dll = arg;
 99   globals.do_trace = 1;
100   globals.do_code = 1;
101 }
102 
103 static void do_document (void)
104 {
105   globals.do_documentation = 1;
106 }
107 
108 static void do_cdecl (void)
109 {
110   globals.do_cdecl = 1;
111 }
112 
113 
114 static void do_quiet (void)
115 {
116   globals.do_quiet = 1;
117 }
118 
119 
120 static void do_start (const char *arg)
121 {
122   globals.start_ordinal = atoi (arg);
123   if (!globals.start_ordinal)
124     fatal ("Invalid -s option (must be numeric)");
125 }
126 
127 
128 static void do_end (const char *arg)
129 {
130   globals.end_ordinal = atoi (arg);
131   if (!globals.end_ordinal)
132     fatal ("Invalid -e option (must be numeric)");
133 }
134 
135 
136 static void do_symfile (const char *arg)
137 {
138   FILE *f;
139   char symstring[256];    /* keep count with "%<width>s" below */
140   search_symbol *symbolp,**symbolptail = &globals.search_symbol;
141 
142   if (!(f = fopen(arg, "rt")))
143     fatal ("Cannot open <symfile>");
144   while (1 == fscanf(f, "%255s", symstring))    /* keep count with [<width>] above */
145   {
146     symstring[sizeof(symstring)-1] = '\0';
147     if (!(symbolp = malloc(sizeof(*symbolp) + strlen(symstring))))
148       fatal ("Out of memory");
149     strcpy(symbolp->symbolname, symstring);
150     symbolp->found = 0;
151     symbolp->next = NULL;
152     *symbolptail = symbolp;
153     symbolptail = &symbolp->next;
154   }
155   if (fclose(f))
156     fatal ("Cannot close <symfile>");
157 }
158 
159 
160 static void do_verbose (void)
161 {
162   globals.do_verbose = 1;
163 }
164 
165 
166 static void do_symdmngl (void)
167 {
168     globals.do_demangle = 1;
169 }
170 
171 static void do_dumphead (void)
172 {
173     globals.do_dumpheader = 1;
174 }
175 
176 static void do_dumpsect (const char* arg)
177 {
178     globals.dumpsect = arg;
179 }
180 
181 static void do_rawdebug (void)
182 {
183     globals.do_debug = 1;
184 }
185 
186 static void do_dumpall(void)
187 {
188     globals.do_dumpheader = 1;
189     globals.do_dump_rawdata = 1;
190     globals.dumpsect = "ALL";
191 }
192 
193 struct my_option
194 {
195   const char *name;
196   Mode mode;
197   int   has_arg;
198   void  (*func) ();
199   const char *usage;
200 };
201 
202 static const struct my_option option_table[] = {
203   {"--help",NONE, 0, do_usage,    "--help       Display this help message"},
204   {"-h",    NONE, 0, do_usage,    "-h           Synonym for --help"},
205   {"-?",    NONE, 0, do_usage,    "-?           Synonym for --help"},
206   {"sym",   DMGL, 0, do_demangle, "sym <sym>    Demangle C++ symbol <sym> and exit"},
207   {"spec",  SPEC, 0, do_spec,     "spec <dll>   Use dll for input file and generate implementation code"},
208   {"-I",    SPEC, 1, do_include,  "-I dir       Look for prototypes in 'dir' (implies -c)"},
209   {"-c",    SPEC, 0, do_code,     "-c           Generate skeleton code (requires -I)"},
210   {"-t",    SPEC, 0, do_trace,    "-t           TRACE arguments (implies -c)"},
211   {"-f",    SPEC, 1, do_forward,  "-f dll       Forward calls to 'dll' (implies -t)"},
212   {"-D",    SPEC, 0, do_document, "-D           Generate documentation"},
213   {"-o",    SPEC, 1, do_name,     "-o name      Set the output dll name (default: dll). note: strips .dll extensions"},
214   {"-C",    SPEC, 0, do_cdecl,    "-C           Assume __cdecl calls (default: __stdcall)"},
215   {"-s",    SPEC, 1, do_start,    "-s num       Start prototype search after symbol 'num'"},
216   {"-e",    SPEC, 1, do_end,      "-e num       End prototype search after symbol 'num'"},
217   {"-S",    SPEC, 1, do_symfile,  "-S symfile   Search only prototype names found in 'symfile'"},
218   {"-q",    SPEC, 0, do_quiet,    "-q           Don't show progress (quiet)."},
219   {"-v",    SPEC, 0, do_verbose,  "-v           Show lots of detail while working (verbose)."},
220   {"dump",  DUMP, 0, do_dump,     "dump <file>  Dumps the contents of a file (dll, exe, lib...)"},
221   {"-C",    DUMP, 0, do_symdmngl, "-C           Turns on symbol demangling"},
222   {"-f",    DUMP, 0, do_dumphead, "-f           Dumps file header information"},
223   {"-G",    DUMP, 0, do_rawdebug, "-G           Dumps raw debug information"},
224   {"-j",    DUMP, 1, do_dumpsect, "-j sect_name Dumps only the content of section sect_name (import, export, debug, resource, tls, clr)"},
225   {"-x",    DUMP, 0, do_dumpall,  "-x           Dumps everything"},
226   {NULL,    NONE, 0, NULL,        NULL}
227 };
228 
229 void do_usage (void)
230 {
231     const struct my_option *opt;
232     printf ("Usage: winedump [-h | sym <sym> | spec <dll> | dump <file>]\n");
233     printf ("Mode options (can be put as the mode (sym/spec/dump...) is declared):\n");
234     printf ("\tWhen used in --help mode\n");
235     for (opt = option_table; opt->name; opt++)
236         if (opt->mode == NONE)
237             printf ("\t   %s\n", opt->usage);
238     printf ("\tWhen used in sym mode\n");
239     for (opt = option_table; opt->name; opt++)
240         if (opt->mode == DMGL)
241             printf ("\t   %s\n", opt->usage);
242     printf ("\tWhen used in spec mode\n");
243     for (opt = option_table; opt->name; opt++)
244         if (opt->mode == SPEC)
245             printf ("\t   %s\n", opt->usage);
246     printf ("\tWhen used in dump mode\n");
247     for (opt = option_table; opt->name; opt++)
248         if (opt->mode == DUMP)
249             printf ("\t   %s\n", opt->usage);
250 
251     puts ("");
252     exit (1);
253 }
254 
255 
256 /*******************************************************************
257  *          parse_options
258  *
259  * Parse options from the argv array
260  */
261 static void parse_options (char *argv[])
262 {
263   const struct my_option *opt;
264   char *const *ptr;
265   const char *arg = NULL;
266 
267   ptr = argv + 1;
268 
269   while (*ptr != NULL)
270   {
271     for (opt = option_table; opt->name; opt++)
272     {
273      if (globals.mode != NONE && opt->mode != NONE && globals.mode != opt->mode)
274        continue;
275      if (((opt->has_arg == 1) && !strncmp (*ptr, opt->name, strlen (opt->name))) ||
276          ((opt->has_arg == 2) && !strcmp (*ptr, opt->name)))
277       {
278         arg = *ptr + strlen (opt->name);
279         if (*arg == '\0') arg = *++ptr;
280         break;
281       }
282       if (!strcmp (*ptr, opt->name))
283       {
284         arg = NULL;
285         break;
286       }
287     }
288 
289     if (!opt->name)
290     {
291         if ((*ptr)[0] == '-')
292             fatal ("Unrecognized option");
293         if (globals.input_name != NULL)
294             fatal ("Only one file can be treated at once");
295         globals.input_name = *ptr;
296     }
297     else if (opt->has_arg && arg != NULL)
298         opt->func (arg);
299     else
300         opt->func ("");
301 
302     ptr++;
303   }
304 
305   if (globals.mode == SPEC && globals.do_code && !globals.directory)
306     fatal ("-I must be used if generating code");
307 
308   if (VERBOSE && QUIET)
309     fatal ("Options -v and -q are mutually exclusive");
310 
311   if (globals.mode == NONE)
312       do_dump("");
313 }
314 
315 static void set_module_name(unsigned setUC)
316 {
317     const char* ptr;
318     char*       buf;
319     int         len;
320 
321     /* FIXME: we shouldn't assume all module extensions are .dll in winedump
322      * in some cases, we could have some .drv for example
323      */
324     /* get module name from name */
325     if ((ptr = strrchr (globals.input_name, '/')))
326         ptr++;
327     else
328         ptr = globals.input_name;
329     len = strlen(ptr);
330     if (len > 4 && strcmp(ptr + len - 4, ".dll") == 0)
331         len -= 4;
332     buf = malloc(len + 1);
333     memcpy(buf, (const void*)ptr, len);
334     buf[len] = 0;
335     globals.input_module = buf;
336     OUTPUT_UC_DLL_NAME = (setUC) ? str_toupper( strdup (OUTPUT_DLL_NAME)) : "";
337 }
338 
339 /* Marks the symbol as 'found'! */
340 /* return: perform-search */
341 static int symbol_searched(int count, const char *symbolname)
342 {
343     search_symbol *search_symbol;
344 
345     if (!(count >= globals.start_ordinal
346           && (!globals.end_ordinal || count <= globals.end_ordinal)))
347         return 0;
348     if (!globals.search_symbol)
349         return 1;
350     for (search_symbol = globals.search_symbol;
351          search_symbol;
352          search_symbol = search_symbol->next)
353     {
354         if (!strcmp(symbolname, search_symbol->symbolname))
355         {
356             search_symbol->found = 1;
357             return 1;
358         }
359     }
360     return 0;
361 }
362 
363 /* return: some symbols weren't found */
364 static int symbol_finish(void)
365 {
366     const search_symbol *search_symbol;
367     int started = 0;
368 
369     for (search_symbol = globals.search_symbol;
370          search_symbol;
371          search_symbol = search_symbol->next)
372     {
373         if (search_symbol->found)
374             continue;
375         if (!started)
376         {
377             /* stderr? not a practice here */
378             puts("These requested <symfile> symbols weren't found:");
379             started = 1;
380         }
381         printf("\t%s\n",search_symbol->symbolname);
382     }
383     return started;
384 }
385 
386 /*******************************************************************
387  *         main
388  */
389 #ifdef __GNUC__
390 int   main (int argc __attribute__((unused)), char *argv[])
391 #else
392 int   main (int argc, char *argv[])
393 #endif
394 {
395     parsed_symbol symbol;
396     int count = 0;
397 
398     globals.mode = NONE;
399     globals.forward_dll = NULL;
400     globals.input_name = NULL;
401     globals.dumpsect = NULL;
402 
403     parse_options (argv);
404 
405     memset (&symbol, 0, sizeof (parsed_symbol));
406 
407     switch (globals.mode)
408     {
409     case DMGL:
410         VERBOSE = 1;
411 
412         if (globals.input_name == NULL)
413             fatal("No symbol name has been given\n");
414         printf("%s\n", get_symbol_str(globals.input_name));
415         break;
416 
417     case SPEC:
418         if (globals.input_name == NULL)
419             fatal("No file name has been given\n");
420         set_module_name(1);
421         if (!dll_open (globals.input_name))
422             break;
423 
424         output_spec_preamble ();
425         output_header_preamble ();
426         output_c_preamble ();
427 
428         while (!dll_next_symbol (&symbol))
429         {
430             count++;
431 
432             if (NORMAL)
433                 printf ("Export %3d - '%s' ...%c", count, symbol.symbol,
434                         VERBOSE ? '\n' : ' ');
435 
436             if (globals.do_code && symbol_searched(count, symbol.symbol))
437             {
438                 /* Attempt to get information about the symbol */
439                 int result = symbol_demangle (&symbol);
440 
441                 if (result)
442                     result = symbol_search (&symbol);
443 
444                 if (!result && symbol.function_name)
445                     /* Clean up the prototype */
446                     symbol_clean_string (symbol.function_name);
447 
448                 if (NORMAL)
449                     puts (result ? "[Not Found]" : "[OK]");
450             }
451             else if (NORMAL)
452                 puts ("[Ignoring]");
453 
454             output_spec_symbol (&symbol);
455             output_header_symbol (&symbol);
456             output_c_symbol (&symbol);
457 
458             symbol_clear (&symbol);
459         }
460 
461         output_makefile ();
462 
463         if (VERBOSE)
464             puts ("Finished, Cleaning up...");
465         if (symbol_finish())
466             return 1;
467         break;
468     case NONE:
469         do_usage();
470         break;
471     case DUMP:
472         if (globals.input_name == NULL)
473             fatal("No file name has been given\n");
474         set_module_name(0);
475         dump_file(globals.input_name);
476         break;
477     }
478 
479     return 0;
480 }
481 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.