1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <stdio.h> 30 #include <unistd.h> 31 #include <stdlib.h> 32 #include <getopt.h> 33 #include <string.h> 34 #include <dlfcn.h> 35 36 extern char *optarg; 37 extern int optind, opterr, optopt; 38 39 static struct option long_options[] = { 40 {"library", required_argument, 0, 'l'}, 41 {"symbol", required_argument, 0, 's'}, 42 {"help", no_argument, 0, 'h'}, 43 {0, 0, 0, 0}, 44 }; 45 46 /* This array must parallel long_options[] */ 47 static const char *descriptions[] = { 48 "specify a library path to look up symbol", 49 "specify symbol to look up", 50 "print this help screen", 51 }; 52 53 void print_help(const char *name) { 54 fprintf(stdout, 55 "invokation:\n" 56 "\t%s [-l <libname>] -s <symbol name>\n" 57 "\t%s -h\n\n", name, name); 58 fprintf(stdout, "options:\n"); 59 struct option *opt = long_options; 60 const char **desc = descriptions; 61 while (opt->name) { 62 fprintf(stdout, "\t-%c/--%s%s: %s\n", 63 opt->val, 64 opt->name, 65 (opt->has_arg ? " (argument)" : ""), 66 *desc); 67 opt++; 68 desc++; 69 } 70 } 71 72 int get_options(int argc, char **argv, char **lib, char **sym) 73 { 74 int c; 75 76 *lib = 0; 77 *sym = 0; 78 79 while (1) { 80 /* getopt_long stores the option index here. */ 81 int option_index = 0; 82 83 c = getopt_long (argc, argv, 84 "l:s:h", 85 long_options, 86 &option_index); 87 /* Detect the end of the options. */ 88 if (c == -1) break; 89 90 switch (c) { 91 case 'l': 92 *lib = strdup(optarg); 93 break; 94 case 's': 95 *sym = strdup(optarg); 96 break; 97 case 'h': print_help(argv[0]); exit(EXIT_FAILURE); break; 98 case '?': 99 /* getopt_long already printed an error message. */ 100 break; 101 default: 102 fprintf(stderr, "Unknown option"); 103 exit(EXIT_FAILURE); 104 } 105 } 106 107 return optind; 108 } 109 110 int main(int argc, char **argv) 111 { 112 char *libname, *symname, *prog = *argv; 113 114 get_options(argc, argv, &libname, &symname); 115 116 if (symname == NULL) { 117 fprintf(stderr, "You must specify a symbol!\n"); 118 print_help(prog); 119 exit(EXIT_FAILURE); 120 } 121 122 { 123 const char *dlerr; 124 void *handle, *symbol; 125 126 printf("opening library [%s]\n", libname); 127 dlerr = dlerror(); 128 handle = libname ? dlopen(libname, RTLD_NOW) : RTLD_DEFAULT; 129 dlerr = dlerror(); 130 if (dlerr != NULL) fprintf(stderr, "dlopen() error: %s\n", dlerr); 131 132 printf("opening symbol [%s]\n", symname); 133 symbol = dlsym(handle, symname); 134 dlerr = dlerror(); 135 if (dlerr != NULL) fprintf(stderr, "dlsym() error: %s\n", dlerr); 136 137 printf("closing library [%s]\n", libname); 138 dlclose(handle); 139 dlerr = dlerror(); 140 if (dlerr != NULL) fprintf(stderr, "dlclose() error: %s\n", dlerr); 141 else printf("successfully opened symbol\n"); 142 } 143 144 if (libname != NULL) free(libname); 145 if (symname != NULL) free(symname); 146 return 0; 147 } 148