/* * Copyright (C) 2008 The Android Open Source Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <getopt.h> #include <string.h> #include <dlfcn.h> extern char *optarg; extern int optind, opterr, optopt; static struct option long_options[] = { {"library", required_argument, 0, 'l'}, {"symbol", required_argument, 0, 's'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}, }; /* This array must parallel long_options[] */ static const char *descriptions[] = { "specify a library path to look up symbol", "specify symbol to look up", "print this help screen", }; void print_help(const char *name) { fprintf(stdout, "invokation:\n" "\t%s [-l <libname>] -s <symbol name>\n" "\t%s -h\n\n", name, name); fprintf(stdout, "options:\n"); struct option *opt = long_options; const char **desc = descriptions; while (opt->name) { fprintf(stdout, "\t-%c/--%s%s: %s\n", opt->val, opt->name, (opt->has_arg ? " (argument)" : ""), *desc); opt++; desc++; } } int get_options(int argc, char **argv, char **lib, char **sym) { int c; *lib = 0; *sym = 0; while (1) { /* getopt_long stores the option index here. */ int option_index = 0; c = getopt_long (argc, argv, "l:s:h", long_options, &option_index); /* Detect the end of the options. */ if (c == -1) break; switch (c) { case 'l': *lib = strdup(optarg); break; case 's': *sym = strdup(optarg); break; case 'h': print_help(argv[0]); exit(EXIT_FAILURE); break; case '?': /* getopt_long already printed an error message. */ break; default: fprintf(stderr, "Unknown option"); exit(EXIT_FAILURE); } } return optind; } int main(int argc, char **argv) { char *libname, *symname, *prog = *argv; get_options(argc, argv, &libname, &symname); if (symname == NULL) { fprintf(stderr, "You must specify a symbol!\n"); print_help(prog); exit(EXIT_FAILURE); } { const char *dlerr; void *handle, *symbol; printf("opening library [%s]\n", libname); dlerr = dlerror(); handle = libname ? dlopen(libname, RTLD_NOW) : RTLD_DEFAULT; dlerr = dlerror(); if (dlerr != NULL) fprintf(stderr, "dlopen() error: %s\n", dlerr); printf("opening symbol [%s]\n", symname); symbol = dlsym(handle, symname); dlerr = dlerror(); if (dlerr != NULL) fprintf(stderr, "dlsym() error: %s\n", dlerr); printf("closing library [%s]\n", libname); dlclose(handle); dlerr = dlerror(); if (dlerr != NULL) fprintf(stderr, "dlclose() error: %s\n", dlerr); else printf("successfully opened symbol\n"); } if (libname != NULL) free(libname); if (symname != NULL) free(symname); return 0; }