Home | History | Annotate | Download | only in soslim
      1 #include <debug.h>
      2 #include <cmdline.h>
      3 #include <stdio.h>
      4 #include <stdlib.h>
      5 #include <getopt.h>
      6 #include <string.h>
      7 #include <ctype.h>
      8 
      9 extern char *optarg;
     10 extern int optind, opterr, optopt;
     11 
     12 static struct option long_options[] =
     13 {
     14     {"verbose",  no_argument,       0, 'V'},
     15     {"quiet",    no_argument,       0, 'Q'},
     16     {"shady",    no_argument,       0, 'S'},
     17     {"print",    no_argument,       0, 'p'},
     18     {"help",     no_argument,       0, 'h'},
     19     {"outfile",  required_argument, 0, 'o'},
     20     {"filter",   required_argument, 0, 'f'},
     21     {"dry",      no_argument,       0, 'n'},
     22     {"strip",    no_argument,       0, 's'},
     23     {0, 0, 0, 0},
     24 };
     25 
     26 /* This array must parallel long_options[] */
     27 static
     28 const char *descriptions[sizeof(long_options)/sizeof(long_options[0])] = {
     29 	"print verbose output",
     30     "suppress errors and warnings",
     31     "patch ABS symbols whose values coincide with section starts and ends",
     32     "print the symbol table (if specified, only -V is allowed)",
     33     "this help screen",
     34     "specify an output file (if not provided, input file is modified)",
     35     "specify a symbol-filter file",
     36     "dry run (perform all calculations but do not modify the ELF file)",
     37     "strip debug sections, if they are present"
     38 };
     39 
     40 void print_help(void)
     41 {
     42     fprintf(stdout,
     43 			"invokation:\n"
     44 			"\tsoslim file1 [file2 file3 ... fileN] [-Ldir1 -Ldir2 ... -LdirN] "
     45 			"[-Vpn]\n"
     46 			"or\n"
     47 			"\tsoslim -h\n\n");
     48 	fprintf(stdout, "options:\n");
     49 	struct option *opt = long_options;
     50 	const char **desc = descriptions;
     51 	while (opt->name) {
     52 		fprintf(stdout, "\t-%c/--%-15s %s\n",
     53 				opt->val,
     54 				opt->name,
     55 				*desc);
     56 		opt++;
     57 		desc++;
     58 	}
     59 }
     60 
     61 int get_options(int argc, char **argv,
     62                 char **outfile,
     63                 char **symsfile,
     64                 int *print_symtab,
     65                 int *verbose,
     66                 int *quiet,
     67                 int *shady,
     68                 int *dry_run,
     69                 int *strip_debug)
     70 {
     71     int c;
     72 
     73     ASSERT(outfile);
     74     *outfile = NULL;
     75     ASSERT(symsfile);
     76     *symsfile = NULL;
     77     ASSERT(print_symtab);
     78     *print_symtab = 0;
     79     ASSERT(verbose);
     80     *verbose = 0;
     81     ASSERT(quiet);
     82     *quiet = 0;
     83     ASSERT(shady);
     84     *shady = 0;
     85     ASSERT(dry_run);
     86     *dry_run = 0;
     87     ASSERT(strip_debug);
     88     *strip_debug = 0;
     89 
     90     while (1) {
     91         /* getopt_long stores the option index here. */
     92         int option_index = 0;
     93 
     94         c = getopt_long (argc, argv,
     95                          "QVSphi:o:y:Y:f:ns",
     96                          long_options,
     97                          &option_index);
     98         /* Detect the end of the options. */
     99         if (c == -1) break;
    100 
    101         if (isgraph(c)) {
    102             INFO ("option -%c with value `%s'\n", c, (optarg ?: "(null)"));
    103         }
    104 
    105 #define SET_STRING_OPTION(name) do { \
    106     ASSERT(optarg);                  \
    107     *name = strdup(optarg);          \
    108 } while(0)
    109 
    110         switch (c) {
    111         case 0:
    112             /* If this option set a flag, do nothing else now. */
    113             if (long_options[option_index].flag != 0)
    114                 break;
    115             INFO ("option %s", long_options[option_index].name);
    116             if (optarg)
    117                 INFO (" with arg %s", optarg);
    118             INFO ("\n");
    119             break;
    120         case 'p': *print_symtab = 1; break;
    121         case 'h': print_help(); exit(1); break;
    122         case 'V': *verbose = 1; break;
    123         case 'Q': *quiet = 1; break;
    124         case 'S': *shady = 1; break;
    125         case 'n': *dry_run = 1; break;
    126         case 's': *strip_debug = 1; break;
    127         case 'o': SET_STRING_OPTION(outfile); break;
    128         case 'f': SET_STRING_OPTION(symsfile); break;
    129         case '?':
    130             /* getopt_long already printed an error message. */
    131             break;
    132 
    133 #undef SET_STRING_OPTION
    134 
    135         default:
    136             FAILIF(1, "Unknown option");
    137         }
    138     }
    139 
    140     return optind;
    141 }
    142