+2006-09-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (elf_link_hash_entry): Add a dynamic field.
+ (bfd_elf_link_mark_dynamic_symbol): New.
+ (SYMBOLIC_BIND): New.
+
+ * elf32-i386.c (elf_i386_check_relocs): Replace info->symbolic
+ with SYMBOLIC_BIND (info, h).
+ (elf_i386_relocate_section): Likewise.
+ * elf64-x86-64.c (elf64_x86_64_check_relocs): Likewise.
+ (elf64_x86_64_relocate_section): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_check_relocs): Likewise.
+
+ * elflink.c (bfd_elf_link_mark_dynamic_symbol): New.
+ (bfd_elf_record_link_assignment): Call
+ bfd_elf_link_mark_dynamic_symbol on new entry.
+ (_bfd_elf_merge_symbol): Likewise.
+ (_bfd_elf_export_symbol): Return if the symbol isn't exported.
+ (_bfd_elf_fix_symbol_flags): Replace info->symbolic with
+ SYMBOLIC_BIND (info, h).
+ (_bfd_elf_dynamic_symbol_p): Likewise.
+ (_bfd_elf_symbol_refs_local_p): Likewise.
+ (bfd_elf_size_dynamic_sections): Updated.
+
2006-09-05 Bibo Mao <bibo.mao@intel.com>
PR binutils/3171
unsigned int hidden : 1;
/* Symbol was forced to local scope due to a version script file. */
unsigned int forced_local : 1;
+ /* Symbol was forced to be dynamic due to a version script file. */
+ unsigned int dynamic : 1;
/* Symbol was marked during garbage collection. */
unsigned int mark : 1;
/* Symbol is referenced by a non-GOT/non-PLT relocation. This is
extern int bfd_elf_link_record_local_dynamic_symbol
(struct bfd_link_info *, bfd *, long);
+extern void bfd_elf_link_mark_dynamic_symbol
+ (struct bfd_link_info *, struct elf_link_hash_entry *);
+
extern bfd_boolean _bfd_elf_close_and_cleanup
(bfd *);
} \
while (0)
+/* Will a symbol be bound to the the definition within the shared
+ library, if any. */
+#define SYMBOLIC_BIND(INFO, H) \
+ ((INFO)->symbolic || ((INFO)->dynamic && !(H)->dynamic))
+
#endif /* _LIBELF_H_ */
&& (sec->flags & SEC_ALLOC) != 0
&& (r_type != R_386_PC32
|| (h != NULL
- && (! info->symbolic
+ && (! SYMBOLIC_BIND (info, h)
|| h->root.type == bfd_link_hash_defweak
|| !h->def_regular))))
|| (ELIMINATE_COPY_RELOCS
&& h->dynindx != -1
&& (r_type == R_386_PC32
|| !info->shared
- || !info->symbolic
+ || !SYMBOLIC_BIND (info, h)
|| !h->def_regular))
outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
else
&& (r_type != R_X86_64_PC32)
&& (r_type != R_X86_64_PC64))
|| (h != NULL
- && (! info->symbolic
+ && (! SYMBOLIC_BIND (info, h)
|| h->root.type == bfd_link_hash_defweak
|| !h->def_regular))))
|| (ELIMINATE_COPY_RELOCS
|| r_type == R_X86_64_PC32
|| r_type == R_X86_64_PC64
|| !info->shared
- || !info->symbolic
+ || !SYMBOLIC_BIND (info, h)
|| !h->def_regular))
{
outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
return TRUE;
}
\f
+/* Mark a symbol dynamic. */
+
+void
+bfd_elf_link_mark_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
+{
+ struct bfd_elf_dynamic_list *d = info->dynamic;
+
+ if (d == NULL || info->relocatable)
+ return;
+
+ if ((*d->match) (&d->head, NULL, h->root.root.string))
+ h->dynamic = 1;
+}
+
/* Record an assignment to a symbol made by a linker script. We need
this in case some dynamic object refers to this symbol. */
}
if (h->root.type == bfd_link_hash_new)
- h->non_elf = 0;
+ {
+ bfd_elf_link_mark_dynamic_symbol (info, h);
+ h->non_elf = 0;
+ }
/* If this symbol is being provided by the linker script, and it is
currently defined by a dynamic object, but not by a regular
if (h->root.type == bfd_link_hash_new)
{
+ bfd_elf_link_mark_dynamic_symbol (info, h);
h->non_elf = 0;
return TRUE;
}
{
struct elf_info_failed *eif = data;
+ /* Ignore this if we won't export it. */
+ if (!eif->info->export_dynamic && !h->dynamic)
+ return TRUE;
+
/* Ignore indirect symbols. These are added by the versioning code. */
if (h->root.type == bfd_link_hash_indirect)
return TRUE;
if (h->needs_plt
&& eif->info->shared
&& is_elf_hash_table (eif->info->hash)
- && (eif->info->symbolic
+ && (SYMBOLIC_BIND (eif->info, h)
|| ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
&& h->def_regular)
{
/* Identify the cases where name binding rules say that a
visible symbol resolves locally. */
- binding_stays_local_p = info->executable || info->symbolic;
+ binding_stays_local_p = info->executable || SYMBOLIC_BIND (info, h);
switch (ELF_ST_VISIBILITY (h->other))
{
/* At this point, we know the symbol is defined and dynamic. In an
executable it must resolve locally, likewise when building symbolic
shared libraries. */
- if (info->executable || info->symbolic)
+ if (info->executable || SYMBOLIC_BIND (info, h))
return TRUE;
/* Now deal with defined dynamic symbols in shared libraries. Ones
/* If we are supposed to export all symbols into the dynamic symbol
table (this is not the normal case), then do so. */
- if (info->export_dynamic)
+ if (info->export_dynamic
+ || (info->executable && info->dynamic))
{
elf_link_hash_traverse (elf_hash_table (info),
_bfd_elf_export_symbol,
have yet been processed. Do something with what we know, as
this may help reduce memory usage and processing time later. */
maybe_dynamic = (h && ((!info->executable
- && (!info->symbolic
+ && (!SYMBOLIC_BIND (info, h)
|| info->unresolved_syms_in_shared_libs == RM_IGNORE))
|| !h->def_regular
|| h->root.type == bfd_link_hash_defweak));
have yet been processed. Do something with what we know, as
this may help reduce memory usage and processing time later. */
maybe_dynamic = (h && ((!info->executable
- && (!info->symbolic
+ && (!SYMBOLIC_BIND (info, h)
|| info->unresolved_syms_in_shared_libs == RM_IGNORE))
|| !h->def_regular
|| h->root.type == bfd_link_hash_defweak));
+2006-09-07 H.J. Lu <hongjiu.lu@intel.com>
+
+ * bfdlink.h (bfd_elf_dynamic_list): New.
+ (bfd_link_info): Add a dynamic field.
+
2006-08-04 Marcelo Tosatti <marcelo@kvack.org>
* bfdlink.h (struct bfd_link_info): New field: print_gc_sections.
RM_GENERATE_ERROR
};
+struct bfd_elf_dynamic_list;
+
/* This structure holds all the information needed to communicate
between BFD and the linker when doing a link. */
/* Start and end of RELRO region. */
bfd_vma relro_start, relro_end;
+
+ /* List of symbols should be dynamic. */
+ struct bfd_elf_dynamic_list *dynamic;
};
/* This structures holds a set of callback functions. These are
struct bfd_elf_version_expr *prev, const char *sym);
};
+struct bfd_elf_dynamic_list
+{
+ struct bfd_elf_version_expr_head head;
+ struct bfd_elf_version_expr *(*match)
+ (struct bfd_elf_version_expr_head *head,
+ struct bfd_elf_version_expr *prev, const char *sym);
+};
+
#endif