11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * All rights reserved.
41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Redistribution and use in source and binary forms, with or without
61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * modification, are permitted provided that the following conditions
71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * are met:
81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *  * Redistributions of source code must retain the above copyright
91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *  * Redistributions in binary form must reproduce the above copyright
111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    notice, this list of conditions and the following disclaimer in
121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    the documentation and/or other materials provided with the
131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    distribution.
141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SUCH DAMAGE.
271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdio.h>
301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <unistd.h>
311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdlib.h>
321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <getopt.h>
331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <string.h>
341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <dlfcn.h>
351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern char *optarg;
371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern int optind, opterr, optopt;
381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic struct option long_options[] = {
401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    {"library", required_argument, 0, 'l'},
411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    {"symbol",  required_argument, 0, 's'},
421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    {"help",    no_argument,       0, 'h'},
431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    {0, 0, 0, 0},
441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project};
451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* This array must parallel long_options[] */
471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const char *descriptions[] = {
481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    "specify a library path to look up symbol",
491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    "specify symbol to look up",
501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    "print this help screen",
511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project};
521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectvoid print_help(const char *name) {
541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    fprintf(stdout,
551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            "invokation:\n"
561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            "\t%s [-l <libname>] -s <symbol name>\n"
571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            "\t%s -h\n\n", name, name);
581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    fprintf(stdout, "options:\n");
591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    struct option *opt = long_options;
601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    const char **desc = descriptions;
611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    while (opt->name) {
621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        fprintf(stdout, "\t-%c/--%s%s: %s\n",
631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                opt->val,
641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                opt->name,
651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                (opt->has_arg ? " (argument)" : ""),
661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                *desc);
671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        opt++;
681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        desc++;
691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    }
701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint get_options(int argc, char **argv, char **lib, char **sym)
731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    int c;
751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    *lib = 0;
771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    *sym = 0;
781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    while (1) {
801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        /* getopt_long stores the option index here. */
811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        int option_index = 0;
821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        c = getopt_long (argc, argv,
841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                         "l:s:h",
851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                         long_options,
861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                         &option_index);
871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        /* Detect the end of the options. */
881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        if (c == -1) break;
891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        switch (c) {
911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case 'l':
921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            *lib = strdup(optarg);
931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        case 's':
951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            *sym = strdup(optarg);
961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            break;
971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        case 'h': print_help(argv[0]); exit(EXIT_FAILURE); break;
981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        case '?':
991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            /* getopt_long already printed an error message. */
1001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            break;
1011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        default:
1021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            fprintf(stderr, "Unknown option");
1031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project            exit(EXIT_FAILURE);
1041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        }
1051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    }
1061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    return optind;
1081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
1091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint main(int argc, char **argv)
1111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
1121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    char *libname, *symname, *prog = *argv;
1131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    get_options(argc, argv, &libname, &symname);
1151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    if (symname == NULL) {
1171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        fprintf(stderr, "You must specify a symbol!\n");
1181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        print_help(prog);
1191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        exit(EXIT_FAILURE);
1201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    }
1211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    {
1231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        const char *dlerr;
1241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        void *handle, *symbol;
1251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        printf("opening library [%s]\n", libname);
1271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        dlerr = dlerror();
1281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        handle = libname ? dlopen(libname, RTLD_NOW) : RTLD_DEFAULT;
1291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        dlerr = dlerror();
1301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        if (dlerr != NULL) fprintf(stderr, "dlopen() error: %s\n", dlerr);
1311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        printf("opening symbol [%s]\n", symname);
1331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        symbol = dlsym(handle, symname);
1341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        dlerr = dlerror();
1351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        if (dlerr != NULL) fprintf(stderr, "dlsym() error: %s\n", dlerr);
1361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        printf("closing library [%s]\n", libname);
1381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        dlclose(handle);
1391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        dlerr = dlerror();
1401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        if (dlerr != NULL) fprintf(stderr, "dlclose() error: %s\n", dlerr);
1411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        else printf("successfully opened symbol\n");
1421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    }
1431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    if (libname != NULL) free(libname);
1451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    if (symname != NULL) free(symname);
1461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    return 0;
1471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
148