xref: /dflybsd-src/contrib/binutils-2.27/bfd/plugin.c (revision a9fa94596c0f48c0524edaac2c001d92fa9c01ac)
1*a9fa9459Szrj /* Plugin support for BFD.
2*a9fa9459Szrj    Copyright (C) 2009-2016 Free Software Foundation, Inc.
3*a9fa9459Szrj 
4*a9fa9459Szrj    This file is part of BFD, the Binary File Descriptor library.
5*a9fa9459Szrj 
6*a9fa9459Szrj    This program is free software; you can redistribute it and/or modify
7*a9fa9459Szrj    it under the terms of the GNU General Public License as published by
8*a9fa9459Szrj    the Free Software Foundation; either version 3 of the License, or
9*a9fa9459Szrj    (at your option) any later version.
10*a9fa9459Szrj 
11*a9fa9459Szrj    This program is distributed in the hope that it will be useful,
12*a9fa9459Szrj    but WITHOUT ANY WARRANTY; without even the implied warranty of
13*a9fa9459Szrj    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*a9fa9459Szrj    GNU General Public License for more details.
15*a9fa9459Szrj 
16*a9fa9459Szrj    You should have received a copy of the GNU General Public License
17*a9fa9459Szrj    along with this program; if not, write to the Free Software
18*a9fa9459Szrj    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19*a9fa9459Szrj    MA 02110-1301, USA.  */
20*a9fa9459Szrj 
21*a9fa9459Szrj #include "sysdep.h"
22*a9fa9459Szrj #include "bfd.h"
23*a9fa9459Szrj 
24*a9fa9459Szrj #if BFD_SUPPORTS_PLUGINS
25*a9fa9459Szrj 
26*a9fa9459Szrj #include <assert.h>
27*a9fa9459Szrj #ifdef HAVE_DLFCN_H
28*a9fa9459Szrj #include <dlfcn.h>
29*a9fa9459Szrj #elif defined (HAVE_WINDOWS_H)
30*a9fa9459Szrj #include <windows.h>
31*a9fa9459Szrj #else
32*a9fa9459Szrj #error Unknown how to handle dynamic-load-libraries.
33*a9fa9459Szrj #endif
34*a9fa9459Szrj #include <stdarg.h>
35*a9fa9459Szrj #include "plugin-api.h"
36*a9fa9459Szrj #include "plugin.h"
37*a9fa9459Szrj #include "libbfd.h"
38*a9fa9459Szrj #include "libiberty.h"
39*a9fa9459Szrj #include <dirent.h>
40*a9fa9459Szrj 
41*a9fa9459Szrj #if !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H)
42*a9fa9459Szrj 
43*a9fa9459Szrj #define RTLD_NOW 0      /* Dummy value.  */
44*a9fa9459Szrj 
45*a9fa9459Szrj static void *
46*a9fa9459Szrj dlopen (const char *file, int mode ATTRIBUTE_UNUSED)
47*a9fa9459Szrj {
48*a9fa9459Szrj   return LoadLibrary (file);
49*a9fa9459Szrj }
50*a9fa9459Szrj 
51*a9fa9459Szrj static void *
52*a9fa9459Szrj dlsym (void *handle, const char *name)
53*a9fa9459Szrj {
54*a9fa9459Szrj   return GetProcAddress (handle, name);
55*a9fa9459Szrj }
56*a9fa9459Szrj 
57*a9fa9459Szrj static int ATTRIBUTE_UNUSED
58*a9fa9459Szrj dlclose (void *handle)
59*a9fa9459Szrj {
60*a9fa9459Szrj   FreeLibrary (handle);
61*a9fa9459Szrj   return 0;
62*a9fa9459Szrj }
63*a9fa9459Szrj 
64*a9fa9459Szrj static const char *
65*a9fa9459Szrj dlerror (void)
66*a9fa9459Szrj {
67*a9fa9459Szrj   return "Unable to load DLL.";
68*a9fa9459Szrj }
69*a9fa9459Szrj 
70*a9fa9459Szrj #endif /* !defined (HAVE_DLFCN_H) && defined (HAVE_WINDOWS_H)  */
71*a9fa9459Szrj 
72*a9fa9459Szrj #define bfd_plugin_close_and_cleanup                  _bfd_generic_close_and_cleanup
73*a9fa9459Szrj #define bfd_plugin_bfd_free_cached_info               _bfd_generic_bfd_free_cached_info
74*a9fa9459Szrj #define bfd_plugin_new_section_hook                   _bfd_generic_new_section_hook
75*a9fa9459Szrj #define bfd_plugin_get_section_contents               _bfd_generic_get_section_contents
76*a9fa9459Szrj #define bfd_plugin_get_section_contents_in_window     _bfd_generic_get_section_contents_in_window
77*a9fa9459Szrj #define bfd_plugin_bfd_copy_private_header_data       _bfd_generic_bfd_copy_private_header_data
78*a9fa9459Szrj #define bfd_plugin_bfd_merge_private_bfd_data         _bfd_generic_bfd_merge_private_bfd_data
79*a9fa9459Szrj #define bfd_plugin_bfd_copy_private_header_data       _bfd_generic_bfd_copy_private_header_data
80*a9fa9459Szrj #define bfd_plugin_bfd_set_private_flags              _bfd_generic_bfd_set_private_flags
81*a9fa9459Szrj #define bfd_plugin_core_file_matches_executable_p     generic_core_file_matches_executable_p
82*a9fa9459Szrj #define bfd_plugin_bfd_is_local_label_name            _bfd_nosymbols_bfd_is_local_label_name
83*a9fa9459Szrj #define bfd_plugin_bfd_is_target_special_symbol       ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
84*a9fa9459Szrj #define bfd_plugin_get_lineno                         _bfd_nosymbols_get_lineno
85*a9fa9459Szrj #define bfd_plugin_find_nearest_line                  _bfd_nosymbols_find_nearest_line
86*a9fa9459Szrj #define bfd_plugin_find_line                          _bfd_nosymbols_find_line
87*a9fa9459Szrj #define bfd_plugin_find_inliner_info                  _bfd_nosymbols_find_inliner_info
88*a9fa9459Szrj #define bfd_plugin_get_symbol_version_string	      _bfd_nosymbols_get_symbol_version_string
89*a9fa9459Szrj #define bfd_plugin_bfd_make_debug_symbol              _bfd_nosymbols_bfd_make_debug_symbol
90*a9fa9459Szrj #define bfd_plugin_read_minisymbols                   _bfd_generic_read_minisymbols
91*a9fa9459Szrj #define bfd_plugin_minisymbol_to_symbol               _bfd_generic_minisymbol_to_symbol
92*a9fa9459Szrj #define bfd_plugin_set_arch_mach                      bfd_default_set_arch_mach
93*a9fa9459Szrj #define bfd_plugin_set_section_contents               _bfd_generic_set_section_contents
94*a9fa9459Szrj #define bfd_plugin_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
95*a9fa9459Szrj #define bfd_plugin_bfd_relax_section                  bfd_generic_relax_section
96*a9fa9459Szrj #define bfd_plugin_bfd_link_hash_table_create         _bfd_generic_link_hash_table_create
97*a9fa9459Szrj #define bfd_plugin_bfd_link_add_symbols               _bfd_generic_link_add_symbols
98*a9fa9459Szrj #define bfd_plugin_bfd_link_just_syms                 _bfd_generic_link_just_syms
99*a9fa9459Szrj #define bfd_plugin_bfd_final_link                     _bfd_generic_final_link
100*a9fa9459Szrj #define bfd_plugin_bfd_link_split_section             _bfd_generic_link_split_section
101*a9fa9459Szrj #define bfd_plugin_bfd_gc_sections                    bfd_generic_gc_sections
102*a9fa9459Szrj #define bfd_plugin_bfd_lookup_section_flags           bfd_generic_lookup_section_flags
103*a9fa9459Szrj #define bfd_plugin_bfd_merge_sections                 bfd_generic_merge_sections
104*a9fa9459Szrj #define bfd_plugin_bfd_is_group_section               bfd_generic_is_group_section
105*a9fa9459Szrj #define bfd_plugin_bfd_discard_group                  bfd_generic_discard_group
106*a9fa9459Szrj #define bfd_plugin_section_already_linked             _bfd_generic_section_already_linked
107*a9fa9459Szrj #define bfd_plugin_bfd_define_common_symbol           bfd_generic_define_common_symbol
108*a9fa9459Szrj #define bfd_plugin_bfd_copy_link_hash_symbol_type     _bfd_generic_copy_link_hash_symbol_type
109*a9fa9459Szrj #define bfd_plugin_bfd_link_check_relocs              _bfd_generic_link_check_relocs
110*a9fa9459Szrj 
111*a9fa9459Szrj static enum ld_plugin_status
112*a9fa9459Szrj message (int level ATTRIBUTE_UNUSED,
113*a9fa9459Szrj 	 const char * format, ...)
114*a9fa9459Szrj {
115*a9fa9459Szrj   va_list args;
116*a9fa9459Szrj   va_start (args, format);
117*a9fa9459Szrj   printf ("bfd plugin: ");
118*a9fa9459Szrj   vprintf (format, args);
119*a9fa9459Szrj   putchar ('\n');
120*a9fa9459Szrj   va_end (args);
121*a9fa9459Szrj   return LDPS_OK;
122*a9fa9459Szrj }
123*a9fa9459Szrj 
124*a9fa9459Szrj /* Register a claim-file handler. */
125*a9fa9459Szrj static ld_plugin_claim_file_handler claim_file;
126*a9fa9459Szrj 
127*a9fa9459Szrj static enum ld_plugin_status
128*a9fa9459Szrj register_claim_file (ld_plugin_claim_file_handler handler)
129*a9fa9459Szrj {
130*a9fa9459Szrj   claim_file = handler;
131*a9fa9459Szrj   return LDPS_OK;
132*a9fa9459Szrj }
133*a9fa9459Szrj 
134*a9fa9459Szrj static enum ld_plugin_status
135*a9fa9459Szrj add_symbols (void * handle,
136*a9fa9459Szrj 	     int nsyms,
137*a9fa9459Szrj 	     const struct ld_plugin_symbol * syms)
138*a9fa9459Szrj {
139*a9fa9459Szrj   bfd *abfd = handle;
140*a9fa9459Szrj   struct plugin_data_struct *plugin_data =
141*a9fa9459Szrj     bfd_alloc (abfd, sizeof (plugin_data_struct));
142*a9fa9459Szrj 
143*a9fa9459Szrj   plugin_data->nsyms = nsyms;
144*a9fa9459Szrj   plugin_data->syms = syms;
145*a9fa9459Szrj 
146*a9fa9459Szrj   if (nsyms != 0)
147*a9fa9459Szrj     abfd->flags |= HAS_SYMS;
148*a9fa9459Szrj 
149*a9fa9459Szrj   abfd->tdata.plugin_data = plugin_data;
150*a9fa9459Szrj   return LDPS_OK;
151*a9fa9459Szrj }
152*a9fa9459Szrj 
153*a9fa9459Szrj static const char *plugin_program_name;
154*a9fa9459Szrj 
155*a9fa9459Szrj void
156*a9fa9459Szrj bfd_plugin_set_program_name (const char *program_name)
157*a9fa9459Szrj {
158*a9fa9459Szrj   plugin_program_name = program_name;
159*a9fa9459Szrj }
160*a9fa9459Szrj 
161*a9fa9459Szrj static int
162*a9fa9459Szrj try_claim (bfd *abfd)
163*a9fa9459Szrj {
164*a9fa9459Szrj   int claimed = 0;
165*a9fa9459Szrj   struct ld_plugin_input_file file;
166*a9fa9459Szrj   bfd *iobfd;
167*a9fa9459Szrj 
168*a9fa9459Szrj   file.name = abfd->filename;
169*a9fa9459Szrj 
170*a9fa9459Szrj   if (abfd->my_archive && !bfd_is_thin_archive (abfd->my_archive))
171*a9fa9459Szrj     {
172*a9fa9459Szrj       iobfd = abfd->my_archive;
173*a9fa9459Szrj       file.offset = abfd->origin;
174*a9fa9459Szrj       file.filesize = arelt_size (abfd);
175*a9fa9459Szrj     }
176*a9fa9459Szrj   else
177*a9fa9459Szrj     {
178*a9fa9459Szrj       iobfd = abfd;
179*a9fa9459Szrj       file.offset = 0;
180*a9fa9459Szrj       file.filesize = 0;
181*a9fa9459Szrj     }
182*a9fa9459Szrj 
183*a9fa9459Szrj   if (!iobfd->iostream && !bfd_open_file (iobfd))
184*a9fa9459Szrj     return 0;
185*a9fa9459Szrj 
186*a9fa9459Szrj   file.fd = fileno ((FILE *) iobfd->iostream);
187*a9fa9459Szrj 
188*a9fa9459Szrj   if (!abfd->my_archive || bfd_is_thin_archive (abfd->my_archive))
189*a9fa9459Szrj     {
190*a9fa9459Szrj       struct stat stat_buf;
191*a9fa9459Szrj       if (fstat (file.fd, &stat_buf))
192*a9fa9459Szrj         return 0;
193*a9fa9459Szrj       file.filesize = stat_buf.st_size;
194*a9fa9459Szrj     }
195*a9fa9459Szrj 
196*a9fa9459Szrj   file.handle = abfd;
197*a9fa9459Szrj   off_t cur_offset = lseek(file.fd, 0, SEEK_CUR);
198*a9fa9459Szrj   claim_file (&file, &claimed);
199*a9fa9459Szrj   lseek(file.fd, cur_offset, SEEK_SET);
200*a9fa9459Szrj   if (!claimed)
201*a9fa9459Szrj     return 0;
202*a9fa9459Szrj 
203*a9fa9459Szrj   return 1;
204*a9fa9459Szrj }
205*a9fa9459Szrj 
206*a9fa9459Szrj static int
207*a9fa9459Szrj try_load_plugin (const char *pname, bfd *abfd, int *has_plugin_p)
208*a9fa9459Szrj {
209*a9fa9459Szrj   void *plugin_handle;
210*a9fa9459Szrj   struct ld_plugin_tv tv[4];
211*a9fa9459Szrj   int i;
212*a9fa9459Szrj   ld_plugin_onload onload;
213*a9fa9459Szrj   enum ld_plugin_status status;
214*a9fa9459Szrj 
215*a9fa9459Szrj   *has_plugin_p = 0;
216*a9fa9459Szrj 
217*a9fa9459Szrj   plugin_handle = dlopen (pname, RTLD_NOW);
218*a9fa9459Szrj   if (!plugin_handle)
219*a9fa9459Szrj     {
220*a9fa9459Szrj       (*_bfd_error_handler)("%s\n", dlerror ());
221*a9fa9459Szrj       return 0;
222*a9fa9459Szrj     }
223*a9fa9459Szrj 
224*a9fa9459Szrj   onload = dlsym (plugin_handle, "onload");
225*a9fa9459Szrj   if (!onload)
226*a9fa9459Szrj     goto err;
227*a9fa9459Szrj 
228*a9fa9459Szrj   i = 0;
229*a9fa9459Szrj   tv[i].tv_tag = LDPT_MESSAGE;
230*a9fa9459Szrj   tv[i].tv_u.tv_message = message;
231*a9fa9459Szrj 
232*a9fa9459Szrj   ++i;
233*a9fa9459Szrj   tv[i].tv_tag = LDPT_REGISTER_CLAIM_FILE_HOOK;
234*a9fa9459Szrj   tv[i].tv_u.tv_register_claim_file = register_claim_file;
235*a9fa9459Szrj 
236*a9fa9459Szrj   ++i;
237*a9fa9459Szrj   tv[i].tv_tag = LDPT_ADD_SYMBOLS;
238*a9fa9459Szrj   tv[i].tv_u.tv_add_symbols = add_symbols;
239*a9fa9459Szrj 
240*a9fa9459Szrj   ++i;
241*a9fa9459Szrj   tv[i].tv_tag = LDPT_NULL;
242*a9fa9459Szrj   tv[i].tv_u.tv_val = 0;
243*a9fa9459Szrj 
244*a9fa9459Szrj   status = (*onload)(tv);
245*a9fa9459Szrj 
246*a9fa9459Szrj   if (status != LDPS_OK)
247*a9fa9459Szrj     goto err;
248*a9fa9459Szrj 
249*a9fa9459Szrj   *has_plugin_p = 1;
250*a9fa9459Szrj 
251*a9fa9459Szrj   abfd->plugin_format = bfd_plugin_no;
252*a9fa9459Szrj 
253*a9fa9459Szrj   if (!claim_file)
254*a9fa9459Szrj     goto err;
255*a9fa9459Szrj 
256*a9fa9459Szrj   if (!try_claim (abfd))
257*a9fa9459Szrj     goto err;
258*a9fa9459Szrj 
259*a9fa9459Szrj   abfd->plugin_format = bfd_plugin_yes;
260*a9fa9459Szrj 
261*a9fa9459Szrj   return 1;
262*a9fa9459Szrj 
263*a9fa9459Szrj  err:
264*a9fa9459Szrj   return 0;
265*a9fa9459Szrj }
266*a9fa9459Szrj 
267*a9fa9459Szrj /* There may be plugin libraries in lib/bfd-plugins.  */
268*a9fa9459Szrj 
269*a9fa9459Szrj static int has_plugin = -1;
270*a9fa9459Szrj 
271*a9fa9459Szrj static const bfd_target *(*ld_plugin_object_p) (bfd *);
272*a9fa9459Szrj 
273*a9fa9459Szrj static const char *plugin_name;
274*a9fa9459Szrj 
275*a9fa9459Szrj void
276*a9fa9459Szrj bfd_plugin_set_plugin (const char *p)
277*a9fa9459Szrj {
278*a9fa9459Szrj   plugin_name = p;
279*a9fa9459Szrj   has_plugin = p != NULL;
280*a9fa9459Szrj }
281*a9fa9459Szrj 
282*a9fa9459Szrj /* Return TRUE if a plugin library is used.  */
283*a9fa9459Szrj 
284*a9fa9459Szrj bfd_boolean
285*a9fa9459Szrj bfd_plugin_specified_p (void)
286*a9fa9459Szrj {
287*a9fa9459Szrj   return has_plugin > 0;
288*a9fa9459Szrj }
289*a9fa9459Szrj 
290*a9fa9459Szrj /* Return TRUE if ABFD can be claimed by linker LTO plugin.  */
291*a9fa9459Szrj 
292*a9fa9459Szrj bfd_boolean
293*a9fa9459Szrj bfd_link_plugin_object_p (bfd *abfd)
294*a9fa9459Szrj {
295*a9fa9459Szrj   if (ld_plugin_object_p)
296*a9fa9459Szrj     return ld_plugin_object_p (abfd) != NULL;
297*a9fa9459Szrj   return FALSE;
298*a9fa9459Szrj }
299*a9fa9459Szrj 
300*a9fa9459Szrj extern const bfd_target plugin_vec;
301*a9fa9459Szrj 
302*a9fa9459Szrj /* Return TRUE if TARGET is a pointer to plugin_vec.  */
303*a9fa9459Szrj 
304*a9fa9459Szrj bfd_boolean
305*a9fa9459Szrj bfd_plugin_target_p (const bfd_target *target)
306*a9fa9459Szrj {
307*a9fa9459Szrj   return target == &plugin_vec;
308*a9fa9459Szrj }
309*a9fa9459Szrj 
310*a9fa9459Szrj /* Register OBJECT_P to be used by bfd_plugin_object_p.  */
311*a9fa9459Szrj 
312*a9fa9459Szrj void
313*a9fa9459Szrj register_ld_plugin_object_p (const bfd_target *(*object_p) (bfd *))
314*a9fa9459Szrj {
315*a9fa9459Szrj   ld_plugin_object_p = object_p;
316*a9fa9459Szrj }
317*a9fa9459Szrj 
318*a9fa9459Szrj static int
319*a9fa9459Szrj load_plugin (bfd *abfd)
320*a9fa9459Szrj {
321*a9fa9459Szrj   char *plugin_dir;
322*a9fa9459Szrj   char *p;
323*a9fa9459Szrj   DIR *d;
324*a9fa9459Szrj   struct dirent *ent;
325*a9fa9459Szrj   int found = 0;
326*a9fa9459Szrj 
327*a9fa9459Szrj   if (!has_plugin)
328*a9fa9459Szrj     return found;
329*a9fa9459Szrj 
330*a9fa9459Szrj   if (plugin_name)
331*a9fa9459Szrj     return try_load_plugin (plugin_name, abfd, &has_plugin);
332*a9fa9459Szrj 
333*a9fa9459Szrj   if (plugin_program_name == NULL)
334*a9fa9459Szrj     return found;
335*a9fa9459Szrj 
336*a9fa9459Szrj   plugin_dir = concat (BINDIR, "/../lib/bfd-plugins", NULL);
337*a9fa9459Szrj   p = make_relative_prefix (plugin_program_name,
338*a9fa9459Szrj 			    BINDIR,
339*a9fa9459Szrj 			    plugin_dir);
340*a9fa9459Szrj   free (plugin_dir);
341*a9fa9459Szrj   plugin_dir = NULL;
342*a9fa9459Szrj 
343*a9fa9459Szrj   d = opendir (p);
344*a9fa9459Szrj   if (!d)
345*a9fa9459Szrj     goto out;
346*a9fa9459Szrj 
347*a9fa9459Szrj   while ((ent = readdir (d)))
348*a9fa9459Szrj     {
349*a9fa9459Szrj       char *full_name;
350*a9fa9459Szrj       struct stat s;
351*a9fa9459Szrj       int valid_plugin;
352*a9fa9459Szrj 
353*a9fa9459Szrj       full_name = concat (p, "/", ent->d_name, NULL);
354*a9fa9459Szrj       if (stat(full_name, &s) == 0 && S_ISREG (s.st_mode))
355*a9fa9459Szrj 	found = try_load_plugin (full_name, abfd, &valid_plugin);
356*a9fa9459Szrj       if (has_plugin <= 0)
357*a9fa9459Szrj 	has_plugin = valid_plugin;
358*a9fa9459Szrj       free (full_name);
359*a9fa9459Szrj       if (found)
360*a9fa9459Szrj 	break;
361*a9fa9459Szrj     }
362*a9fa9459Szrj 
363*a9fa9459Szrj  out:
364*a9fa9459Szrj   free (p);
365*a9fa9459Szrj   if (d)
366*a9fa9459Szrj     closedir (d);
367*a9fa9459Szrj 
368*a9fa9459Szrj   return found;
369*a9fa9459Szrj }
370*a9fa9459Szrj 
371*a9fa9459Szrj 
372*a9fa9459Szrj static const bfd_target *
373*a9fa9459Szrj bfd_plugin_object_p (bfd *abfd)
374*a9fa9459Szrj {
375*a9fa9459Szrj   if (ld_plugin_object_p)
376*a9fa9459Szrj     return ld_plugin_object_p (abfd);
377*a9fa9459Szrj 
378*a9fa9459Szrj   if (abfd->plugin_format == bfd_plugin_unknown && !load_plugin (abfd))
379*a9fa9459Szrj     return NULL;
380*a9fa9459Szrj 
381*a9fa9459Szrj   return abfd->plugin_format == bfd_plugin_yes ? abfd->xvec : NULL;
382*a9fa9459Szrj }
383*a9fa9459Szrj 
384*a9fa9459Szrj /* Copy any private info we understand from the input bfd
385*a9fa9459Szrj    to the output bfd.  */
386*a9fa9459Szrj 
387*a9fa9459Szrj static bfd_boolean
388*a9fa9459Szrj bfd_plugin_bfd_copy_private_bfd_data (bfd *ibfd ATTRIBUTE_UNUSED,
389*a9fa9459Szrj 				      bfd *obfd ATTRIBUTE_UNUSED)
390*a9fa9459Szrj {
391*a9fa9459Szrj   BFD_ASSERT (0);
392*a9fa9459Szrj   return TRUE;
393*a9fa9459Szrj }
394*a9fa9459Szrj 
395*a9fa9459Szrj /* Copy any private info we understand from the input section
396*a9fa9459Szrj    to the output section.  */
397*a9fa9459Szrj 
398*a9fa9459Szrj static bfd_boolean
399*a9fa9459Szrj bfd_plugin_bfd_copy_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
400*a9fa9459Szrj 					  asection *isection ATTRIBUTE_UNUSED,
401*a9fa9459Szrj 					  bfd *obfd ATTRIBUTE_UNUSED,
402*a9fa9459Szrj 					  asection *osection ATTRIBUTE_UNUSED)
403*a9fa9459Szrj {
404*a9fa9459Szrj   BFD_ASSERT (0);
405*a9fa9459Szrj   return TRUE;
406*a9fa9459Szrj }
407*a9fa9459Szrj 
408*a9fa9459Szrj /* Copy any private info we understand from the input symbol
409*a9fa9459Szrj    to the output symbol.  */
410*a9fa9459Szrj 
411*a9fa9459Szrj static bfd_boolean
412*a9fa9459Szrj bfd_plugin_bfd_copy_private_symbol_data (bfd *ibfd ATTRIBUTE_UNUSED,
413*a9fa9459Szrj 					 asymbol *isymbol ATTRIBUTE_UNUSED,
414*a9fa9459Szrj 					 bfd *obfd ATTRIBUTE_UNUSED,
415*a9fa9459Szrj 					 asymbol *osymbol ATTRIBUTE_UNUSED)
416*a9fa9459Szrj {
417*a9fa9459Szrj   BFD_ASSERT (0);
418*a9fa9459Szrj   return TRUE;
419*a9fa9459Szrj }
420*a9fa9459Szrj 
421*a9fa9459Szrj static bfd_boolean
422*a9fa9459Szrj bfd_plugin_bfd_print_private_bfd_data (bfd *abfd ATTRIBUTE_UNUSED, PTR ptr ATTRIBUTE_UNUSED)
423*a9fa9459Szrj {
424*a9fa9459Szrj   BFD_ASSERT (0);
425*a9fa9459Szrj   return TRUE;
426*a9fa9459Szrj }
427*a9fa9459Szrj 
428*a9fa9459Szrj static char *
429*a9fa9459Szrj bfd_plugin_core_file_failing_command (bfd *abfd ATTRIBUTE_UNUSED)
430*a9fa9459Szrj {
431*a9fa9459Szrj   BFD_ASSERT (0);
432*a9fa9459Szrj   return NULL;
433*a9fa9459Szrj }
434*a9fa9459Szrj 
435*a9fa9459Szrj static int
436*a9fa9459Szrj bfd_plugin_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED)
437*a9fa9459Szrj {
438*a9fa9459Szrj   BFD_ASSERT (0);
439*a9fa9459Szrj   return 0;
440*a9fa9459Szrj }
441*a9fa9459Szrj 
442*a9fa9459Szrj static int
443*a9fa9459Szrj bfd_plugin_core_file_pid (bfd *abfd ATTRIBUTE_UNUSED)
444*a9fa9459Szrj {
445*a9fa9459Szrj   BFD_ASSERT (0);
446*a9fa9459Szrj   return 0;
447*a9fa9459Szrj }
448*a9fa9459Szrj 
449*a9fa9459Szrj static long
450*a9fa9459Szrj bfd_plugin_get_symtab_upper_bound (bfd *abfd)
451*a9fa9459Szrj {
452*a9fa9459Szrj   struct plugin_data_struct *plugin_data = abfd->tdata.plugin_data;
453*a9fa9459Szrj   long nsyms = plugin_data->nsyms;
454*a9fa9459Szrj 
455*a9fa9459Szrj   BFD_ASSERT (nsyms >= 0);
456*a9fa9459Szrj 
457*a9fa9459Szrj   return ((nsyms + 1) * sizeof (asymbol *));
458*a9fa9459Szrj }
459*a9fa9459Szrj 
460*a9fa9459Szrj static flagword
461*a9fa9459Szrj convert_flags (const struct ld_plugin_symbol *sym)
462*a9fa9459Szrj {
463*a9fa9459Szrj  switch (sym->def)
464*a9fa9459Szrj    {
465*a9fa9459Szrj    case LDPK_DEF:
466*a9fa9459Szrj    case LDPK_COMMON:
467*a9fa9459Szrj    case LDPK_UNDEF:
468*a9fa9459Szrj      return BSF_GLOBAL;
469*a9fa9459Szrj 
470*a9fa9459Szrj    case LDPK_WEAKUNDEF:
471*a9fa9459Szrj    case LDPK_WEAKDEF:
472*a9fa9459Szrj      return BSF_GLOBAL | BSF_WEAK;
473*a9fa9459Szrj 
474*a9fa9459Szrj    default:
475*a9fa9459Szrj      BFD_ASSERT (0);
476*a9fa9459Szrj      return 0;
477*a9fa9459Szrj    }
478*a9fa9459Szrj }
479*a9fa9459Szrj 
480*a9fa9459Szrj static long
481*a9fa9459Szrj bfd_plugin_canonicalize_symtab (bfd *abfd,
482*a9fa9459Szrj 				asymbol **alocation)
483*a9fa9459Szrj {
484*a9fa9459Szrj   struct plugin_data_struct *plugin_data = abfd->tdata.plugin_data;
485*a9fa9459Szrj   long nsyms = plugin_data->nsyms;
486*a9fa9459Szrj   const struct ld_plugin_symbol *syms = plugin_data->syms;
487*a9fa9459Szrj   static asection fake_section;
488*a9fa9459Szrj   static asection fake_common_section;
489*a9fa9459Szrj   int i;
490*a9fa9459Szrj 
491*a9fa9459Szrj   fake_section.name = ".text";
492*a9fa9459Szrj   fake_common_section.flags = SEC_IS_COMMON;
493*a9fa9459Szrj 
494*a9fa9459Szrj   for (i = 0; i < nsyms; i++)
495*a9fa9459Szrj     {
496*a9fa9459Szrj       asymbol *s = bfd_alloc (abfd, sizeof (asymbol));
497*a9fa9459Szrj 
498*a9fa9459Szrj       BFD_ASSERT (s);
499*a9fa9459Szrj       alocation[i] = s;
500*a9fa9459Szrj 
501*a9fa9459Szrj       s->the_bfd = abfd;
502*a9fa9459Szrj       s->name = syms[i].name;
503*a9fa9459Szrj       s->value = 0;
504*a9fa9459Szrj       s->flags = convert_flags (&syms[i]);
505*a9fa9459Szrj       switch (syms[i].def)
506*a9fa9459Szrj 	{
507*a9fa9459Szrj 	case LDPK_COMMON:
508*a9fa9459Szrj 	  s->section = &fake_common_section;
509*a9fa9459Szrj 	  break;
510*a9fa9459Szrj 	case LDPK_UNDEF:
511*a9fa9459Szrj 	case LDPK_WEAKUNDEF:
512*a9fa9459Szrj 	  s->section = bfd_und_section_ptr;
513*a9fa9459Szrj 	  break;
514*a9fa9459Szrj 	case LDPK_DEF:
515*a9fa9459Szrj 	case LDPK_WEAKDEF:
516*a9fa9459Szrj 	  s->section = &fake_section;
517*a9fa9459Szrj 	  break;
518*a9fa9459Szrj 	default:
519*a9fa9459Szrj 	  BFD_ASSERT (0);
520*a9fa9459Szrj 	}
521*a9fa9459Szrj 
522*a9fa9459Szrj       s->udata.p = (void *) &syms[i];
523*a9fa9459Szrj     }
524*a9fa9459Szrj 
525*a9fa9459Szrj   return nsyms;
526*a9fa9459Szrj }
527*a9fa9459Szrj 
528*a9fa9459Szrj static void
529*a9fa9459Szrj bfd_plugin_print_symbol (bfd *abfd ATTRIBUTE_UNUSED,
530*a9fa9459Szrj 			 PTR afile ATTRIBUTE_UNUSED,
531*a9fa9459Szrj 			 asymbol *symbol ATTRIBUTE_UNUSED,
532*a9fa9459Szrj 			 bfd_print_symbol_type how ATTRIBUTE_UNUSED)
533*a9fa9459Szrj {
534*a9fa9459Szrj   BFD_ASSERT (0);
535*a9fa9459Szrj }
536*a9fa9459Szrj 
537*a9fa9459Szrj static void
538*a9fa9459Szrj bfd_plugin_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
539*a9fa9459Szrj 			    asymbol *symbol,
540*a9fa9459Szrj 			    symbol_info *ret)
541*a9fa9459Szrj {
542*a9fa9459Szrj   bfd_symbol_info (symbol, ret);
543*a9fa9459Szrj }
544*a9fa9459Szrj 
545*a9fa9459Szrj /* Make an empty symbol. */
546*a9fa9459Szrj 
547*a9fa9459Szrj static asymbol *
548*a9fa9459Szrj bfd_plugin_make_empty_symbol (bfd *abfd)
549*a9fa9459Szrj {
550*a9fa9459Szrj   asymbol *new_symbol = bfd_zalloc (abfd, sizeof (asymbol));
551*a9fa9459Szrj   if (new_symbol == NULL)
552*a9fa9459Szrj     return new_symbol;
553*a9fa9459Szrj   new_symbol->the_bfd = abfd;
554*a9fa9459Szrj   return new_symbol;
555*a9fa9459Szrj }
556*a9fa9459Szrj 
557*a9fa9459Szrj static int
558*a9fa9459Szrj bfd_plugin_sizeof_headers (bfd *a ATTRIBUTE_UNUSED,
559*a9fa9459Szrj 			   struct bfd_link_info *info ATTRIBUTE_UNUSED)
560*a9fa9459Szrj {
561*a9fa9459Szrj   BFD_ASSERT (0);
562*a9fa9459Szrj   return 0;
563*a9fa9459Szrj }
564*a9fa9459Szrj 
565*a9fa9459Szrj const bfd_target plugin_vec =
566*a9fa9459Szrj {
567*a9fa9459Szrj   "plugin",			/* Name.  */
568*a9fa9459Szrj   bfd_target_unknown_flavour,
569*a9fa9459Szrj   BFD_ENDIAN_LITTLE,		/* Target byte order.  */
570*a9fa9459Szrj   BFD_ENDIAN_LITTLE,		/* Target headers byte order.  */
571*a9fa9459Szrj   (HAS_RELOC | EXEC_P |		/* Object flags.  */
572*a9fa9459Szrj    HAS_LINENO | HAS_DEBUG |
573*a9fa9459Szrj    HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
574*a9fa9459Szrj   (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
575*a9fa9459Szrj    | SEC_ALLOC | SEC_LOAD | SEC_RELOC),	/* Section flags.  */
576*a9fa9459Szrj   0,				/* symbol_leading_char.  */
577*a9fa9459Szrj   '/',				/* ar_pad_char.  */
578*a9fa9459Szrj   15,				/* ar_max_namelen.  */
579*a9fa9459Szrj   255,				/* match priority.  */
580*a9fa9459Szrj 
581*a9fa9459Szrj   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
582*a9fa9459Szrj   bfd_getl32, bfd_getl_signed_32, bfd_putl32,
583*a9fa9459Szrj   bfd_getl16, bfd_getl_signed_16, bfd_putl16,	/* data */
584*a9fa9459Szrj   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
585*a9fa9459Szrj   bfd_getl32, bfd_getl_signed_32, bfd_putl32,
586*a9fa9459Szrj   bfd_getl16, bfd_getl_signed_16, bfd_putl16,	/* hdrs */
587*a9fa9459Szrj 
588*a9fa9459Szrj   {				/* bfd_check_format.  */
589*a9fa9459Szrj     _bfd_dummy_target,
590*a9fa9459Szrj     bfd_plugin_object_p,
591*a9fa9459Szrj     bfd_generic_archive_p,
592*a9fa9459Szrj     _bfd_dummy_target
593*a9fa9459Szrj   },
594*a9fa9459Szrj   {				/* bfd_set_format.  */
595*a9fa9459Szrj     bfd_false,
596*a9fa9459Szrj     bfd_false,
597*a9fa9459Szrj     _bfd_generic_mkarchive,
598*a9fa9459Szrj     bfd_false,
599*a9fa9459Szrj   },
600*a9fa9459Szrj   {				/* bfd_write_contents.  */
601*a9fa9459Szrj     bfd_false,
602*a9fa9459Szrj     bfd_false,
603*a9fa9459Szrj     _bfd_write_archive_contents,
604*a9fa9459Szrj     bfd_false,
605*a9fa9459Szrj   },
606*a9fa9459Szrj 
607*a9fa9459Szrj   BFD_JUMP_TABLE_GENERIC (bfd_plugin),
608*a9fa9459Szrj   BFD_JUMP_TABLE_COPY (bfd_plugin),
609*a9fa9459Szrj   BFD_JUMP_TABLE_CORE (bfd_plugin),
610*a9fa9459Szrj #ifdef USE_64_BIT_ARCHIVE
611*a9fa9459Szrj   BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_64_bit),
612*a9fa9459Szrj #else
613*a9fa9459Szrj   BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
614*a9fa9459Szrj #endif
615*a9fa9459Szrj   BFD_JUMP_TABLE_SYMBOLS (bfd_plugin),
616*a9fa9459Szrj   BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
617*a9fa9459Szrj   BFD_JUMP_TABLE_WRITE (bfd_plugin),
618*a9fa9459Szrj   BFD_JUMP_TABLE_LINK (bfd_plugin),
619*a9fa9459Szrj   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
620*a9fa9459Szrj 
621*a9fa9459Szrj   NULL,
622*a9fa9459Szrj 
623*a9fa9459Szrj   NULL  			/* backend_data.  */
624*a9fa9459Szrj };
625*a9fa9459Szrj #endif /* BFD_SUPPORTS_PLUGIN */
626