• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
print_help(const char * name)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 
get_options(int argc,char ** argv,char ** lib,char ** sym)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 
main(int argc,char ** argv)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