155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project#include <stdio.h>
255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project#include <stdlib.h>
355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project#include <string.h>
455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project#include <unistd.h>
555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project#include <ctype.h>
655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project#include "bitvector.h"
755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project#include "parse_options.h"
855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project#include "hash_table.h"
955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
1055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectconst char *root = "";
1155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectbool lump_kernel;
1255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectbool lump_libraries;
1355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source ProjectBitvector pid_include_vector(32768);
1455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source ProjectBitvector pid_exclude_vector(32768);
1555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectbool include_some_pids;
1655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectbool exclude_some_pids;
1755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
1855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source ProjectHashTable<int> excluded_procedures(2000);
1955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source ProjectHashTable<int> included_procedures(2000);
2055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectbool exclude_some_procedures;
2155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectbool include_some_procedures;
2255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
2355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectbool exclude_kernel_syms;
2455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectbool exclude_library_syms;
2555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectbool include_kernel_syms;
2655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectbool include_library_syms;
2755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectbool demangle = true;
2855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
2955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectstatic const char *OptionsUsageStr =
3055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    "  -e :kernel exclude all kernel symbols\n"
3155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    "  -e :libs   exclude all library symbols\n"
3255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    "  -e <func>  exclude function <func>\n"
3355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    "  -e <pid>   exclude process <pid>\n"
3455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    "  -i :kernel include all kernel symbols\n"
3555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    "  -i :libs   include all library symbols\n"
3655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    "  -i <func>  include function <func>\n"
3755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    "  -i <pid>   include process <pid>\n"
3855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    "  -l :kernel lump all the kernel symbols together\n"
3955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    "  -l :libs   lump all the library symbols together\n"
4055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    "  -m         do not demangle C++ symbols (m for 'mangle')\n"
4155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    "  -r <root>  use <root> as the path for finding ELF executables\n"
4255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    ;
4355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
4455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectvoid OptionsUsage()
4555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project{
4655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    fprintf(stderr, "%s", OptionsUsageStr);
4755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project}
4855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
4955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectvoid ParseOptions(int argc, char **argv)
5055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project{
5155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    bool err = false;
5255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    while (!err) {
5355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        int opt = getopt(argc, argv, "+e:i:l:mr:");
5455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        if (opt == -1)
5555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            break;
5655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        switch (opt) {
5755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        case 'e':
5855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            if (*optarg == ':') {
5955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                if (strcmp(optarg, ":kernel") == 0)
6055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                    exclude_kernel_syms = true;
6155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                else if (strcmp(optarg, ":libs") == 0)
6255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                    exclude_library_syms = true;
6355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                else
6455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                    err = true;
6555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                excluded_procedures.Update(optarg, 1);
6655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                exclude_some_procedures = true;
6755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            } else if (isdigit(*optarg)) {
6855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                int bitnum = atoi(optarg);
6955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                pid_exclude_vector.SetBit(bitnum);
7055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                exclude_some_pids = true;
7155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            } else {
7255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                excluded_procedures.Update(optarg, 1);
7355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                exclude_some_procedures = true;
7455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            }
7555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            break;
7655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        case 'i':
7755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            if (*optarg == ':') {
7855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                if (strcmp(optarg, ":kernel") == 0)
7955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                    include_kernel_syms = true;
8055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                else if (strcmp(optarg, ":libs") == 0)
8155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                    include_library_syms = true;
8255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                else
8355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                    err = true;
8455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                included_procedures.Update(optarg, 1);
8555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                include_some_procedures = true;
8655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            } else if (isdigit(*optarg)) {
8755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                int bitnum = atoi(optarg);
8855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                pid_include_vector.SetBit(bitnum);
8955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                include_some_pids = true;
9055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            } else {
9155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                included_procedures.Update(optarg, 1);
9255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                include_some_procedures = true;
9355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            }
9455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            break;
9555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        case 'l':
9655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            if (strcmp(optarg, ":kernel") == 0)
9755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                lump_kernel = true;
9855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            else if (strcmp(optarg, ":libs") == 0)
9955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                lump_libraries = true;
10055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            else
10155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project                err = true;
10255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            break;
10355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        case 'm':
10455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            demangle = false;
10555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            break;
10655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        case 'r':
10755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            root = optarg;
10855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            break;
10955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        default:
11055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            err = true;
11155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project            break;
11255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        }
11355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    }
11455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project
11555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    if (err) {
11655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        Usage(argv[0]);
11755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project        exit(1);
11855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project    }
11955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project}
120