#define bfd_plugin_bfd_lookup_section_flags bfd_generic_lookup_section_flags
#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_group_name bfd_generic_group_name
#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
}
}
- plugin_list_iter = (struct plugin_list_entry *) xmalloc (sizeof *plugin_list_iter);
+ plugin_list_iter = bfd_malloc (sizeof *plugin_list_iter);
+ if (plugin_list_iter == NULL)
+ return 0;
plugin_list_iter->handle = plugin_handle;
plugin_list_iter->claim_file = NULL;
plugin_list_iter->next = plugin_list;
static int
load_plugin (bfd *abfd)
{
- char *plugin_dir;
- char *p;
- DIR *d;
- struct dirent *ent;
+ /* The intent was to search ${libdir}/bfd-plugins for plugins, but
+ unfortunately the original implementation wasn't precisely that
+ when configuring binutils using --libdir. Search in the proper
+ path first, then the old one for backwards compatibility. */
+ static const char *path[]
+ = { LIBDIR "/bfd-plugins", BINDIR "/../lib/bfd-plugins" };
+ struct stat last_st;
int found = 0;
+ unsigned int i;
if (!has_plugin)
return found;
if (plugin_program_name == NULL)
return found;
- plugin_dir = concat (BINDIR, "/../lib/bfd-plugins", NULL);
- p = make_relative_prefix (plugin_program_name,
- BINDIR,
- plugin_dir);
- free (plugin_dir);
- plugin_dir = NULL;
-
- d = opendir (p);
- if (!d)
- goto out;
-
- while ((ent = readdir (d)))
+ /* Try not to search the same dir twice, by looking at st_dev and
+ st_ino for the dir. If we are on a file system that always sets
+ st_ino to zero or the actual st_ino is zero we might waste some
+ time, but that doesn't matter too much. */
+ last_st.st_dev = 0;
+ last_st.st_ino = 0;
+ for (i = 0; i < sizeof (path) / sizeof (path[0]); i++)
{
- char *full_name;
- struct stat s;
- int valid_plugin;
-
- full_name = concat (p, "/", ent->d_name, NULL);
- if (stat (full_name, &s) == 0 && S_ISREG (s.st_mode))
- found = try_load_plugin (full_name, abfd, &valid_plugin);
- if (has_plugin <= 0)
- has_plugin = valid_plugin;
- free (full_name);
+ char *plugin_dir = make_relative_prefix (plugin_program_name,
+ BINDIR,
+ path[i]);
+ if (plugin_dir)
+ {
+ struct stat st;
+ DIR *d;
+
+ if (stat (plugin_dir, &st) == 0
+ && S_ISDIR (st.st_mode)
+ && !(last_st.st_dev == st.st_dev
+ && last_st.st_ino == st.st_ino
+ && st.st_ino != 0)
+ && (d = opendir (plugin_dir)) != NULL)
+ {
+ struct dirent *ent;
+
+ last_st.st_dev = st.st_dev;
+ last_st.st_ino = st.st_ino;
+ while ((ent = readdir (d)) != NULL)
+ {
+ char *full_name;
+
+ full_name = concat (plugin_dir, "/", ent->d_name, NULL);
+ if (stat (full_name, &st) == 0 && S_ISREG (st.st_mode))
+ {
+ int valid_plugin;
+
+ found = try_load_plugin (full_name, abfd, &valid_plugin);
+ if (has_plugin <= 0)
+ has_plugin = valid_plugin;
+ }
+ free (full_name);
+ if (found)
+ break;
+ }
+ closedir (d);
+ }
+ free (plugin_dir);
+ }
if (found)
break;
}
- out:
- free (p);
- if (d)
- closedir (d);
-
return found;
}
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;
+ static asection fake_section
+ = BFD_FAKE_SECTION (fake_section, NULL, "plug", 0,
+ SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS);
+ static asection fake_common_section
+ = BFD_FAKE_SECTION (fake_common_section, NULL, "plug", 0, SEC_IS_COMMON);
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));