1/* plugin-api.h -- External linker plugin API.  */
2
3/* Copyright 2009 Free Software Foundation, Inc.
4   Written by Cary Coutant <ccoutant@google.com>.
5
6   This file is part of binutils.
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 3 of the License, or
11   (at your option) any later version.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program; if not, write to the Free Software
20   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21   MA 02110-1301, USA.  */
22
23/* This file defines the interface for writing a linker plugin, which is
24   described at < http://gcc.gnu.org/wiki/whopr/driver >.  */
25
26#ifndef PLUGIN_API_H
27#define PLUGIN_API_H
28
29#ifdef HAVE_STDINT_H
30#include <stdint.h>
31#elif defined(HAVE_INTTYPES_H)
32#include <inttypes.h>
33#endif
34#include <sys/types.h>
35#if !defined(HAVE_STDINT_H) && !defined(HAVE_INTTYPES_H) && \
36    !defined(UINT64_MAX) && !defined(uint64_t)
37#error can not find uint64_t type
38#endif
39
40#ifdef __cplusplus
41extern "C"
42{
43#endif
44
45/* Status code returned by most API routines.  */
46
47enum ld_plugin_status
48{
49  LDPS_OK = 0,
50  LDPS_NO_SYMS,         /* Attempt to get symbols that haven't been added. */
51  LDPS_BAD_HANDLE,      /* No claimed object associated with given handle. */
52  LDPS_ERR
53  /* Additional Error codes TBD.  */
54};
55
56/* The version of the API specification.  */
57
58enum ld_plugin_api_version
59{
60  LD_PLUGIN_API_VERSION = 1
61};
62
63/* The type of output file being generated by the linker.  */
64
65enum ld_plugin_output_file_type
66{
67  LDPO_REL,
68  LDPO_EXEC,
69  LDPO_DYN
70};
71
72/* An input file managed by the plugin library.  */
73
74struct ld_plugin_input_file
75{
76  const char *name;
77  int fd;
78  off_t offset;
79  off_t filesize;
80  void *handle;
81};
82
83/* A symbol belonging to an input file managed by the plugin library.  */
84
85struct ld_plugin_symbol
86{
87  char *name;
88  char *version;
89  int def;
90  int visibility;
91  uint64_t size;
92  char *comdat_key;
93  int resolution;
94};
95
96/* Whether the symbol is a definition, reference, or common, weak or not.  */
97
98enum ld_plugin_symbol_kind
99{
100  LDPK_DEF,
101  LDPK_WEAKDEF,
102  LDPK_UNDEF,
103  LDPK_WEAKUNDEF,
104  LDPK_COMMON
105};
106
107/* The visibility of the symbol.  */
108
109enum ld_plugin_symbol_visibility
110{
111  LDPV_DEFAULT,
112  LDPV_PROTECTED,
113  LDPV_INTERNAL,
114  LDPV_HIDDEN
115};
116
117/* How a symbol is resolved.  */
118
119enum ld_plugin_symbol_resolution
120{
121  LDPR_UNKNOWN = 0,
122
123  /* Symbol is still undefined at this point.  */
124  LDPR_UNDEF,
125
126  /* This is the prevailing definition of the symbol, with references from
127     regular object code.  */
128  LDPR_PREVAILING_DEF,
129
130  /* This is the prevailing definition of the symbol, with no
131     references from regular objects.  It is only referenced from IR
132     code.  */
133  LDPR_PREVAILING_DEF_IRONLY,
134
135  /* This definition was pre-empted by a definition in a regular
136     object file.  */
137  LDPR_PREEMPTED_REG,
138
139  /* This definition was pre-empted by a definition in another IR file.  */
140  LDPR_PREEMPTED_IR,
141
142  /* This symbol was resolved by a definition in another IR file.  */
143  LDPR_RESOLVED_IR,
144
145  /* This symbol was resolved by a definition in a regular object
146     linked into the main executable.  */
147  LDPR_RESOLVED_EXEC,
148
149  /* This symbol was resolved by a definition in a shared object.  */
150  LDPR_RESOLVED_DYN
151};
152
153/* The plugin library's "claim file" handler.  */
154
155typedef
156enum ld_plugin_status
157(*ld_plugin_claim_file_handler) (
158  const struct ld_plugin_input_file *file, int *claimed);
159
160/* The plugin library's "all symbols read" handler.  */
161
162typedef
163enum ld_plugin_status
164(*ld_plugin_all_symbols_read_handler) (void);
165
166/* The plugin library's cleanup handler.  */
167
168typedef
169enum ld_plugin_status
170(*ld_plugin_cleanup_handler) (void);
171
172/* The linker's interface for registering the "claim file" handler.  */
173
174typedef
175enum ld_plugin_status
176(*ld_plugin_register_claim_file) (ld_plugin_claim_file_handler handler);
177
178/* The linker's interface for registering the "all symbols read" handler.  */
179
180typedef
181enum ld_plugin_status
182(*ld_plugin_register_all_symbols_read) (
183  ld_plugin_all_symbols_read_handler handler);
184
185/* The linker's interface for registering the cleanup handler.  */
186
187typedef
188enum ld_plugin_status
189(*ld_plugin_register_cleanup) (ld_plugin_cleanup_handler handler);
190
191/* The linker's interface for adding symbols from a claimed input file.  */
192
193typedef
194enum ld_plugin_status
195(*ld_plugin_add_symbols) (void *handle, int nsyms,
196                          const struct ld_plugin_symbol *syms);
197
198/* The linker's interface for getting the input file information with
199   an open (possibly re-opened) file descriptor.  */
200
201typedef
202enum ld_plugin_status
203(*ld_plugin_get_input_file) (const void *handle,
204                             struct ld_plugin_input_file *file);
205
206/* The linker's interface for releasing the input file.  */
207
208typedef
209enum ld_plugin_status
210(*ld_plugin_release_input_file) (const void *handle);
211
212/* The linker's interface for retrieving symbol resolution information.  */
213
214typedef
215enum ld_plugin_status
216(*ld_plugin_get_symbols) (const void *handle, int nsyms,
217                          struct ld_plugin_symbol *syms);
218
219/* The linker's interface for adding a compiled input file.  */
220
221typedef
222enum ld_plugin_status
223(*ld_plugin_add_input_file) (char *pathname);
224
225/* The linker's interface for adding a library that should be searched.  */
226
227typedef
228enum ld_plugin_status
229(*ld_plugin_add_input_library) (char *libname);
230
231/* The linker's interface for issuing a warning or error message.  */
232
233typedef
234enum ld_plugin_status
235(*ld_plugin_message) (int level, const char *format, ...);
236
237enum ld_plugin_level
238{
239  LDPL_INFO,
240  LDPL_WARNING,
241  LDPL_ERROR,
242  LDPL_FATAL
243};
244
245/* Values for the tv_tag field of the transfer vector.  */
246
247enum ld_plugin_tag
248{
249  LDPT_NULL = 0,
250  LDPT_API_VERSION,
251  LDPT_GOLD_VERSION,
252  LDPT_LINKER_OUTPUT,
253  LDPT_OPTION,
254  LDPT_REGISTER_CLAIM_FILE_HOOK,
255  LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK,
256  LDPT_REGISTER_CLEANUP_HOOK,
257  LDPT_ADD_SYMBOLS,
258  LDPT_GET_SYMBOLS,
259  LDPT_ADD_INPUT_FILE,
260  LDPT_MESSAGE,
261  LDPT_GET_INPUT_FILE,
262  LDPT_RELEASE_INPUT_FILE,
263  LDPT_ADD_INPUT_LIBRARY
264};
265
266/* The plugin transfer vector.  */
267
268struct ld_plugin_tv
269{
270  enum ld_plugin_tag tv_tag;
271  union
272  {
273    int tv_val;
274    const char *tv_string;
275    ld_plugin_register_claim_file tv_register_claim_file;
276    ld_plugin_register_all_symbols_read tv_register_all_symbols_read;
277    ld_plugin_register_cleanup tv_register_cleanup;
278    ld_plugin_add_symbols tv_add_symbols;
279    ld_plugin_get_symbols tv_get_symbols;
280    ld_plugin_add_input_file tv_add_input_file;
281    ld_plugin_message tv_message;
282    ld_plugin_get_input_file tv_get_input_file;
283    ld_plugin_release_input_file tv_release_input_file;
284    ld_plugin_add_input_library tv_add_input_library;
285  } tv_u;
286};
287
288/* The plugin library's "onload" entry point.  */
289
290typedef
291enum ld_plugin_status
292(*ld_plugin_onload) (struct ld_plugin_tv *tv);
293
294#ifdef __cplusplus
295}
296#endif
297
298#endif /* !defined(PLUGIN_API_H) */
299