diff options
Diffstat (limited to 'tools/soslim/cmdline.c')
-rw-r--r-- | tools/soslim/cmdline.c | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/tools/soslim/cmdline.c b/tools/soslim/cmdline.c new file mode 100644 index 0000000..c2d5e71 --- /dev/null +++ b/tools/soslim/cmdline.c @@ -0,0 +1,141 @@ +#include <debug.h> +#include <cmdline.h> +#include <stdio.h> +#include <stdlib.h> +#include <getopt.h> +#include <string.h> +#include <ctype.h> + +extern char *optarg; +extern int optind, opterr, optopt; + +static struct option long_options[] = +{ + {"verbose", no_argument, 0, 'V'}, + {"quiet", no_argument, 0, 'Q'}, + {"shady", no_argument, 0, 'S'}, + {"print", no_argument, 0, 'p'}, + {"help", no_argument, 0, 'h'}, + {"outfile", required_argument, 0, 'o'}, + {"filter", required_argument, 0, 'f'}, + {"dry", no_argument, 0, 'n'}, + {"strip", no_argument, 0, 's'}, + {0, 0, 0, 0}, +}; + +/* This array must parallel long_options[] */ +static +const char *descriptions[sizeof(long_options)/sizeof(long_options[0])] = { + "print verbose output", + "suppress errors and warnings", + "patch ABS symbols whose values coincide with section starts and ends", + "print the symbol table (if specified, only -V is allowed)", + "this help screen", + "specify an output file (if not provided, input file is modified)", + "specify a symbol-filter file", + "dry run (perform all calculations but do not modify the ELF file)", + "strip debug sections, if they are present" +}; + +void print_help(void) +{ + fprintf(stdout, + "invokation:\n" + "\tsoslim file1 [file2 file3 ... fileN] [-Ldir1 -Ldir2 ... -LdirN] " + "[-Vpn]\n" + "or\n" + "\tsoslim -h\n\n"); + fprintf(stdout, "options:\n"); + struct option *opt = long_options; + const char **desc = descriptions; + while (opt->name) { + fprintf(stdout, "\t-%c/--%-15s %s\n", + opt->val, + opt->name, + *desc); + opt++; + desc++; + } +} + +int get_options(int argc, char **argv, + char **outfile, + char **symsfile, + int *print_symtab, + int *verbose, + int *quiet, + int *shady, + int *dry_run, + int *strip_debug) +{ + int c; + + ASSERT(outfile); + *outfile = NULL; + ASSERT(symsfile); + *symsfile = NULL; + ASSERT(print_symtab); + *print_symtab = 0; + ASSERT(verbose); + *verbose = 0; + ASSERT(quiet); + *quiet = 0; + ASSERT(shady); + *shady = 0; + ASSERT(dry_run); + *dry_run = 0; + ASSERT(strip_debug); + *strip_debug = 0; + + while (1) { + /* getopt_long stores the option index here. */ + int option_index = 0; + + c = getopt_long (argc, argv, + "QVSphi:o:y:Y:f:ns", + long_options, + &option_index); + /* Detect the end of the options. */ + if (c == -1) break; + + if (isgraph(c)) { + INFO ("option -%c with value `%s'\n", c, (optarg ?: "(null)")); + } + +#define SET_STRING_OPTION(name) do { \ + ASSERT(optarg); \ + *name = strdup(optarg); \ +} while(0) + + switch (c) { + case 0: + /* If this option set a flag, do nothing else now. */ + if (long_options[option_index].flag != 0) + break; + INFO ("option %s", long_options[option_index].name); + if (optarg) + INFO (" with arg %s", optarg); + INFO ("\n"); + break; + case 'p': *print_symtab = 1; break; + case 'h': print_help(); exit(1); break; + case 'V': *verbose = 1; break; + case 'Q': *quiet = 1; break; + case 'S': *shady = 1; break; + case 'n': *dry_run = 1; break; + case 's': *strip_debug = 1; break; + case 'o': SET_STRING_OPTION(outfile); break; + case 'f': SET_STRING_OPTION(symsfile); break; + case '?': + /* getopt_long already printed an error message. */ + break; + +#undef SET_STRING_OPTION + + default: + FAILIF(1, "Unknown option"); + } + } + + return optind; +} |