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