diff --git a/bfd/Makefile.am b/bfd/Makefile.am index bacf88f..7f22aee 100644 --- a/bfd/Makefile.am +++ b/bfd/Makefile.am @@ -25,7 +25,7 @@ bfdlib_LTLIBRARIES = libbfd.la WARN_CFLAGS = @WARN_CFLAGS@ NO_WERROR = @NO_WERROR@ -AM_CFLAGS = $(WARN_CFLAGS) $(LFS_CFLAGS) +AM_CFLAGS = $(WARN_CFLAGS) $(LFS_CFLAGS) -DBINDIR='"$(bindir)"' # bfd.h goes here, for now BFD_H = bfd.h @@ -355,6 +355,7 @@ BFD32_BACKENDS = \ pe-mips.lo \ pei-mips.lo \ peigen.lo \ + plugin.lo \ ppcboot.lo \ reloc16.lo \ riscix.lo \ @@ -534,6 +535,7 @@ BFD32_BACKENDS_CFILES = \ pei-sh.c \ pe-mips.c \ pei-mips.c \ + plugin.c \ ppcboot.c \ reloc16.c \ riscix.c \ @@ -1117,6 +1119,7 @@ cpu-ia64.lo: cpu-ia64.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h \ cpu-ia64-opc.c $(srcdir)/../opcodes/ia64-opc.h $(INCDIR)/opcode/ia64.h cpu-i370.lo: cpu-i370.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h cpu-i386.lo: cpu-i386.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h +cpu-plugin.lo: cpu-i386.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h cpu-i860.lo: cpu-i860.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h cpu-i960.lo: cpu-i960.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h cpu-ip2k.lo: cpu-ip2k.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h diff --git a/bfd/archures.c b/bfd/archures.c index 0a78542..9e84b88 100644 --- a/bfd/archures.c +++ b/bfd/archures.c @@ -204,6 +204,7 @@ DESCRIPTION .#define bfd_mach_h8300sx 6 .#define bfd_mach_h8300sxn 7 . bfd_arch_pdp11, {* DEC PDP-11 *} +. bfd_arch_plugin, . bfd_arch_powerpc, {* PowerPC *} .#define bfd_mach_ppc 32 .#define bfd_mach_ppc64 64 @@ -501,6 +502,7 @@ extern const bfd_arch_info_type bfd_openrisc_arch; extern const bfd_arch_info_type bfd_or32_arch; extern const bfd_arch_info_type bfd_pdp11_arch; extern const bfd_arch_info_type bfd_pj_arch; +extern const bfd_arch_info_type bfd_plugin_arch; extern const bfd_arch_info_type bfd_powerpc_archs[]; #define bfd_powerpc_arch bfd_powerpc_archs[0] extern const bfd_arch_info_type bfd_rs6000_arch; diff --git a/bfd/bfd.c b/bfd/bfd.c index 3be7a63..058289b 100644 --- a/bfd/bfd.c +++ b/bfd/bfd.c @@ -241,6 +241,7 @@ CODE_FRAGMENT . struct netbsd_core_struct *netbsd_core_data; . struct mach_o_data_struct *mach_o_data; . struct mach_o_fat_data_struct *mach_o_fat_data; +. struct plugin_data_struct *plugin_data; . struct bfd_pef_data_struct *pef_data; . struct bfd_pef_xlib_data_struct *pef_xlib_data; . struct bfd_sym_data_struct *sym_data; @@ -394,6 +395,42 @@ const char *const bfd_errmsgs[] = N_("#") }; +static const char *plugin_name; + +/* +FUNCTION + bfd_plugin_set_plugin + +SYNOPSIS + void bfd_plugin_set_plugin (const char *p); + +DESCRIPTION + Set the plugin file. +*/ + +void +bfd_plugin_set_plugin (const char *p) +{ + plugin_name = p; +} + +/* +FUNCTION + bfd_plugin_get_plugin + +SYNOPSIS + const char * bfd_plugin_get_plugin (void); + +DESCRIPTION + Get the plugin file. +*/ + +const char * +bfd_plugin_get_plugin (void) +{ + return plugin_name; +} + /* FUNCTION bfd_get_error diff --git a/bfd/config.bfd b/bfd/config.bfd index 56894ad..545d848 100644 --- a/bfd/config.bfd +++ b/bfd/config.bfd @@ -137,6 +137,11 @@ case "${targ}" in exit 1 ;; + plugin) + targ_defvec=plugin_vec + targ_selvecs="plugin_vec" + ;; + # START OF targmatch.h #ifdef BFD64 alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu) diff --git a/bfd/configure.in b/bfd/configure.in index dd5f37d..f1096dc 100644 --- a/bfd/configure.in +++ b/bfd/configure.in @@ -552,6 +552,19 @@ AC_SUBST(SHARED_LIBADD) # target stuff: +AC_ARG_ENABLE([plugins], +[ --enable-plugins linker plugins], +[case "${enableval}" in + yes | "") plugins=yes ;; + no) plugins=no ;; + *) plugins=yes ;; + esac], +[plugins=no]) + +if test "$plugins" = "yes"; then + enable_targets="$enable_targets plugin"; +fi + # Canonicalize the secondary target names. if test -n "$enable_targets" ; then for targ in `echo $enable_targets | sed 's/,/ /g'` @@ -877,6 +890,7 @@ do pef_vec) tb="$tb pef.lo" ;; pef_xlib_vec) tb="$tb pef.lo" ;; pdp11_aout_vec) tb="$tb pdp11.lo" ;; + plugin_vec) tb="$tb plugin.lo" ;; pmac_xcoff_vec) tb="$tb coff-rs6000.lo xcofflink.lo" ;; ppcboot_vec) tb="$tb ppcboot.lo" ;; riscix_vec) tb="$tb aout32.lo riscix.lo" ;; diff --git a/bfd/cpu-plugin.c b/bfd/cpu-plugin.c new file mode 100644 index 0000000..be28bb3 --- /dev/null +++ b/bfd/cpu-plugin.c @@ -0,0 +1,40 @@ +/* BFD support for plugins. + Copyright 1992, 1994, 1995, 1996, 1998, 2000, 2001, 2002, 2004, 2007 + Free Software Foundation, Inc. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include "sysdep.h" +#include "bfd.h" +#include "libbfd.h" + +const bfd_arch_info_type bfd_plugin_arch = +{ + 32, /* 32 bits in a word */ + 32, /* 32 bits in an address */ + 8, /* 8 bits in a byte */ + bfd_arch_plugin, + 0, /* only 1 machine */ + "plugin", + "plugin", + 3, + TRUE, + bfd_default_compatible, + bfd_default_scan, + 0 +}; diff --git a/bfd/plugin.c b/bfd/plugin.c new file mode 100644 index 0000000..ecaee41 --- /dev/null +++ b/bfd/plugin.c @@ -0,0 +1,476 @@ +/* Plugin support for BFD. + Copyright 1999, 2000, 2001, 2002, 2003, 2005, 2007, 2008 + Free Software Foundation, Inc. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include +#include +#include +#include "plugin-api.h" +#include "sysdep.h" +#include "plugin.h" +#include "libbfd.h" +#include "libiberty.h" +#include + +#define bfd_plugin_close_and_cleanup _bfd_generic_close_and_cleanup +#define bfd_plugin_bfd_free_cached_info _bfd_generic_bfd_free_cached_info +#define bfd_plugin_new_section_hook _bfd_generic_new_section_hook +#define bfd_plugin_get_section_contents _bfd_generic_get_section_contents +#define bfd_plugin_get_section_contents_in_window _bfd_generic_get_section_contents_in_window +#define bfd_plugin_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data +#define bfd_plugin_bfd_merge_private_bfd_data _bfd_generic_bfd_merge_private_bfd_data +#define bfd_plugin_bfd_copy_private_header_data _bfd_generic_bfd_copy_private_header_data +#define bfd_plugin_bfd_set_private_flags _bfd_generic_bfd_set_private_flags +#define bfd_plugin_core_file_matches_executable_p generic_core_file_matches_executable_p +#define bfd_plugin_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name +#define bfd_plugin_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false) +#define bfd_plugin_get_lineno _bfd_nosymbols_get_lineno +#define bfd_plugin_find_nearest_line _bfd_nosymbols_find_nearest_line +#define bfd_plugin_find_inliner_info _bfd_nosymbols_find_inliner_info +#define bfd_plugin_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol +#define bfd_plugin_read_minisymbols _bfd_generic_read_minisymbols +#define bfd_plugin_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol +#define bfd_plugin_set_arch_mach bfd_default_set_arch_mach +#define bfd_plugin_set_section_contents _bfd_generic_set_section_contents +#define bfd_plugin_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents +#define bfd_plugin_bfd_relax_section bfd_generic_relax_section +#define bfd_plugin_bfd_link_hash_table_create _bfd_generic_link_hash_table_create +#define bfd_plugin_bfd_link_hash_table_free _bfd_generic_link_hash_table_free +#define bfd_plugin_bfd_link_add_symbols _bfd_generic_link_add_symbols +#define bfd_plugin_bfd_link_just_syms _bfd_generic_link_just_syms +#define bfd_plugin_bfd_final_link _bfd_generic_final_link +#define bfd_plugin_bfd_link_split_section _bfd_generic_link_split_section +#define bfd_plugin_bfd_gc_sections bfd_generic_gc_sections +#define bfd_plugin_bfd_merge_sections bfd_generic_merge_sections +#define bfd_plugin_bfd_is_group_section bfd_generic_is_group_section +#define bfd_plugin_bfd_discard_group bfd_generic_discard_group +#define bfd_plugin_section_already_linked _bfd_generic_section_already_linked +#define bfd_plugin_bfd_define_common_symbol bfd_generic_define_common_symbol + +static enum ld_plugin_status +message (int level ATTRIBUTE_UNUSED, + const char * format, ...) +{ + va_list args; + va_start (args, format); + vprintf (format, args); + va_end (args); + return LDPS_OK; +} + +// Register a claim-file handler. +static ld_plugin_claim_file_handler claim_file; + +static enum ld_plugin_status +register_claim_file (ld_plugin_claim_file_handler handler) +{ + claim_file = handler; + return LDPS_OK; +} + +static enum ld_plugin_status +add_symbols (void* handle, int nsyms, + const struct ld_plugin_symbol *syms) +{ + bfd *abfd = handle; + struct plugin_data_struct *plugin_data = + bfd_alloc (abfd, sizeof (plugin_data_struct));; + + plugin_data->nsyms = nsyms; + plugin_data->syms = syms; + + if (nsyms != 0) + abfd->flags |= HAS_SYMS; + + abfd->tdata.plugin_data = plugin_data; + return LDPS_OK; +} + +extern char *program_name __attribute__ ((weak)); + +static int +try_load_plugin (const char *pname) +{ + static void *plugin_handle; + int tv_size = 4; + struct ld_plugin_tv tv[tv_size]; + int i; + ld_plugin_onload onload; + enum ld_plugin_status status; + + plugin_handle = dlopen (pname, RTLD_NOW); + if (!plugin_handle) + { + fprintf (stderr, "%s\n", dlerror()); + return 0; + } + + onload = dlsym (plugin_handle, "onload"); + if (!onload) + goto err; + + i = 0; + tv[i].tv_tag = LDPT_MESSAGE; + tv[i].tv_u.tv_message = message; + + ++i; + tv[i].tv_tag = LDPT_REGISTER_CLAIM_FILE_HOOK; + tv[i].tv_u.tv_register_claim_file = register_claim_file; + + ++i; + tv[i].tv_tag = LDPT_ADD_SYMBOLS; + tv[i].tv_u.tv_add_symbols = add_symbols; + + ++i; + tv[i].tv_tag = LDPT_NULL; + tv[i].tv_u.tv_val = 0; + + status = (*onload)(tv); + + if (status != LDPS_OK) + goto err; + + if (!claim_file) + goto err; + + return 1; + + err: + plugin_handle = NULL; + return 0; +} + +static int +load_plugin (void) +{ + char *plugin_dir; + char *p; + DIR *d; + struct dirent *ent; + int found = 0; + const char *pname = bfd_plugin_get_plugin (); + + if (pname) + return try_load_plugin (pname); + + plugin_dir = concat (BINDIR, "/../lib/bfd-plugins", NULL); + p = make_relative_prefix (program_name, + BINDIR, + plugin_dir); + free (plugin_dir); + plugin_dir = NULL; + + d = opendir (p); + if (!d) + goto out; + + while ((ent = readdir (d))) + { + char *full_name; + if (ent->d_type != DT_REG && ent->d_type != DT_LNK) + continue; + + full_name = concat (p, "/", ent->d_name, NULL); + found = try_load_plugin (full_name); + free (full_name); + if (found) + break; + } + + out: + free (p); + if (d) + closedir (d); + + return found; +} + + +static const bfd_target * +bfd_plugin_object_p (bfd *abfd) +{ + int claimed = 0; + int t = load_plugin (); + struct ld_plugin_input_file file; + if (!t) + return NULL; + + file.name = abfd->filename; + + if (abfd->iostream) + { + file.fd = fileno (abfd->iostream); + file.offset = 0; + file.filesize = 0; /*FIXME*/ + } + else + { + bfd *archive = abfd->my_archive; + BFD_ASSERT (archive); + file.fd = fileno (archive->iostream); + file.offset = abfd->origin; + file.filesize = arelt_size (abfd); + + } + file.handle = abfd; + claim_file (&file, &claimed); + if (!claimed) + return NULL; + + return abfd->xvec; +} + +/* Copy any private info we understand from the input bfd + to the output bfd. */ + +static bfd_boolean +bfd_plugin_bfd_copy_private_bfd_data (bfd *ibfd ATTRIBUTE_UNUSED, + bfd *obfd ATTRIBUTE_UNUSED) +{ + BFD_ASSERT (0); + return TRUE; +} + +/* Copy any private info we understand from the input section + to the output section. */ + +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) +{ + BFD_ASSERT (0); + return TRUE; +} + +/* Copy any private info we understand from the input symbol + to the output symbol. */ + +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) +{ + BFD_ASSERT (0); + return TRUE; +} + +static bfd_boolean +bfd_plugin_bfd_print_private_bfd_data (bfd *abfd ATTRIBUTE_UNUSED, PTR ptr ATTRIBUTE_UNUSED) +{ + BFD_ASSERT (0); + return TRUE; +} + +static char * +bfd_plugin_core_file_failing_command (bfd *abfd ATTRIBUTE_UNUSED) +{ + BFD_ASSERT (0); + return NULL; +} + +static int +bfd_plugin_core_file_failing_signal (bfd *abfd ATTRIBUTE_UNUSED) +{ + BFD_ASSERT (0); + return 0; +} + +static long +bfd_plugin_get_symtab_upper_bound (bfd *abfd) +{ + struct plugin_data_struct *plugin_data = abfd->tdata.plugin_data; + long nsyms = plugin_data->nsyms; + + BFD_ASSERT (nsyms >= 0); + + return ((nsyms + 1) * sizeof (asymbol *)); +} + +static flagword +convert_flags (const struct ld_plugin_symbol *sym) +{ + switch (sym->def) + { + case LDPK_DEF: + case LDPK_COMMON: + case LDPK_UNDEF: + return BSF_GLOBAL; + + case LDPK_WEAKUNDEF: + case LDPK_WEAKDEF: + return BSF_GLOBAL | BSF_WEAK; + + default: + BFD_ASSERT (0); + return 0; + } +} + +static long +bfd_plugin_canonicalize_symtab (bfd *abfd, + asymbol **alocation) +{ + struct plugin_data_struct *plugin_data = abfd->tdata.plugin_data; + long nsyms = plugin_data->nsyms; + const struct ld_plugin_symbol *syms = plugin_data->syms; + static asection fake_section; + static asection fake_common_section; + int i; + + fake_section.name = ".text"; + fake_common_section.flags = SEC_IS_COMMON; + + for (i = 0; i < nsyms; i++) + { + asymbol *s = bfd_alloc (abfd, sizeof (asymbol)); + + BFD_ASSERT (s); + alocation[i] = s; + + s->the_bfd = abfd; + s->name = syms[i].name; + s->value = 0; + s->flags = convert_flags (&syms[i]); + switch (syms[i].def) + { + case LDPK_COMMON: + s->section = &fake_common_section; + break; + case LDPK_UNDEF: + case LDPK_WEAKUNDEF: + s->section = bfd_und_section_ptr; + break; + case LDPK_DEF: + case LDPK_WEAKDEF: + s->section = &fake_section; + break; + default: + BFD_ASSERT (0); + } + + s->udata.p = (void *) &syms[i]; + } + + return nsyms; +} + +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) +{ + BFD_ASSERT (0); +} + +static void +bfd_plugin_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED, + asymbol *symbol, + symbol_info *ret) +{ + bfd_symbol_info (symbol, ret); +} + +/* Make an empty symbol. */ + +static asymbol * +bfd_plugin_make_empty_symbol (bfd *abfd) +{ + asymbol *new = bfd_zalloc (abfd, sizeof (asymbol)); + if (new == NULL) + return new; + new->the_bfd = abfd; + return new; +} + +static int +bfd_plugin_sizeof_headers (bfd *a ATTRIBUTE_UNUSED, + struct bfd_link_info *info ATTRIBUTE_UNUSED) +{ + BFD_ASSERT (0); + return 0; +} + +static bfd_boolean +bfd_plugin_mkobject (bfd *abfd ATTRIBUTE_UNUSED) +{ + BFD_ASSERT (0); + return 0; +} + +const bfd_target plugin_vec = +{ + "plugin", /* Name. */ + bfd_target_unknown_flavour, + BFD_ENDIAN_LITTLE, /* Target byte order. */ + BFD_ENDIAN_LITTLE, /* Target headers byte order. */ + (HAS_RELOC | EXEC_P | /* Object flags. */ + HAS_LINENO | HAS_DEBUG | + HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED), + (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS + | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* Section flags. */ + 0, /* symbol_leading_char. */ + '/', /* ar_pad_char. */ + 15, /* ar_max_namelen. */ + + bfd_getl64, bfd_getl_signed_64, bfd_putl64, + bfd_getl32, bfd_getl_signed_32, bfd_putl32, + bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ + bfd_getl64, bfd_getl_signed_64, bfd_putl64, + bfd_getl32, bfd_getl_signed_32, bfd_putl32, + bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ + + { /* bfd_check_format. */ + _bfd_dummy_target, + bfd_plugin_object_p, + bfd_generic_archive_p, + _bfd_dummy_target + }, + { /* bfd_set_format. */ + bfd_false, + bfd_plugin_mkobject, + _bfd_generic_mkarchive, + bfd_false, + }, + { /* bfd_write_contents. */ + bfd_false, + bfd_false, + _bfd_write_archive_contents, + bfd_false, + }, + + BFD_JUMP_TABLE_GENERIC (bfd_plugin), + BFD_JUMP_TABLE_COPY (bfd_plugin), + BFD_JUMP_TABLE_CORE (bfd_plugin), + BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff), + BFD_JUMP_TABLE_SYMBOLS (bfd_plugin), + BFD_JUMP_TABLE_RELOCS (_bfd_norelocs), + BFD_JUMP_TABLE_WRITE (bfd_plugin), + BFD_JUMP_TABLE_LINK (bfd_plugin), + BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), + + NULL, + + /* backend_data: */ + NULL +}; diff --git a/bfd/plugin.h b/bfd/plugin.h new file mode 100644 index 0000000..37392b0 --- /dev/null +++ b/bfd/plugin.h @@ -0,0 +1,34 @@ +/* Plugin support for BFD. + Copyright 1999, 2000, 2001, 2002, 2003, 2005, 2007, 2008 + Free Software Foundation, Inc. + + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#ifndef _PLUGIN_H_ +#define _PLUGIN_H_ + +#include "bfd.h" + +typedef struct plugin_data_struct +{ + int nsyms; + const struct ld_plugin_symbol *syms; +} +plugin_data_struct; + +#endif diff --git a/bfd/targets.c b/bfd/targets.c index 57a400d..6ec6a6c 100644 --- a/bfd/targets.c +++ b/bfd/targets.c @@ -766,6 +766,7 @@ extern const bfd_target pc532netbsd_vec; extern const bfd_target pdp11_aout_vec; extern const bfd_target pef_vec; extern const bfd_target pef_xlib_vec; +extern const bfd_target plugin_vec; extern const bfd_target pmac_xcoff_vec; extern const bfd_target ppcboot_vec; extern const bfd_target riscix_vec; @@ -1144,6 +1145,7 @@ static const bfd_target * const _bfd_target_vector[] = &pdp11_aout_vec, &pef_vec, &pef_xlib_vec, + &plugin_vec, #if 0 /* This has the same magic number as RS/6000. */ &pmac_xcoff_vec, diff --git a/binutils/Makefile.am b/binutils/Makefile.am index 3ef352f..de2bc63 100644 --- a/binutils/Makefile.am +++ b/binutils/Makefile.am @@ -22,6 +22,10 @@ NO_WERROR = @NO_WERROR@ AM_CFLAGS = $(WARN_CFLAGS) LIBICONV = @LIBICONV@ +if PLUGINS +LIBDL = -ldl +endif + # these two are almost the same program AR_PROG=ar RANLIB_PROG=ranlib @@ -235,7 +239,7 @@ addr2line_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) $(BFDLIB) readelf_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) dllwrap_DEPENDENCIES = $(LIBINTL_DEP) $(LIBIBERTY) -LDADD = $(BFDLIB) $(LIBIBERTY) $(LIBINTL) +LDADD = $(BFDLIB) $(LIBIBERTY) $(LIBINTL) $(LIBDL) size_SOURCES = size.c $(BULIBS) @@ -251,7 +255,7 @@ strip_new_SOURCES = objcopy.c is-strip.c rename.c $(WRITE_DEBUG_SRCS) $(BULIBS) nm_new_SOURCES = nm.c $(BULIBS) objdump_SOURCES = objdump.c dwarf.c prdbg.c $(DEBUG_SRCS) $(BULIBS) -objdump_LDADD = $(OPCODES) $(BFDLIB) $(LIBIBERTY) $(LIBINTL) +objdump_LDADD = $(OPCODES) $(BFDLIB) $(LIBIBERTY) $(LIBINTL) $(LIBDL) objdump.o:objdump.c $(COMPILE) -c $(OBJDUMP_DEFS) $(srcdir)/objdump.c @@ -260,11 +264,11 @@ cxxfilt_SOURCES = cxxfilt.c $(BULIBS) ar_SOURCES = arparse.y arlex.l ar.c not-ranlib.c arsup.c rename.c binemul.c \ emul_$(EMULATION).c $(BULIBS) -ar_LDADD = $(BFDLIB) $(LIBIBERTY) @LEXLIB@ $(LIBINTL) +ar_LDADD = $(BFDLIB) $(LIBIBERTY) @LEXLIB@ $(LIBINTL) $(LIBDL) ranlib_SOURCES = ar.c is-ranlib.c arparse.y arlex.l arsup.c rename.c \ binemul.c emul_$(EMULATION).c $(BULIBS) -ranlib_LDADD = $(BFDLIB) $(LIBIBERTY) @LEXLIB@ $(LIBINTL) +ranlib_LDADD = $(BFDLIB) $(LIBIBERTY) @LEXLIB@ $(LIBINTL) $(LIBDL) addr2line_SOURCES = addr2line.c $(BULIBS) diff --git a/binutils/ar.c b/binutils/ar.c index 73ab1d4..c31864e 100644 --- a/binutils/ar.c +++ b/binutils/ar.c @@ -480,6 +480,17 @@ main (int argc, char **argv) arg_index = 1; arg_ptr = argv[arg_index]; + if (strcmp (arg_ptr, "--plugin") == 0) + { + if (argc < 4) + usage(1); + + bfd_plugin_set_plugin(argv[2]); + + arg_index += 2; + arg_ptr = argv[arg_index]; + } + if (*arg_ptr == '-') { /* When the first option starts with '-' we support POSIX-compatible diff --git a/binutils/configure.in b/binutils/configure.in index e35b169..b0d0fa8 100644 --- a/binutils/configure.in +++ b/binutils/configure.in @@ -62,6 +62,17 @@ AM_PO_SUBDIRS AM_MAINTAINER_MODE AM_CONDITIONAL(GENINSRC_NEVER, false) +AC_ARG_ENABLE([plugins], +[ --enable-plugins linker plugins], +[case "${enableval}" in + yes | "") plugins=yes ;; + no) plugins=no ;; + *) plugins=yes ;; + esac], +[plugins=no]) + +AM_CONDITIONAL(PLUGINS, test "$plugins" = "yes") + AC_EXEEXT if test -n "$EXEEXT"; then AC_DEFINE(HAVE_EXECUTABLE_SUFFIX, 1, diff --git a/binutils/nm.c b/binutils/nm.c index e11568a..8789c90 100644 --- a/binutils/nm.c +++ b/binutils/nm.c @@ -178,6 +178,7 @@ static bfd *lineno_cache_bfd; static bfd *lineno_cache_rel_bfd; #define OPTION_TARGET 200 +#define OPTION_PLUGIN 201 static struct option long_options[] = { @@ -192,6 +193,7 @@ static struct option long_options[] = {"no-demangle", no_argument, &do_demangle, 0}, {"no-sort", no_argument, &no_sort, 1}, {"numeric-sort", no_argument, &sort_numerically, 1}, + {"plugin", required_argument, 0, OPTION_PLUGIN}, {"portability", no_argument, 0, 'P'}, {"print-armap", no_argument, &print_armap, 1}, {"print-file-name", no_argument, 0, 'o'}, @@ -1608,6 +1610,10 @@ main (int argc, char **argv) target = optarg; break; + case OPTION_PLUGIN: /* --plugin */ + bfd_plugin_set_plugin (optarg); + break; + case 0: /* A long option that just sets a flag. */ break; diff --git a/gas/Makefile.am b/gas/Makefile.am index 40c52be..5d0e42f 100644 --- a/gas/Makefile.am +++ b/gas/Makefile.am @@ -499,6 +499,10 @@ BASEDIR = $(srcdir)/.. BFDDIR = $(BASEDIR)/bfd INCDIR = $(BASEDIR)/include +if PLUGINS +LIBDL = -ldl +endif + # This is the variable actually used when we compile. # Specify the directories to be searched for header files. # Both . and srcdir are used, in that order, @@ -530,7 +534,7 @@ STAGESTUFF = *.o $(noinst_PROGRAMS) as_new_SOURCES = $(GAS_CFILES) as_new_LDADD = $(TARG_CPU_O) $(OBJ_FORMAT_O) $(ATOF_TARG_O) \ - $(extra_objects) $(GASLIBS) $(LIBINTL) $(LIBM) + $(extra_objects) $(GASLIBS) $(LIBINTL) $(LIBM) $(LIBDL) as_new_DEPENDENCIES = $(TARG_CPU_O) $(OBJ_FORMAT_O) $(ATOF_TARG_O) \ $(extra_objects) $(GASLIBS) $(LIBINTL_DEP) diff --git a/gas/configure.in b/gas/configure.in index 011e886..961ea79 100644 --- a/gas/configure.in +++ b/gas/configure.in @@ -604,6 +604,16 @@ AM_PO_SUBDIRS AM_MAINTAINER_MODE AM_CONDITIONAL(GENINSRC_NEVER, false) +AC_ARG_ENABLE([plugins], +[ --enable-plugins linker plugins], +[case "${enableval}" in + yes | "") plugins=yes ;; + no) plugins=no ;; + *) plugins=yes ;; + esac], +[plugins=no]) + +AM_CONDITIONAL(PLUGINS, test "$plugins" = "yes") AC_EXEEXT AC_CHECK_HEADERS(string.h stdlib.h memory.h strings.h unistd.h stdarg.h varargs.h errno.h sys/types.h limits.h) diff --git a/gprof/Makefile.am b/gprof/Makefile.am index 1d3d3ca..3151f9b 100644 --- a/gprof/Makefile.am +++ b/gprof/Makefile.am @@ -15,6 +15,10 @@ WARN_CFLAGS = @WARN_CFLAGS@ NO_WERROR = @NO_WERROR@ AM_CFLAGS = $(WARN_CFLAGS) +if PLUGINS +LIBDL = -ldl +endif + MKDEP = gcc -MM INCLUDES = -DDEBUG -I../bfd -I$(srcdir)/../include \ @@ -30,7 +34,7 @@ sources = basic_blocks.c call_graph.c cg_arcs.c cg_dfn.c \ i386.c alpha.c vax.c tahoe.c sparc.c mips.c gprof_SOURCES = $(sources) flat_bl.c bsd_callg_bl.c fsf_callg_bl.c gprof_DEPENDENCIES = ../bfd/libbfd.la ../libiberty/libiberty.a $(LIBINTL_DEP) -gprof_LDADD = ../bfd/libbfd.la ../libiberty/libiberty.a $(LIBINTL) +gprof_LDADD = ../bfd/libbfd.la ../libiberty/libiberty.a $(LIBINTL) $(LIBDL) noinst_HEADERS = \ basic_blocks.h call_graph.h cg_arcs.h cg_dfn.h cg_print.h \ diff --git a/gprof/configure.in b/gprof/configure.in index 1ee8064..c1dec91 100644 --- a/gprof/configure.in +++ b/gprof/configure.in @@ -33,6 +33,16 @@ AM_PO_SUBDIRS AM_MAINTAINER_MODE AM_CONDITIONAL(GENINSRC_NEVER, false) +AC_ARG_ENABLE([plugins], +[ --enable-plugins linker plugins], +[case "${enableval}" in + yes | "") plugins=yes ;; + no) plugins=no ;; + *) plugins=yes ;; + esac], +[plugins=no]) + +AM_CONDITIONAL(PLUGINS, test "$plugins" = "yes") AC_EXEEXT AC_CHECK_HEADERS(sys/gmon_out.h) diff --git a/ld/Makefile.am b/ld/Makefile.am index 6a4139a..c59ea54 100644 --- a/ld/Makefile.am +++ b/ld/Makefile.am @@ -108,6 +108,10 @@ INCLUDES = -I. -I$(srcdir) -I../bfd -I$(BFDDIR) -I$(INCDIR) \ BFDLIB = ../bfd/libbfd.la LIBIBERTY = ../libiberty/libiberty.a +if PLUGINS +LIBDL = -ldl +endif + ALL_EMULATIONS = \ eaixppc.o \ eaixrs6.o \ @@ -1748,7 +1752,7 @@ EXTRA_ld_new_SOURCES = deffilep.y ld_new_SOURCES = ldgram.y ldlex.l lexsup.c ldlang.c mri.c ldctor.c ldmain.c \ ldwrite.c ldexp.c ldemul.c ldver.c ldmisc.c ldfile.c ldcref.c ld_new_DEPENDENCIES = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) $(BFDLIB) $(LIBIBERTY) $(LIBINTL_DEP) -ld_new_LDADD = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) $(BFDLIB) $(LIBIBERTY) $(LIBINTL) +ld_new_LDADD = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) $(BFDLIB) $(LIBIBERTY) $(LIBINTL) $(LIBDL) # The generated emulation files mostly have the same dependencies. $(EMULATION_OFILES): ../bfd/bfd.h sysdep.h config.h $(INCDIR)/bfdlink.h \ diff --git a/ld/configure.in b/ld/configure.in index eddfeb1..7e4fed7 100644 --- a/ld/configure.in +++ b/ld/configure.in @@ -127,6 +127,17 @@ AM_MAINTAINER_MODE AM_CONDITIONAL(GENINSRC_NEVER, false) ACX_PROG_CMP_IGNORE_INITIAL +AC_ARG_ENABLE([plugins], +[ --enable-plugins linker plugins], +[case "${enableval}" in + yes | "") plugins=yes ;; + no) plugins=no ;; + *) plugins=yes ;; + esac], +[plugins=no]) + +AM_CONDITIONAL(PLUGINS, test "$plugins" = "yes") + . ${srcdir}/configure.host AC_SUBST(HDEFINES)