this in case some dynamic object refers to this symbol. */
bfd_boolean
-bfd_elf_record_link_assignment (bfd *output_bfd ATTRIBUTE_UNUSED,
- struct bfd_link_info *info,
+bfd_elf_record_link_assignment (struct bfd_link_info *info,
const char *name,
bfd_boolean provide)
{
/* If this is a hidden symbol, or if it is not version
1, we append the version name to the symbol name.
- However, we do not modify a non-hidden absolute
- symbol, because it might be the version symbol
- itself. FIXME: What if it isn't? */
+ However, we do not modify a non-hidden absolute symbol
+ if it is not a function, because it might be the version
+ symbol itself. FIXME: What if it isn't? */
if ((iver.vs_vers & VERSYM_HIDDEN) != 0
- || (vernum > 1 && ! bfd_is_abs_section (sec)))
+ || (vernum > 1 && (! bfd_is_abs_section (sec)
+ || ELF_ST_TYPE (isym->st_info) == STT_FUNC)))
{
const char *verstr;
size_t namelen, verlen, newlen;
(asection *, struct bfd_link_info *, Elf_Internal_Rela *,
struct elf_link_hash_entry *h, Elf_Internal_Sym *);
- if (!info->gc_sections)
- return bfd_generic_gc_sections (abfd, info);
-
if (!get_elf_backend_data (abfd)->can_gc_sections
|| info->relocatable
|| info->emitrelocations
h->forced_local = 1;
}
-/* Set NAME to VAL if the symbol exists and is undefined. If val is NULL
- it is an absolute symbol, otherwise it is relative to that section. */
+/* Set NAME to VAL if the symbol exists and is not defined in a regular
+ object file. If S is NULL it is an absolute symbol, otherwise it is
+ relative to that section. */
void
_bfd_elf_provide_symbol (struct bfd_link_info *info, const char *name,
{
struct elf_link_hash_entry *h;
- h = elf_link_hash_lookup (elf_hash_table (info), name, FALSE, FALSE,
- FALSE);
- if (h != NULL && (h->root.type == bfd_link_hash_undefined
- || h->root.type == bfd_link_hash_undefweak))
+ bfd_elf_record_link_assignment (info, name, TRUE);
+
+ h = elf_link_hash_lookup (elf_hash_table (info), name, FALSE, FALSE, FALSE);
+ if (h != NULL
+ && !(h->root.type == bfd_link_hash_defined
+ && h->root.u.def.section != NULL
+ && h->root.u.def.section != h->root.u.def.section->output_section))
bfd_elf_set_symbol (h, val, s);
}
-/* Set START and END to boundaries of SEC if they exist and are
- undefined. */
+/* Set START and END to boundaries of SEC if they exist and are not
+ defined in regular object files. */
void
_bfd_elf_provide_section_bound_symbols (struct bfd_link_info *info,
const char *start,
const char *end)
{
- struct elf_link_hash_entry *hs, *he;
- bfd_vma start_val, end_val;
- bfd_boolean do_start, do_end;
-
- /* Check if we need them or not first. */
- hs = elf_link_hash_lookup (elf_hash_table (info), start, FALSE,
- FALSE, FALSE);
- do_start = (hs != NULL
- && (hs->root.type == bfd_link_hash_undefined
- || hs->root.type == bfd_link_hash_undefweak));
-
- he = elf_link_hash_lookup (elf_hash_table (info), end, FALSE,
- FALSE, FALSE);
- do_end = (he != NULL
- && (he->root.type == bfd_link_hash_undefined
- || he->root.type == bfd_link_hash_undefweak));
-
- if (!do_start && !do_end)
- return;
-
+ bfd_vma val = 0;
+ _bfd_elf_provide_symbol (info, start, val, sec);
if (sec != NULL)
+ val = sec->size;
+ _bfd_elf_provide_symbol (info, end, val, sec);
+}
+
+/* Convert symbols in excluded output sections to absolute. */
+
+static bfd_boolean
+fix_syms (struct bfd_link_hash_entry *h, void *data)
+{
+ bfd *obfd = (bfd *) data;
+
+ if (h->type == bfd_link_hash_warning)
+ h = h->u.i.link;
+
+ if (h->type == bfd_link_hash_defined
+ || h->type == bfd_link_hash_defweak)
{
- start_val = sec->vma;
- end_val = start_val + sec->size;
- }
- else
- {
- /* We have to choose those values very carefully. Some targets,
- like alpha, may have relocation overflow with 0. "__bss_start"
- should be defined in all cases. */
- struct elf_link_hash_entry *h
- = elf_link_hash_lookup (elf_hash_table (info), "__bss_start",
- FALSE, FALSE, FALSE);
- if (h != NULL && h->root.type == bfd_link_hash_defined)
- start_val = h->root.u.def.value;
- else
- start_val = 0;
- end_val = start_val;
+ asection *s = h->u.def.section;
+ if (s != NULL
+ && s == s->output_section
+ && bfd_section_removed_from_list (obfd, s))
+ {
+ h->u.def.value += s->vma;
+ h->u.def.section = bfd_abs_section_ptr;
+ }
}
- if (do_start)
- bfd_elf_set_symbol (hs, start_val, NULL);
+ return TRUE;
+}
- if (do_end)
- bfd_elf_set_symbol (he, end_val, NULL);
+void
+_bfd_elf_fix_excluded_sec_syms (bfd *obfd, struct bfd_link_info *info)
+{
+ bfd_link_hash_traverse (info->hash, fix_syms, obfd);
}