blob: e84d5a324e2c326a0398067f11d991fc472fdac5 [file] [log] [blame]
The Android Open Source Projecta27d2ba2008-10-21 07:00:00 -07001#include <stdio.h>
2#include <unistd.h>
3#include <stdlib.h>
4#include <getopt.h>
5#include <string.h>
6#include <dlfcn.h>
7
8extern char *optarg;
9extern int optind, opterr, optopt;
10
11static struct option long_options[] = {
12 {"library", required_argument, 0, 'l'},
13 {"symbol", required_argument, 0, 's'},
14 {"help", no_argument, 0, 'h'},
15 {0, 0, 0, 0},
16};
17
18/* This array must parallel long_options[] */
19static const char *descriptions[] = {
20 "specify a library path to look up symbol",
21 "specify symbol to look up",
22 "print this help screen",
23};
24
25void print_help(const char *name) {
26 fprintf(stdout,
27 "invokation:\n"
28 "\t%s [-l <libname>] -s <symbol name>\n"
29 "\t%s -h\n\n", name, name);
30 fprintf(stdout, "options:\n");
31 struct option *opt = long_options;
32 const char **desc = descriptions;
33 while (opt->name) {
34 fprintf(stdout, "\t-%c/--%s%s: %s\n",
35 opt->val,
36 opt->name,
37 (opt->has_arg ? " (argument)" : ""),
38 *desc);
39 opt++;
40 desc++;
41 }
42}
43
44int get_options(int argc, char **argv, char **lib, char **sym)
45{
46 int c;
47
48 *lib = 0;
49 *sym = 0;
50
51 while (1) {
52 /* getopt_long stores the option index here. */
53 int option_index = 0;
54
55 c = getopt_long (argc, argv,
56 "l:s:h",
57 long_options,
58 &option_index);
59 /* Detect the end of the options. */
60 if (c == -1) break;
61
62 switch (c) {
63 case 'l':
64 *lib = strdup(optarg);
65 break;
66 case 's':
67 *sym = strdup(optarg);
68 break;
69 case 'h': print_help(argv[0]); exit(EXIT_FAILURE); break;
70 case '?':
71 /* getopt_long already printed an error message. */
72 break;
73 default:
74 fprintf(stderr, "Unknown option");
75 exit(EXIT_FAILURE);
76 }
77 }
78
79 return optind;
80}
81
82int main(int argc, char **argv)
83{
84 char *libname, *symname, *prog = *argv;
85
86 get_options(argc, argv, &libname, &symname);
87
88 if (symname == NULL) {
89 fprintf(stderr, "You must specify a symbol!\n");
90 print_help(prog);
91 exit(EXIT_FAILURE);
92 }
93
94 {
95 const char *dlerr;
96 void *handle, *symbol;
97
98 printf("opening library [%s]\n", libname);
99 dlerr = dlerror();
100 handle = libname ? dlopen(libname, RTLD_NOW) : RTLD_DEFAULT;
101 dlerr = dlerror();
102 if (dlerr != NULL) fprintf(stderr, "dlopen() error: %s\n", dlerr);
103
104 printf("opening symbol [%s]\n", symname);
105 symbol = dlsym(handle, symname);
106 dlerr = dlerror();
107 if (dlerr != NULL) fprintf(stderr, "dlsym() error: %s\n", dlerr);
108
109 printf("closing library [%s]\n", libname);
110 dlclose(handle);
111 dlerr = dlerror();
112 if (dlerr != NULL) fprintf(stderr, "dlclose() error: %s\n", dlerr);
113 else printf("successfully opened symbol\n");
114 }
115
116 if (libname != NULL) free(libname);
117 if (symname != NULL) free(symname);
118 return 0;
119}