ksymoops.c
上传用户:hxtd_72
上传日期:2007-06-06
资源大小:64k
文件大小:20k
源码类别:

驱动编程

开发平台:

C/C++

  1. /*
  2.     ksymoops.c.
  3.     Read a Linux kernel Oops file and make the best stab at converting
  4.     the code to instructions and mapping stack values to kernel
  5.     symbols.
  6.     Copyright 1999 Keith Owens <kaos@ocs.com.au>.
  7.     Released under the GNU Public Licence, Version 2.
  8. */
  9. #define VERSION "2.4.9"
  10. #include "ksymoops.h"
  11. #include <ctype.h>
  12. #include <errno.h>
  13. #include <getopt.h>
  14. #include <malloc.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <unistd.h>
  18. #include <sys/utsname.h>
  19. #include <endian.h>
  20. char *prefix;
  21. char *path_nm = INSTALL_PREFIX"/bin/"CROSS"nm";          /* env KSYMOOPS_NM */
  22. char *path_find = "/usr/bin/find";      /* env KSYMOOPS_FIND */
  23. char *path_objdump = INSTALL_PREFIX"/bin/"CROSS"objdump";    /* env KSYMOOPS_OBJDUMP */
  24. int debug = 0;
  25. int errors = 0;
  26. int warnings = 0;
  27. addr_t truncate_mask = ~(addr_t)0;
  28. SYMBOL_SET   ss_vmlinux;
  29. SYMBOL_SET   ss_ksyms_base;
  30. SYMBOL_SET **ss_ksyms_module;
  31. int          ss_ksyms_modules;
  32. int          ss_ksyms_modules_known_objects;
  33. SYMBOL_SET   ss_lsmod;
  34. SYMBOL_SET **ss_object;
  35. int          ss_objects;
  36. SYMBOL_SET   ss_system_map;
  37. SYMBOL_SET   ss_merged;   /* merged map with info from all sources */
  38. SYMBOL_SET   ss_Version;  /* Version_ numbers where available */
  39. /* Regular expression stuff */
  40. regex_t     re_nm;
  41. regmatch_t *re_nm_pmatch;
  42. regex_t     re_bracketed_address;
  43. regmatch_t *re_bracketed_address_pmatch;
  44. regex_t     re_revbracketed_address;
  45. regmatch_t *re_revbracketed_address_pmatch;
  46. regex_t     re_unbracketed_address;
  47. regmatch_t *re_unbracketed_address_pmatch;
  48. static void usage(void)
  49. {
  50.     static const char usage_text[] =
  51.    "t[-v vmlinux] [--vmlinux=vmlinux]ntttttWhere to read vmlinuxn"
  52.    "t[-V] [--no-vmlinux]ttNo vmlinux is availablen"
  53.    "t[-k ksyms] [--ksyms=ksyms]tWhere to read ksymsn"
  54.    "t[-K] [--no-ksyms]ttNo ksyms is availablen"
  55.    "t[-l lsmod] [--lsmod=lsmod]tWhere to read lsmodn"
  56.    "t[-L] [--no-lsmod]ttNo lsmod is availablen"
  57.    "t[-o object] [--object=object]tDirectory containing modules or anntttttindividual object namen"
  58.    "t[-O] [--no-object]ttNo objects are availablen"
  59.    "t[-m system.map] [--system-map=system.map]ntttttWhere to read System.mapn"
  60.    "t[-M] [--no-system-map]ttNo System.map is availablen"
  61.    "t[-s save.map] [--save-map=save.map]ntttttSave consolidated mapn"
  62.    "t[-S] [--short-lines]ttShort or long lines togglen"
  63.    "t[-e] [--endian-swap]ttToggle endianess of code bytesn"
  64.    "t[-x] [--hex]tttHex or decimal togglen"
  65.    "t[-1] [--one-shot]ttOne shot toggle (exit after first Oops)n"
  66.    "t[-i] [--ignore-insmod-path]tIgnore path from __insmod symbols, togglen"
  67.    "t[-I] [--ignore-insmod-all]tIgnore all __insmod symbols, togglen"
  68.    "t[-d] [--debug]tttIncrease debug level by 1n"
  69.    "t[-h] [--help]tttPrint help textn"
  70.    "t[-t target] [--target=target]tTarget of oops logn"
  71.    "t[-a architecture] [--architecture=architecture]ntttttArchitecture of oops logn"
  72.    "t[-A "address list"] [--addresses="address list"]ntttttAdhoc addresses to decoden"
  73.    "t< Oops.filetttOops report to decoden"
  74.    "n"
  75.    "ttAll flags can occur more than once.  With the exception "
  76. "of -o,n"
  77.    "tt-d and -A which are cumulative, the last occurrence of each "
  78. "flag isn"
  79.    "ttused.  Note that "-v my.vmlinux -V" will be taken as "
  80. ""No vmlinuxn"
  81.    "ttavailable" but "-V -v my.vmlinux" will read "
  82. "my.vmlinux.  Youn"
  83.    "ttwill be warned about such combinations.n"
  84.    "n"
  85.    "ttEach occurrence of -d increases the debug level.n"
  86.    "n"
  87.    "ttEach -o flag can refer to a directory or to a single "
  88. "objectn"
  89.    "ttfile.  If a directory is specified then all *.o files in "
  90. "thatn"
  91.    "ttdirectory and its subdirectories are assumed to be "
  92. "modules.n"
  93.    "n"
  94.    "ttIf any of the vmlinux, object, ksyms or system.map "
  95. "optionsn"
  96.    "ttcontain the string *r (*m, *n, *s) then it is replaced "
  97. "at runn"
  98.    "tttime by the current value of `uname -r` (-m, -n, -s).n"
  99.    "n"
  100.    "ttThe defaults can be changed in the Makefile, current "
  101. "defaultsn"
  102.    "ttarenn"
  103.    "ttt"
  104. #ifdef DEF_VMLINUX
  105.    "-v " DEF_VMLINUX
  106. #else
  107.    "-V"
  108. #endif
  109.    "n"
  110.    "ttt"
  111. #ifdef DEF_KSYMS
  112.    "-k " DEF_KSYMS
  113. #else
  114.    "-K"
  115. #endif
  116.    "n"
  117.    "ttt"
  118. #ifdef DEF_LSMOD
  119.    "-l " DEF_LSMOD
  120. #else
  121.    "-L"
  122. #endif
  123.    "n"
  124.    "ttt"
  125. #ifdef DEF_OBJECTS
  126.    "-o " DEF_OBJECTS
  127. #else
  128.    "-O"
  129. #endif
  130.    "n"
  131.    "ttt"
  132. #ifdef DEF_MAP
  133.    "-m " DEF_MAP
  134. #else
  135.    "-M"
  136. #endif
  137.    "n"
  138. #ifdef DEF_TARGET
  139.    "ttt"
  140.    "-t " DEF_TARGET
  141.    "n"
  142. #endif
  143. #ifdef DEF_ARCH
  144.    "ttt"
  145.    "-a " DEF_ARCH
  146.    "n"
  147. #endif
  148.    "n"
  149.   ;
  150.     printf("Version " VERSION "n");
  151.     printf("usage: %sn", prefix);
  152.     printf("%s", usage_text);
  153. }
  154. /* Check if possibly conflicting options were specified */
  155. static void multi_opt(int specl, int specu, char type, const char *using)
  156. {
  157.     static char procname[] = "multi_opt";
  158.     if (specl && specu) {
  159. WARNING_S("you specified both -%c and -%c.  Using '",
  160.     type, toupper(type));
  161. if (using) {
  162.     WARNING_M("-%c %s", type, using);
  163.     if (type == 'o')
  164. WARNING_M("%s", " ...");
  165.     WARNING_E("%s", "'");
  166. }
  167. else
  168.     WARNING_E("-%c'", toupper(type));
  169.     }
  170.     else if (specl > 1 && type != 'o') {
  171. WARNING("you specified -%c more than once.  Using '-%c %s'",
  172.     type, type, using);
  173.     }
  174.     else if (specu > 1) {
  175. WARNING("you specified -%c more than once.  "
  176.     "Second and subsequent '-%c' ignored",
  177.     toupper(type), toupper(type));
  178.     }
  179. }
  180. /* If a name contains *r (*m, *n, *s), replace with the current value of
  181.  * `uname -r` (-m, -n, -s).  Actually uses uname system call rather than the
  182.  * uname command but the result is the same.
  183.  */
  184. static void convert_uname(char **name)
  185. {
  186.     char *p, *newname, *oldname, *replacement;
  187.     unsigned len;
  188.     int free_oldname = 0;
  189.     static char procname[] = "convert_uname";
  190.     if (!*name)
  191. return;
  192.     while ((p = strchr(*name, '*'))) {
  193. struct utsname buf;
  194. int i = uname(&buf);
  195. DEBUG(1, "%s in", *name);
  196. if (i) {
  197.     ERROR("uname failed, %s will not be processed", *name);
  198.     perror(prefix);
  199.     return;
  200. }
  201. switch (*(p+1)) {
  202. case 'r':
  203.     replacement = buf.release;
  204.     break;
  205. case 'm':
  206.     replacement = buf.machine;
  207.     break;
  208. case 'n':
  209.     replacement = buf.nodename;
  210.     break;
  211. case 's':
  212.     replacement = buf.sysname;
  213.     break;
  214. default:
  215.     ERROR("invalid replacement character '*%c' in %s", *(p+1), *name);
  216.     return;
  217. }
  218. len = strlen(*name)-2+strlen(replacement)+1;
  219. if (!(newname = malloc(len)))
  220.     malloc_error(procname);
  221. strncpy(newname, *name, (p-*name));
  222. strcpy(newname+(p-*name), replacement);
  223. strcpy(newname+(p-*name)+strlen(replacement), p+2);
  224. p = newname+(p-*name)+strlen(replacement);  /* no rescan */
  225. oldname = *name;
  226. *name = newname;
  227. if (free_oldname)
  228.     free(oldname);
  229. free_oldname = 1;
  230. DEBUG(1, "%s out", *name);
  231.     }
  232.     return;
  233. }
  234. /* Report if the option was specified or defaulted */
  235. static void spec_or_default(int spec, int *some_spec) {
  236.     if (spec) {
  237. printf(" (specified)n");
  238. if (some_spec)
  239.     *some_spec = 1;
  240.     }
  241.     else
  242. printf(" (default)n");
  243. }
  244. /* Extract adhoc addresses from a string and save for later.
  245.  * An address is a string of at least 4 hex digits delimited by white space or
  246.  * punctuation marks, possibly prefixed by 0x or 0X.
  247.  */
  248. static void adhoc_addresses(struct options *options, const unsigned char *string)
  249. {
  250.     int count, start;
  251.     const unsigned char *p = string, *p1;
  252.     char *address;
  253.     while (*p) {
  254. while (*p && !isxdigit(*p))
  255.     ++p;
  256. if (!*p)
  257.     continue;
  258. start = p == string || isspace(*(p-1)) || ispunct(*(p-1));
  259. if (!start && p >= string+2 && *(p-2) == '0' && (*(p-1) == 'x' || *(p-1) == 'X')) {
  260.     start = p == string+2 || isspace(*(p-3)) || ispunct(*(p-3));
  261. }
  262. if (!start) {
  263.     ++p;
  264.     continue;
  265. }
  266. p1 = p;
  267. while (isxdigit(*++p)) {};
  268. if (p-p1 < 4)
  269.     continue;
  270. address = malloc(p-p1+1);
  271. if (!address)
  272.     malloc_error("adhoc_addresses");
  273. memcpy(address, p1, p-p1);
  274. address[p-p1] = '';
  275. for (count = 0; options->adhoc_addresses && options->adhoc_addresses[count]; ++count) {};
  276. options->adhoc_addresses = realloc(options->adhoc_addresses, (count+2)*sizeof(options->adhoc_addresses));
  277. if (!options->adhoc_addresses)
  278.     malloc_error("adhoc_addresses");
  279. options->adhoc_addresses[count] = address;
  280. options->adhoc_addresses[count+1] = NULL;
  281.     }
  282. }
  283. /* Parse the options.  Verbose but what's new with getopt? */
  284. static void parse(int argc, char **argv, struct options *options, int *spec_h)
  285. {
  286.     int spec_v = 0, spec_V = 0,
  287. spec_o = 0, spec_O = 0,
  288. spec_k = 0, spec_K = 0,
  289. spec_l = 0, spec_L = 0,
  290. spec_m = 0, spec_M = 0,
  291. spec_s = 0;
  292.     struct utsname buf;
  293.     static char const procname[] = "parse";
  294.     struct option long_opts[] = {
  295. {"vmlinux", 1, 0, 'v'},
  296. {"no-vmlinux", 0, 0, 'V'},
  297. {"ksyms", 1, 0, 'k'},
  298. {"no-ksyms", 0, 0, 'K'},
  299. {"lsmod", 1, 0, 'l'},
  300. {"no-lsmod", 0, 0, 'L'},
  301. {"object", 1, 0, 'o'},
  302. {"no-object", 0, 0, 'O'},
  303. {"system-map", 1, 0, 'm'},
  304. {"no-system-map", 0, 0, 'M'},
  305. {"save-map", 1, 0, 's'},
  306. {"short-lines", 0, 0, 'S'},
  307. {"endian-swap", 0, 0, 'e'},
  308. {"hex", 0, 0, 'x'},
  309. {"one-shot", 0, 0, '1'},
  310. {"ignore-insmod-path", 0, 0, 'i'},
  311. {"ignore-insmod-all", 0, 0, 'I'},
  312. {"truncate", 1, 0, 'T'},
  313. {"debug", 0, 0, 'd'},
  314. {"help", 0, 0, 'h'},
  315. {"target", 1, 0, 't'},
  316. {"architecture", 1, 0, 'a'},
  317. {"addresses", 1, 0, 'A'},
  318. {0, 0, 0, 0}
  319.     };
  320.     int c, i, some_spec = 0;
  321.     char *p, *before;
  322.     while ((c = getopt_long(argc, argv, "v:Vk:Kl:Lo:Om:Ms:e1xSiIT:hdt:a:A:",
  323.     long_opts, NULL)) != EOF) {
  324. if (c != 'd')
  325.     DEBUG(1, "'%c' '%s'", c, optarg);
  326. switch(c) {
  327. case 'v':
  328.     options->vmlinux = optarg;
  329.     ++spec_v;
  330.     break;
  331. case 'V':
  332.     options->vmlinux = NULL;
  333.     ++spec_V;
  334.     break;
  335. case 'k':
  336.     options->ksyms = optarg;
  337.     ++spec_k;
  338.     break;
  339. case 'K':
  340.     options->ksyms = NULL;
  341.     ++spec_K;
  342.     break;
  343. case 'l':
  344.     options->lsmod = optarg;
  345.     ++spec_l;
  346.     break;
  347. case 'L':
  348.     options->lsmod = NULL;
  349.     ++spec_L;
  350.     break;
  351. case 'o':
  352.     if (!spec_o) {
  353. /* First -o, discard default value(s) */
  354. for (i = 0; i < options->objects; ++i)
  355.     free((options->object)[i]);
  356. free(options->object);
  357. options->object = NULL;
  358. options->objects = 0;
  359.     }
  360.     options->object = realloc(options->object,
  361. ((options->objects)+1)*sizeof(*(options->object)));
  362.     if (!options->object)
  363. malloc_error("object");
  364.     if (!(p = strdup(optarg)))
  365. malloc_error("strdup -o");
  366.     else {
  367. (options->object)[(options->objects)++] = p;
  368. ++spec_o;
  369.     }
  370.     break;
  371. case 'O':
  372.     ++spec_O;
  373.     for (i = 0; i < options->objects; ++i)
  374. free((options->object)[i]);
  375.     free(options->object);
  376.     options->object = NULL;
  377.     options->objects = 0;
  378.     break;
  379. case 'm':
  380.     options->system_map = optarg;
  381.     ++spec_m;
  382.     break;
  383. case 'M':
  384.     options->system_map = NULL;
  385.     ++spec_M;
  386.     break;
  387. case 's':
  388.     options->save_system_map = optarg;
  389.     ++spec_s;
  390.     break;
  391. case 'e':
  392.     options->endianess = !options->endianess;
  393.     break;
  394. case '1':
  395.     options->one_shot = !options->one_shot;
  396.     break;
  397. case 'x':
  398.     options->hex = !options->hex;
  399.     break;
  400. case 'S':
  401.     options->short_lines = !options->short_lines;
  402.     break;
  403. case 'i':
  404.     options->ignore_insmod_path = !options->ignore_insmod_path;
  405.     break;
  406. case 'I':
  407.     options->ignore_insmod_all = !options->ignore_insmod_all;
  408.     break;
  409. case 'T':
  410.     options->truncate = atoi(optarg);
  411.     if (options->truncate >= 8*sizeof(addr_t) || options->truncate <= 0) {
  412. options->truncate = 0;
  413. truncate_mask = ~(addr_t)0;
  414.     }
  415.     else {
  416. truncate_mask = (~(addr_t)0) >> (8*sizeof(addr_t)-options->truncate);
  417.     }
  418.     break;
  419. case 'h':
  420.     usage();
  421.     ++*spec_h;
  422.     break;
  423. case 'd':
  424.     ++debug;
  425.     break;
  426. case 't':
  427.     options->target = optarg;
  428.     break;
  429. case 'a':
  430.     options->architecture = optarg;
  431.     break;
  432. case 'A':
  433.     adhoc_addresses(options, optarg);
  434.     break;
  435. case '?':
  436.     if (c == 'c')
  437. printf("Option -c is obsolete, use -e toggle insteadn");
  438.     usage();
  439.     exit(2);
  440. }
  441.     }
  442.     options->filecount = argc - optind;
  443.     options->filename = argv + optind;
  444.     if (options->adhoc_addresses && !options->filecount) {
  445. static char *null = "/dev/null";
  446. static char **null_list = { &null };
  447. options->filecount = 1;
  448. options->filename = null_list;
  449.     }
  450.     /* Expand any requests for the current uname values */
  451.     convert_uname(&options->vmlinux);
  452.     if (options->objects) {
  453. for (i = 0; i < options->objects; ++i)
  454.     convert_uname(options->object+i);
  455.     }
  456.     convert_uname(&options->ksyms);
  457.     convert_uname(&options->lsmod);
  458.     convert_uname(&options->system_map);
  459.     /* Check for multiple options specified */
  460.     multi_opt(spec_v, spec_V, 'v', options->vmlinux);
  461.     multi_opt(spec_o, spec_O, 'o', options->object ? *options->object : NULL);
  462.     multi_opt(spec_k, spec_K, 'k', options->ksyms);
  463.     multi_opt(spec_l, spec_L, 'l', options->lsmod);
  464.     multi_opt(spec_m, spec_M, 'm', options->system_map);
  465.     printf("ksymoops %s", VERSION);
  466.     if (uname(&buf) == 0)
  467. printf(" on %s %s", buf.machine, buf.release);
  468.     printf(".  Options usedn");
  469.     printf("    ");
  470.     if (options->vmlinux)
  471. printf(" -v %s", options->vmlinux);
  472.     else
  473. printf(" -V");
  474.     spec_or_default(spec_v || spec_V, &some_spec);
  475.     printf("    ");
  476.     if (options->ksyms)
  477. printf(" -k %s", options->ksyms);
  478.     else
  479. printf(" -K");
  480.     spec_or_default(spec_k || spec_K, &some_spec);
  481.     printf("    ");
  482.     if (options->lsmod)
  483. printf(" -l %s", options->lsmod);
  484.     else
  485. printf(" -L");
  486.     spec_or_default(spec_l || spec_L, &some_spec);
  487.     printf("    ");
  488.     if (options->objects) {
  489. for (i = 0; i < options->objects; ++i)
  490.     printf(" -o %s", (options->object)[i]);
  491.     }
  492.     else
  493. printf(" -O");
  494.     spec_or_default(spec_o || spec_O, &some_spec);
  495.     printf("    ");
  496.     if (options->system_map)
  497. printf(" -m %s", options->system_map);
  498.     else
  499. printf(" -M");
  500.     spec_or_default(spec_m || spec_M, &some_spec);
  501.     /* Toggles on one line */
  502.     before = "    ";
  503.     if (!options->short_lines) {
  504. printf("%s -S", before);
  505. before = "";
  506.     }
  507.     if (options->endianess) {
  508. printf("%s -e", before);
  509. before = "";
  510.     }
  511.     if (!options->hex) {
  512. printf("%s -x", before);
  513. before = "";
  514.     }
  515.     if (options->one_shot) {
  516. printf("%s -1", before);
  517. before = "";
  518.     }
  519.     if (options->ignore_insmod_path) {
  520. printf("%s -i", before);
  521. before = "";
  522.     }
  523.     if (options->ignore_insmod_all) {
  524. printf("%s -I", before);
  525. before = "";
  526.     }
  527.     if (!*before)
  528. printf("n");
  529.     before = "    ";
  530.     if (options->truncate) {
  531. printf("%s -T %d", before, options->truncate);
  532. before = "";
  533.     }
  534.     if (!*before)
  535. printf("n");
  536.     /* Target and architecture on one line */
  537.     before = "    ";
  538.     if (options->target) {
  539. printf("%s -t %s", before, options->target);
  540. before = "";
  541.     }
  542.     if (options->architecture) {
  543. printf("%s -a %s", before, options->architecture);
  544. before = "";
  545.     }
  546.     if (!*before)
  547. printf("n");
  548.     printf("n");
  549.     if (!some_spec) {
  550. /* special warning, no procname */
  551. ++warnings;
  552. WARNING_E("%s",
  553. "Warning: You did not tell me where to find symbol information.  I willn"
  554. "assume that the log matches the kernel and modules that are runningn"
  555. "right now and I'll use the default options above for symbol resolution.n"
  556. "If the current kernel and/or modules do not match the log, you can getn"
  557. "more accurate output by telling me the kernel version and where to findn"
  558. "map, modules, ksyms etc.  ksymoops -h explains the options.n"
  559.     );
  560.     }
  561. }
  562. /* Read environment variables */
  563. static void read_env(const char *external, char **internal)
  564. {
  565.     char *p;
  566.     static char const procname[] = "read_env";
  567.     if ((p = getenv(external))) {
  568. *internal = p;
  569. DEBUG(1, "override %s=%s", external, *internal);
  570.     }
  571.     else
  572. DEBUG(1, "default %s=%s", external, *internal);
  573. }
  574. /* Print the available target and architectures. */
  575. static void print_available_ta(const struct options *options)
  576. {
  577.     const char **list, **one;
  578.     if (options->target && strcmp(options->target, "?") == 0) {
  579. printf("Targets supported by your libbfdn");
  580. list = one = bfd_target_list();
  581. if (!list || !*list)
  582.     printf("    None, oh dearn");
  583. else while (*one)
  584.     printf("    %sn", *one++);
  585. free(list);
  586.     }
  587.     if (options->architecture && strcmp(options->architecture, "?") == 0) {
  588. printf("Architectures supported by your libbfdn");
  589. list = one = bfd_arch_list();
  590. if (!list || !*list)
  591.     printf("    None, oh dearn");
  592. else while (*one)
  593.     printf("    %sn", *one++);
  594. free(list);
  595.     }
  596.     printf(
  597. "Note that the above list comes from libbfd.  I have to assume that yourn"
  598. "other binutils libraries (libiberty, libopcodes) and binutils programsn"
  599. "(nm and objdump) are in sync with libbfd.n"
  600.     );
  601. }
  602. /* Do all the hard work of reading the symbol sources */
  603. void read_symbol_sources(const OPTIONS *options)
  604. {
  605.     int i;
  606.     read_vmlinux(options);
  607.     read_ksyms(options);
  608.     /* No point in reading modules unless ksyms shows modules loaded */
  609.     if (ss_ksyms_modules) {
  610. expand_objects(options);
  611. for (i = 0; i < ss_objects; ++i)
  612.     read_object(ss_object[i]->source, i);
  613.     }
  614.     else if (options->objects)
  615. printf("No modules in ksyms, skipping objectsn");
  616.     /* No point in reading lsmod without ksyms */
  617.     if (ss_ksyms_modules || ss_ksyms_base.used)
  618. read_lsmod(options);
  619.     else if (options->lsmod)
  620. printf("No ksyms, skipping lsmodn");
  621.     read_system_map(options);
  622.     merge_maps(options);
  623. }
  624. int main(int argc, char **argv)
  625. {
  626.     int spec_h = 0;     /* -h was specified */
  627.     int ret;
  628.     struct options options = {
  629. NULL,   /* vmlinux */
  630. NULL,   /* object */
  631. 0, /* objects */
  632. NULL,   /* ksyms */
  633. NULL,   /* lsmod */
  634. NULL,   /* system_map */
  635. NULL,   /* save_system_map */
  636. NULL,   /* filename */
  637. 0, /* filecount */
  638. 1, /* short_lines */
  639. 0, /* endianess */
  640. 1, /* hex */
  641. 0, /* one_shot */
  642. 0, /* ignore_insmod_path */
  643. 0, /* ignore_insmod_all */
  644. 0, /* truncate */
  645. NULL,   /* target */
  646. NULL,   /* architecture */
  647. NULL,   /* addresses */
  648. 0 /* address_bits */
  649.     };
  650.     static char const procname[] = "main";
  651.     prefix = *argv;
  652.     setvbuf(stdout, NULL, _IONBF, 0);
  653. #ifdef DEF_VMLINUX
  654.     options.vmlinux = DEF_VMLINUX;
  655. #endif
  656. #ifdef DEF_KSYMS
  657.     options.ksyms = DEF_KSYMS;
  658. #endif
  659. #ifdef DEF_LSMOD
  660.     options.lsmod = DEF_LSMOD;
  661. #endif
  662. #ifdef DEF_OBJECTS
  663.     {
  664. char *p;
  665. options.object = realloc(options.object,
  666.     (options.objects+1)*sizeof(*options.object));
  667. if (!options.object)
  668.     malloc_error("DEF_OBJECTS");
  669. if (!(p = strdup(DEF_OBJECTS)))
  670.     malloc_error("DEF_OBJECTS");
  671. else
  672.     options.object[options.objects++] = p;
  673.     }
  674. #endif
  675. #ifdef DEF_MAP
  676.     options.system_map = DEF_MAP;
  677. #endif
  678. #ifdef DEF_TARGET
  679.     options.target = DEF_TARGET;
  680.     {
  681. int target_byteorder;
  682. if (strstr(options.target, "-big"))
  683.     target_byteorder = __BIG_ENDIAN;
  684. else if (strstr(options.target, "-little"))
  685.     target_byteorder = __LITTLE_ENDIAN;
  686. else
  687.     target_byteorder = __BYTE_ORDER;
  688. if (target_byteorder != __BYTE_ORDER)
  689.     options.endianess = 1;
  690.     }
  691. #endif
  692. #ifdef DEF_ARCH
  693.     options.architecture = DEF_ARCH;
  694. #endif
  695.     /* Not all include files define __u16, __u32, __u64 so do it the hard way.
  696.      * Any decent optimizing compiler will discard these tests at compile time
  697.      * unless there is a problem.
  698.      */
  699.     if (sizeof(U16) != 2)
  700. FATAL("%s", "sizeof(U16) != 2");
  701.     if (sizeof(U32) != 4)
  702. FATAL("%s", "sizeof(U32) != 4");
  703.     if (sizeof(U64) != 8)
  704. FATAL("%s", "sizeof(U64) != 8");
  705.     parse(argc, argv, &options, &spec_h);
  706.     if (spec_h && options.filecount == 0)
  707. return(0);  /* just the help text */
  708.     bfd_init();
  709.     if ((options.target && strcmp(options.target, "?") == 0) ||
  710. (options.architecture && strcmp(options.architecture, "?") == 0)) {
  711. print_available_ta(&options);
  712. return(0);  /* just the available target/architecture */
  713.     }
  714.     if (errors)
  715. return(1);
  716.     DEBUG(1, "level %d", debug);
  717.     read_env("KSYMOOPS_NM", &path_nm);
  718.     read_env("KSYMOOPS_FIND", &path_find);
  719.     read_env("KSYMOOPS_OBJDUMP", &path_objdump);
  720.     re_compile_common();
  721.     ss_init_common();
  722.     if (!options.one_shot)
  723. read_symbol_sources(&options);
  724.     /* After all that work, it is finally time to read the Oops report */
  725.     ret = Oops_read(&options);
  726.     if (warnings || errors) {
  727. printf("n");
  728. if (warnings)
  729.     printf("%d warning%s ",
  730.    warnings, warnings == 1 ? "" : "s");
  731. if (warnings && errors)
  732.     printf("and ");
  733. if (errors)
  734.     printf("%d error%s ", errors, errors == 1 ? "" : "s");
  735. printf("issued.  Results may not be reliable.n");
  736. if (!ret)
  737.     return(1);
  738.     }
  739.     return(ret);
  740. }