package / ocaml-base-compiler.4.10.0 / tools / objinfo_helper.c
1 /**************************************************************************/
2 /* */
3 /* OCaml */
4 /* */
5 /* Mehdi Dogguy, PPS laboratory, University Paris Diderot */
6 /* */
7 /* Copyright 2010 Mehdi Dogguy */
8 /* */
9 /* All rights reserved. This file is distributed under the terms of */
10 /* the GNU Lesser General Public License version 2.1, with the */
11 /* special exception on linking described in the file LICENSE. */
12 /* */
13 /**************************************************************************/
14
15 #include "caml/s.h"
16 #include <stdio.h>
17
18 #ifdef HAS_LIBBFD
19 #include <stdlib.h>
20 #include <string.h>
21 #include <stdarg.h>
22
23 // PACKAGE: protect against binutils change
24 // https://sourceware.org/bugzilla/show_bug.cgi?id=14243
25 #define PACKAGE "ocamlobjinfo"
26 #include <bfd.h>
27 #undef PACKAGE
28
29 #define plugin_header_sym (symbol_prefix "caml_plugin_header")
30
31 /* We need to refer to a few functions of the BFD library that are */
32 /* actually defined as macros. We thus define equivalent */
33 /* functions below */
34
35 long get_static_symtab_upper_bound(bfd *fd)
36 {
37 return bfd_get_symtab_upper_bound(fd);
38 }
39
40 long get_dynamic_symtab_upper_bound(bfd *fd)
41 {
42 return bfd_get_dynamic_symtab_upper_bound(fd);
43 }
44
45 long canonicalize_static_symtab(bfd * fd, asymbol **symbolTable)
46 {
47 return bfd_canonicalize_symtab(fd, symbolTable);
48 }
49
50 long canonicalize_dynamic_symtab(bfd * fd, asymbol **symbolTable)
51 {
52 return bfd_canonicalize_dynamic_symtab(fd, symbolTable);
53 }
54
55 typedef struct {
56 long (*get_upper_bound)(bfd *);
57 long (*canonicalize)(bfd *, asymbol **);
58 } symTable_ops;
59
60 symTable_ops staticSymTable_ops = {
61 &get_static_symtab_upper_bound,
62 &canonicalize_static_symtab
63 };
64
65 symTable_ops dynamicSymTable_ops = {
66 &get_dynamic_symtab_upper_bound,
67 &canonicalize_dynamic_symtab
68 };
69
70 /* Print an error message and exit */
71 static void error(bfd *fd, char *msg, ...)
72 {
73 va_list ap;
74 va_start(ap, msg);
75 vfprintf (stderr, msg, ap);
76 va_end(ap);
77 fprintf(stderr, "\n");
78 if (fd!=NULL) bfd_close(fd);
79 exit(2);
80 }
81
82 /* Look for plugin_header_sym in the specified symbol table */
83 /* Return its address, -1 if not found */
84 long lookup(bfd* fd, symTable_ops *ops)
85 {
86 long st_size;
87 asymbol ** symbol_table;
88 long sym_count, i;
89
90 st_size = ops->get_upper_bound (fd);
91 if (st_size <= 0) return -1;
92
93 symbol_table = malloc(st_size);
94 if (! symbol_table)
95 error(fd, "Error: out of memory");
96
97 sym_count = ops->canonicalize (fd, symbol_table);
98
99 for (i = 0; i < sym_count; i++) {
100 if (strcmp(symbol_table[i]->name, plugin_header_sym) == 0)
101 return symbol_table[i]->value;
102 }
103 return -1;
104 }
105
106 int main(int argc, char ** argv)
107 {
108 bfd *fd;
109 asection *sec;
110 file_ptr offset;
111 long value;
112
113 if (argc != 2)
114 error(NULL, "Usage: objinfo_helper <dynamic library>");
115
116 fd = bfd_openr(argv[1], "default");
117 if (!fd)
118 error(NULL, "Error opening file %s", argv[1]);
119 if (! bfd_check_format (fd, bfd_object))
120 error(fd, "Error: wrong format");
121
122 sec = bfd_get_section_by_name(fd, ".data");
123 if (! sec)
124 error(fd, "Error: section .data not found");
125
126 offset = sec->filepos;
127
128 value = lookup(fd, &dynamicSymTable_ops);
129
130 if (value == -1)
131 value = lookup(fd, &staticSymTable_ops);
132 bfd_close(fd);
133
134 if (value == -1)
135 error(NULL, "Error: missing symbol %s", plugin_header_sym);
136
137 printf("%ld\n", (long) offset + value);
138 }
139
140 #else
141
142 int main(int argc, char ** argv)
143 {
144 fprintf(stderr,"BFD library unavailable, cannot print info on .cmxs files\n");
145 return 2;
146 }
147
148 #endif
149