}
bh = &h->root;
+ bed = get_elf_backend_data (abfd);
if (!_bfd_generic_link_add_one_symbol (info, abfd, name, BSF_GLOBAL,
- sec, 0, NULL, FALSE,
- get_elf_backend_data (abfd)->collect,
+ sec, 0, NULL, FALSE, bed->collect,
&bh))
return NULL;
h = (struct elf_link_hash_entry *) bh;
if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL)
h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
- bed = get_elf_backend_data (abfd);
(*bed->elf_backend_hide_symbol) (info, h, TRUE);
return h;
}
{
struct elf_link_hash_entry **p;
- p = (struct elf_link_hash_entry **)
- bfd_zmalloc (reldata->count * sizeof (struct elf_link_hash_entry *));
+ p = ((struct elf_link_hash_entry **)
+ bfd_zmalloc (reldata->count * sizeof (*p)));
if (p == NULL)
return FALSE;
requested we not re-export it, then mark it as hidden. */
if (definition
&& !dynamic
- && (abfd->no_export
- || (abfd->my_archive && abfd->my_archive->no_export))
+ && abfd->no_export
&& ELF_ST_VISIBILITY (isym->st_other) != STV_INTERNAL)
isym->st_other = (STV_HIDDEN
| (isym->st_other & ~ELF_ST_VISIBILITY (-1)));
{
amt = ((isymend - isym + 1)
* sizeof (struct elf_link_hash_entry *));
- nondeflt_vers =
- (struct elf_link_hash_entry **) bfd_malloc (amt);
+ nondeflt_vers
+ = (struct elf_link_hash_entry **) bfd_malloc (amt);
if (!nondeflt_vers)
goto error_free_vers;
}
}
elf_dyn_lib_class (abfd) = (enum dynamic_lib_link_class)
- (elf_dyn_lib_class (abfd) & ~DYN_AS_NEEDED);
+ (elf_dyn_lib_class (abfd) & ~DYN_AS_NEEDED);
add_needed = TRUE;
ret = elf_add_dt_needed_tag (abfd, info, soname, add_needed);
/* Add this bfd to the loaded list. */
struct elf_link_loaded_list *n;
- n = (struct elf_link_loaded_list *)
- bfd_alloc (abfd, sizeof (struct elf_link_loaded_list));
+ n = (struct elf_link_loaded_list *) bfd_alloc (abfd, sizeof (*n));
if (n == NULL)
goto error_return;
n->abfd = abfd;
{
best_chlen = max;
best_size = i;
- no_improvement_count = 0;
+ no_improvement_count = 0;
}
/* PR 11843: Avoid futile long searches for the best bucket size
when there are a large number of symbols. */
if (entry == NULL)
{
entry = (struct bfd_hash_entry *)
- bfd_hash_allocate (table, sizeof (struct elf_link_hash_entry));
+ bfd_hash_allocate (table, sizeof (struct elf_link_hash_entry));
if (entry == NULL)
return entry;
}
if (count1 == 0 || count2 == 0 || count1 != count2)
goto done;
- symtable1 = (struct elf_symbol *)
- bfd_malloc (count1 * sizeof (struct elf_symbol));
- symtable2 = (struct elf_symbol *)
- bfd_malloc (count2 * sizeof (struct elf_symbol));
+ symtable1
+ = (struct elf_symbol *) bfd_malloc (count1 * sizeof (*symtable1));
+ symtable2
+ = (struct elf_symbol *) bfd_malloc (count2 * sizeof (*symtable2));
if (symtable1 == NULL || symtable2 == NULL)
goto done;
{
bfd_boolean failed;
bfd_boolean localsyms;
- bfd_boolean need_second_pass;
- bfd_boolean second_pass;
bfd_boolean file_sym_done;
struct elf_final_link_info *flinfo;
};
amt = flinfo->shndxbuf_size * sizeof (Elf_External_Sym_Shndx);
destshndx = (Elf_External_Sym_Shndx *) bfd_realloc (destshndx,
- amt * 2);
+ amt * 2);
if (destshndx == NULL)
return 0;
flinfo->symshndxbuf = destshndx;
{
if (!h->forced_local)
return TRUE;
- if (eoinfo->second_pass
- && !((h->root.type == bfd_link_hash_defined
- || h->root.type == bfd_link_hash_defweak)
- && h->root.u.def.section->output_section != NULL))
- return TRUE;
-
- if (!eoinfo->file_sym_done
- && (eoinfo->second_pass ? eoinfo->flinfo->filesym_count == 1
- : eoinfo->flinfo->filesym_count > 1))
- {
- /* Output a FILE symbol so that following locals are not associated
- with the wrong input file. */
- memset (&sym, 0, sizeof (sym));
- sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE);
- sym.st_shndx = SHN_ABS;
- if (!elf_link_output_sym (eoinfo->flinfo, NULL, &sym,
- bfd_und_section_ptr, NULL))
- return FALSE;
-
- eoinfo->file_sym_done = TRUE;
- }
}
else
{
a regular file, or that we have been told to strip. However, if
h->indx is set to -2, the symbol is used by a reloc and we must
output it. */
+ strip = FALSE;
if (h->indx == -2)
- strip = FALSE;
+ ;
else if ((h->def_dynamic
|| h->ref_dynamic
|| h->root.type == bfd_link_hash_new)
|| h->root.type == bfd_link_hash_defweak)
&& ((flinfo->info->strip_discarded
&& discarded_section (h->root.u.def.section))
- || (h->root.u.def.section->owner != NULL
+ || ((h->root.u.def.section->flags & SEC_LINKER_CREATED) == 0
+ && h->root.u.def.section->owner != NULL
&& (h->root.u.def.section->owner->flags & BFD_PLUGIN) != 0)))
strip = TRUE;
else if ((h->root.type == bfd_link_hash_undefined
&& h->root.u.undef.abfd != NULL
&& (h->root.u.undef.abfd->flags & BFD_PLUGIN) != 0)
strip = TRUE;
- else
- strip = FALSE;
/* If we're stripping it, and it's not a dynamic symbol, there's
- nothing else to do unless it is a forced local symbol or a
- STT_GNU_IFUNC symbol. */
+ nothing else to do. However, if it is a forced local symbol or
+ an ifunc symbol we need to give the backend finish_dynamic_symbol
+ function a chance to make it dynamic. */
if (strip
&& h->dynindx == -1
&& h->type != STT_GNU_IFUNC
input_sec = h->root.u.def.section;
if (input_sec->output_section != NULL)
{
- if (eoinfo->localsyms && flinfo->filesym_count == 1)
- {
- bfd_boolean second_pass_sym
- = (input_sec->owner == flinfo->output_bfd
- || input_sec->owner == NULL
- || (input_sec->flags & SEC_LINKER_CREATED) != 0
- || (input_sec->owner->flags & BFD_LINKER_CREATED) != 0);
-
- eoinfo->need_second_pass |= second_pass_sym;
- if (eoinfo->second_pass != second_pass_sym)
- return TRUE;
- }
-
sym.st_shndx =
_bfd_elf_section_from_bfd_section (flinfo->output_bfd,
input_sec->output_section);
asection *tls_sec = elf_hash_table (flinfo->info)->tls_sec;
if (tls_sec != NULL)
sym.st_value -= tls_sec->vma;
- else
- {
- /* The TLS section may have been garbage collected. */
- BFD_ASSERT (flinfo->info->gc_sections
- && !input_sec->gc_mark);
- }
}
}
}
}
}
- /* If we're stripping it, then it was just a dynamic symbol, and
- there's nothing else to do. */
- if (strip || (input_sec->flags & SEC_EXCLUDE) != 0)
+ /* If the symbol is undefined, and we didn't output it to .dynsym,
+ strip it from .symtab too. Obviously we can't do this for
+ relocatable output or when needed for --emit-relocs. */
+ else if (input_sec == bfd_und_section_ptr
+ && h->indx != -2
+ && !flinfo->info->relocatable)
return TRUE;
+ /* Also strip others that we couldn't earlier due to dynamic symbol
+ processing. */
+ if (strip)
+ return TRUE;
+ if ((input_sec->flags & SEC_EXCLUDE) != 0)
+ return TRUE;
+
+ /* Output a FILE symbol so that following locals are not associated
+ with the wrong input file. We need one for forced local symbols
+ if we've seen more than one FILE symbol or when we have exactly
+ one FILE symbol but global symbols are present in a file other
+ than the one with the FILE symbol. We also need one if linker
+ defined symbols are present. In practice these conditions are
+ always met, so just emit the FILE symbol unconditionally. */
+ if (eoinfo->localsyms
+ && !eoinfo->file_sym_done
+ && eoinfo->flinfo->filesym_count != 0)
+ {
+ Elf_Internal_Sym fsym;
+
+ memset (&fsym, 0, sizeof (fsym));
+ fsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE);
+ fsym.st_shndx = SHN_ABS;
+ if (!elf_link_output_sym (eoinfo->flinfo, NULL, &fsym,
+ bfd_und_section_ptr, NULL))
+ return FALSE;
+
+ eoinfo->file_sym_done = TRUE;
+ }
indx = bfd_get_symcount (flinfo->output_bfd);
ret = elf_link_output_sym (flinfo, h->root.root.string, &sym, input_sec, h);
*ppsection = isec;
- /* Don't output the first, undefined, symbol. */
- if (ppsection == flinfo->sections)
+ /* Don't output the first, undefined, symbol. In fact, don't
+ output any undefined local symbol. */
+ if (isec == bfd_und_section_ptr)
continue;
if (ELF_ST_TYPE (isym->st_info) == STT_SECTION)
if (ELF_ST_TYPE (isym->st_info) == STT_FILE)
{
+ if (input_bfd->lto_output)
+ /* -flto puts a temp file name here. This means builds
+ are not reproducible. Discard the symbol. */
+ continue;
have_file_sym = TRUE;
flinfo->filesym_count += 1;
}
memset (&osym, 0, sizeof (osym));
osym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE);
osym.st_shndx = SHN_ABS;
- if (!elf_link_output_sym (flinfo, input_bfd->filename, &osym,
- bfd_abs_section_ptr, NULL))
+ if (!elf_link_output_sym (flinfo,
+ (input_bfd->lto_output ? NULL
+ : input_bfd->filename),
+ &osym, bfd_abs_section_ptr, NULL))
return FALSE;
}
s_type = h->type;
+ /* If a plugin symbol is referenced from a non-IR file,
+ mark the symbol as undefined. Note that the
+ linker may attach linker created dynamic sections
+ to the plugin bfd. Symbols defined in linker
+ created sections are not plugin symbols. */
+ if (h->root.non_ir_ref
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && (h->root.u.def.section->flags
+ & SEC_LINKER_CREATED) == 0
+ && h->root.u.def.section->owner != NULL
+ && (h->root.u.def.section->owner->flags
+ & BFD_PLUGIN) != 0)
+ {
+ h->root.type = bfd_link_hash_undefined;
+ h->root.u.undef.abfd = h->root.u.def.section->owner;
+ }
+
ps = NULL;
if (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
eoinfo.failed = FALSE;
eoinfo.flinfo = &flinfo;
eoinfo.localsyms = TRUE;
- eoinfo.need_second_pass = FALSE;
- eoinfo.second_pass = FALSE;
eoinfo.file_sym_done = FALSE;
bfd_hash_traverse (&info->hash->table, elf_link_output_extsym, &eoinfo);
if (eoinfo.failed)
return FALSE;
- if (eoinfo.need_second_pass)
- {
- eoinfo.second_pass = TRUE;
- bfd_hash_traverse (&info->hash->table, elf_link_output_extsym, &eoinfo);
- if (eoinfo.failed)
- return FALSE;
- }
-
/* If backend needs to output some local symbols not present in the hash
table, do it now. */
if (bed->elf_backend_output_arch_local_syms
if (!h->mark
&& (((h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
- && !(h->def_regular
+ && !((h->def_regular || ELF_COMMON_DEF_P (h))
&& h->root.u.def.section->gc_mark))
|| h->root.type == bfd_link_hash_undefined
|| h->root.type == bfd_link_hash_undefweak))
if ((h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
&& (h->ref_dynamic
- || (h->def_regular
+ || ((h->def_regular || ELF_COMMON_DEF_P (h))
&& ELF_ST_VISIBILITY (h->other) != STV_INTERNAL
&& ELF_ST_VISIBILITY (h->other) != STV_HIDDEN
&& (!info->executable
win:
if (!child->vtable)
{
- child->vtable = (struct elf_link_virtual_table_entry *)
- bfd_zalloc (abfd, sizeof (*child->vtable));
+ child->vtable = ((struct elf_link_virtual_table_entry *)
+ bfd_zalloc (abfd, sizeof (*child->vtable)));
if (!child->vtable)
return FALSE;
}
if (!h->vtable)
{
- h->vtable = (struct elf_link_virtual_table_entry *)
- bfd_zalloc (abfd, sizeof (*h->vtable));
+ h->vtable = ((struct elf_link_virtual_table_entry *)
+ bfd_zalloc (abfd, sizeof (*h->vtable)));
if (!h->vtable)
return FALSE;
}
string table associated with ABFD. */
asection *
-_bfd_elf_make_dynamic_reloc_section (asection * sec,
- bfd * dynobj,
- unsigned int alignment,
- bfd * abfd,
- bfd_boolean is_rela)
+_bfd_elf_make_dynamic_reloc_section (asection *sec,
+ bfd *dynobj,
+ unsigned int alignment,
+ bfd *abfd,
+ bfd_boolean is_rela)
{
asection * reloc_sec = elf_section_data (sec)->sreloc;