/* ELF linking support for BFD.
- Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
return TRUE;
}
\f
+/* Create a strtab to hold the dynamic symbol names. */
+static bfd_boolean
+_bfd_elf_link_create_dynstrtab (bfd *abfd, struct bfd_link_info *info)
+{
+ struct elf_link_hash_table *hash_table;
+
+ hash_table = elf_hash_table (info);
+ if (hash_table->dynobj == NULL)
+ hash_table->dynobj = abfd;
+
+ if (hash_table->dynstr == NULL)
+ {
+ hash_table->dynstr = _bfd_elf_strtab_init ();
+ if (hash_table->dynstr == NULL)
+ return FALSE;
+ }
+ return TRUE;
+}
+
/* Create some sections which will be filled in with dynamic linking
information. ABFD is an input file which requires dynamic sections
to be created. The dynamic sections take up virtual memory space
if (elf_hash_table (info)->dynamic_sections_created)
return TRUE;
- /* Make sure that all dynamic sections use the same input BFD. */
- if (elf_hash_table (info)->dynobj == NULL)
- elf_hash_table (info)->dynobj = abfd;
- else
- abfd = elf_hash_table (info)->dynobj;
+ if (!_bfd_elf_link_create_dynstrtab (abfd, info))
+ return FALSE;
+ abfd = elf_hash_table (info)->dynobj;
bed = get_elf_backend_data (abfd);
flags = bed->dynamic_sec_flags;
|| ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY))
return FALSE;
- /* Create a strtab to hold the dynamic symbol names. */
- if (elf_hash_table (info)->dynstr == NULL)
- {
- elf_hash_table (info)->dynstr = _bfd_elf_strtab_init ();
- if (elf_hash_table (info)->dynstr == NULL)
- return FALSE;
- }
-
s = bfd_make_section (abfd, ".dynamic");
if (s == NULL
|| ! bfd_set_section_flags (abfd, s, flags)
return FALSE;
/* The special symbol _DYNAMIC is always set to the start of the
- .dynamic section. This call occurs before we have processed the
- symbols for any dynamic object, so we don't have to worry about
- overriding a dynamic definition. We could set _DYNAMIC in a
- linker script, but we only want to define it if we are, in fact,
- creating a .dynamic section. We don't want to define it if there
- is no .dynamic section, since on some ELF platforms the start up
- code examines it to decide how to initialize the process. */
- bh = NULL;
+ .dynamic section. We could set _DYNAMIC in a linker script, but we
+ only want to define it if we are, in fact, creating a .dynamic
+ section. We don't want to define it if there is no .dynamic
+ section, since on some ELF platforms the start up code examines it
+ to decide how to initialize the process. */
+ h = elf_link_hash_lookup (elf_hash_table (info), "_DYNAMIC",
+ FALSE, FALSE, FALSE);
+ if (h != NULL)
+ {
+ /* Zap symbol defined in an as-needed lib that wasn't linked.
+ This is a symptom of a larger problem: Absolute symbols
+ defined in shared libraries can't be overridden, because we
+ lose the link to the bfd which is via the symbol section. */
+ h->root.type = bfd_link_hash_new;
+ }
+ bh = &h->root;
if (! (_bfd_generic_link_add_one_symbol
(info, abfd, "_DYNAMIC", BSF_GLOBAL, s, 0, NULL, FALSE,
get_elf_backend_data (abfd)->collect, &bh)))
return FALSE;
/* The .rel[a].bss section holds copy relocs. This section is not
- normally needed. We need to create it here, though, so that the
- linker will map it to an output section. We can't just create it
- only if we need it, because we will not know whether we need it
- until we have seen all the input files, and the first time the
- main linker code calls BFD after examining all the input files
- (size_dynamic_sections) the input sections have already been
- mapped to the output sections. If the section turns out not to
- be needed, we can discard it later. We will never need this
- section when generating a shared object, since they do not use
- copy relocs. */
+ normally needed. We need to create it here, though, so that the
+ linker will map it to an output section. We can't just create it
+ only if we need it, because we will not know whether we need it
+ until we have seen all the input files, and the first time the
+ main linker code calls BFD after examining all the input files
+ (size_dynamic_sections) the input sections have already been
+ mapped to the output sections. If the section turns out not to
+ be needed, we can discard it later. We will never need this
+ section when generating a shared object, since they do not use
+ copy relocs. */
if (! info->shared)
{
s = bfd_make_section (abfd,
&& h->root.type != bfd_link_hash_undefweak)
{
h->forced_local = 1;
- return TRUE;
+ if (!elf_hash_table (info)->is_relocatable_executable)
+ return TRUE;
}
default:
bfd_boolean provide)
{
struct elf_link_hash_entry *h;
+ struct elf_link_hash_table *htab;
if (!is_elf_hash_table (info->hash))
return TRUE;
- h = elf_link_hash_lookup (elf_hash_table (info), name, TRUE, TRUE, FALSE);
+ htab = elf_hash_table (info);
+ h = elf_link_hash_lookup (htab, name, !provide, TRUE, FALSE);
if (h == NULL)
- return FALSE;
+ return provide;
/* Since we're defining the symbol, don't let it seem to have not
been defined. record_dynamic_symbol and size_dynamic_sections
- may depend on this.
- ??? Changing bfd_link_hash_undefined to bfd_link_hash_new (or
- to bfd_link_hash_undefweak, see linker.c:link_action) runs the risk
- of some later symbol manipulation setting the symbol back to
- bfd_link_hash_undefined, and the linker trying to add the symbol to
- the undefs list twice. */
+ may depend on this. */
if (h->root.type == bfd_link_hash_undefweak
|| h->root.type == bfd_link_hash_undefined)
- h->root.type = bfd_link_hash_new;
+ {
+ h->root.type = bfd_link_hash_new;
+ if (h->root.u.undef.next != NULL || htab->root.undefs_tail == &h->root)
+ bfd_link_repair_undef_list (&htab->root);
+ }
if (h->root.type == bfd_link_hash_new)
h->non_elf = 0;
h->def_regular = 1;
+ /* STV_HIDDEN and STV_INTERNAL symbols must be STB_LOCAL in shared objects
+ and executables. */
+ if (!info->relocatable
+ && h->dynindx != -1
+ && (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
+ || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL))
+ h->forced_local = 1;
+
if ((h->def_dynamic
|| h->ref_dynamic
- || info->shared)
+ || info->shared
+ || (info->executable && elf_hash_table (info)->is_relocatable_executable))
&& h->dynindx == -1)
{
if (! bfd_elf_link_record_dynamic_symbol (info, h))
if (h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ if (h->forced_local)
+ return TRUE;
+
+ if (h->dynindx != -1)
+ h->dynindx = ++(*count);
+
+ return TRUE;
+}
+
+
+/* Like elf_link_renumber_hash_table_dynsyms, but just number symbols with
+ STB_LOCAL binding. */
+
+static bfd_boolean
+elf_link_renumber_local_hash_table_dynsyms (struct elf_link_hash_entry *h,
+ void *data)
+{
+ size_t *count = data;
+
+ if (h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ if (!h->forced_local)
+ return TRUE;
+
if (h->dynindx != -1)
h->dynindx = ++(*count);
}
/* Assign dynsym indices. In a shared library we generate a section
- symbol for each output section, which come first. Next come all of
- the back-end allocated local dynamic syms, followed by the rest of
- the global symbols. */
+ symbol for each output section, which come first. Next come symbols
+ which have been forced to local binding. Then all of the back-end
+ allocated local dynamic syms, followed by the rest of the global
+ symbols. */
unsigned long
_bfd_elf_link_renumber_dynsyms (bfd *output_bfd, struct bfd_link_info *info)
{
unsigned long dynsymcount = 0;
- if (info->shared)
+ if (info->shared || elf_hash_table (info)->is_relocatable_executable)
{
const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
asection *p;
elf_section_data (p)->dynindx = ++dynsymcount;
}
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_link_renumber_local_hash_table_dynsyms,
+ &dynsymcount);
+
if (elf_hash_table (info)->dynlocal)
{
struct elf_link_local_dynamic_entry *p;
TYPE_CHANGE_OK if it is OK for the type to change. We set
SIZE_CHANGE_OK if it is OK for the size to change. By OK to
change, we mean that we shouldn't warn if the type or size does
- change. */
+ change. We set POLD_ALIGNMENT if an old common symbol in a dynamic
+ object is overridden by a regular object. */
bfd_boolean
_bfd_elf_merge_symbol (bfd *abfd,
Elf_Internal_Sym *sym,
asection **psec,
bfd_vma *pvalue,
+ unsigned int *pold_alignment,
struct elf_link_hash_entry **sym_hash,
bfd_boolean *skip,
bfd_boolean *override,
symbol is a function or is weak. */
flip = NULL;
- if (! newdyn
+ if (!newdyn
&& (newdef
|| (bfd_is_com_section (sec)
&& (oldweak
if (h->size > *pvalue)
*pvalue = h->size;
- /* FIXME: We no longer know the alignment required by the symbol
- in the dynamic object, so we just wind up using the one from
- the regular object. */
+ /* We need to remember the alignment required by the symbol
+ in the dynamic object. */
+ BFD_ASSERT (pold_alignment);
+ *pold_alignment = h->root.u.def.section->alignment_power;
olddef = FALSE;
olddyncommon = FALSE;
size_change_ok = FALSE;
sec = *psec;
if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &sec, value,
- &hi, &skip, &override, &type_change_ok,
- &size_change_ok))
+ NULL, &hi, &skip, &override,
+ &type_change_ok, &size_change_ok))
return FALSE;
if (skip)
size_change_ok = FALSE;
sec = *psec;
if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &sec, value,
- &hi, &skip, &override, &type_change_ok,
- &size_change_ok))
+ NULL, &hi, &skip, &override,
+ &type_change_ok, &size_change_ok))
return FALSE;
if (skip)
/* Proper resolution for function pointer equality may require
that these symbols perhaps be resolved dynamically, even though
we should be resolving them to the current module. */
- if (!ignore_protected)
+ if (!ignore_protected || h->type != STT_FUNC)
binding_stays_local_p = TRUE;
break;
if (ELF_ST_VISIBILITY (h->other) != STV_PROTECTED)
return TRUE;
+ /* STV_PROTECTED non-function symbols are local. */
+ if (h->type != STT_FUNC)
+ return TRUE;
+
/* Function pointer equality tests may require that STV_PROTECTED
symbols be treated as dynamic symbols, even when we know that the
dynamic linker will resolve them locally. */
1 if a DT_NEEDED tag already exists, and 0 on success. */
static int
-elf_add_dt_needed_tag (struct bfd_link_info *info,
+elf_add_dt_needed_tag (bfd *abfd,
+ struct bfd_link_info *info,
const char *soname,
bfd_boolean do_it)
{
bfd_size_type oldsize;
bfd_size_type strindex;
+ if (!_bfd_elf_link_create_dynstrtab (abfd, info))
+ return -1;
+
hash_table = elf_hash_table (info);
oldsize = _bfd_elf_strtab_size (hash_table->dynstr);
strindex = _bfd_elf_strtab_add (hash_table->dynstr, soname, FALSE);
bed = get_elf_backend_data (hash_table->dynobj);
sdyn = bfd_get_section_by_name (hash_table->dynobj, ".dynamic");
- BFD_ASSERT (sdyn != NULL);
-
- for (extdyn = sdyn->contents;
- extdyn < sdyn->contents + sdyn->size;
- extdyn += bed->s->sizeof_dyn)
- {
- Elf_Internal_Dyn dyn;
+ if (sdyn != NULL)
+ for (extdyn = sdyn->contents;
+ extdyn < sdyn->contents + sdyn->size;
+ extdyn += bed->s->sizeof_dyn)
+ {
+ Elf_Internal_Dyn dyn;
- bed->s->swap_dyn_in (hash_table->dynobj, extdyn, &dyn);
- if (dyn.d_tag == DT_NEEDED
- && dyn.d_un.d_val == strindex)
- {
- _bfd_elf_strtab_delref (hash_table->dynstr, strindex);
- return 1;
- }
- }
+ bed->s->swap_dyn_in (hash_table->dynobj, extdyn, &dyn);
+ if (dyn.d_tag == DT_NEEDED
+ && dyn.d_un.d_val == strindex)
+ {
+ _bfd_elf_strtab_delref (hash_table->dynstr, strindex);
+ return 1;
+ }
+ }
}
if (do_it)
{
+ if (!_bfd_elf_link_create_dynamic_sections (hash_table->dynobj, info))
+ return -1;
+
if (!_bfd_elf_add_dynamic_entry (info, DT_NEEDED, strindex))
return -1;
}
return 0;
}
+/* Called via elf_link_hash_traverse, elf_smash_syms sets all symbols
+ belonging to NOT_NEEDED to bfd_link_hash_new. We know there are no
+ references from regular objects to these symbols.
+
+ ??? Should we do something about references from other dynamic
+ obects? If not, we potentially lose some warnings about undefined
+ symbols. But how can we recover the initial undefined / undefweak
+ state? */
+
+struct elf_smash_syms_data
+{
+ bfd *not_needed;
+ struct elf_link_hash_table *htab;
+ bfd_boolean twiddled;
+};
+
+static bfd_boolean
+elf_smash_syms (struct elf_link_hash_entry *h, void *data)
+{
+ struct elf_smash_syms_data *inf = (struct elf_smash_syms_data *) data;
+ struct bfd_link_hash_entry *bh;
+
+ switch (h->root.type)
+ {
+ default:
+ case bfd_link_hash_new:
+ return TRUE;
+
+ case bfd_link_hash_undefined:
+ if (h->root.u.undef.abfd != inf->not_needed)
+ return TRUE;
+ if (h->root.u.undef.weak != NULL
+ && h->root.u.undef.weak != inf->not_needed)
+ {
+ /* Symbol was undefweak in u.undef.weak bfd, and has become
+ undefined in as-needed lib. Restore weak. */
+ h->root.type = bfd_link_hash_undefweak;
+ h->root.u.undef.abfd = h->root.u.undef.weak;
+ if (h->root.u.undef.next != NULL
+ || inf->htab->root.undefs_tail == &h->root)
+ inf->twiddled = TRUE;
+ return TRUE;
+ }
+ break;
+
+ case bfd_link_hash_undefweak:
+ if (h->root.u.undef.abfd != inf->not_needed)
+ return TRUE;
+ break;
+
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ if (h->root.u.def.section->owner != inf->not_needed)
+ return TRUE;
+ break;
+
+ case bfd_link_hash_common:
+ if (h->root.u.c.p->section->owner != inf->not_needed)
+ return TRUE;
+ break;
+
+ case bfd_link_hash_warning:
+ case bfd_link_hash_indirect:
+ elf_smash_syms ((struct elf_link_hash_entry *) h->root.u.i.link, data);
+ if (h->root.u.i.link->type != bfd_link_hash_new)
+ return TRUE;
+ if (h->root.u.i.link->u.undef.abfd != inf->not_needed)
+ return TRUE;
+ break;
+ }
+
+ /* There is no way we can undo symbol table state from defined or
+ defweak back to undefined. */
+ if (h->ref_regular)
+ abort ();
+
+ /* Set sym back to newly created state, but keep undefs list pointer. */
+ bh = h->root.u.undef.next;
+ if (bh != NULL || inf->htab->root.undefs_tail == &h->root)
+ inf->twiddled = TRUE;
+ (*inf->htab->root.table.newfunc) (&h->root.root,
+ &inf->htab->root.table,
+ h->root.root.string);
+ h->root.u.undef.next = bh;
+ h->root.u.undef.abfd = inf->not_needed;
+ h->non_elf = 0;
+ return TRUE;
+}
+
/* Sort symbol by value and section. */
static int
elf_sort_symbol (const void *arg1, const void *arg2)
{
char *msg;
bfd_size_type sz;
- bfd_size_type prefix_len;
- const char * gnu_warning_prefix = _("warning: ");
name += sizeof ".gnu.warning." - 1;
}
sz = s->size;
- prefix_len = strlen (gnu_warning_prefix);
- msg = bfd_alloc (abfd, prefix_len + sz + 1);
+ msg = bfd_alloc (abfd, sz + 1);
if (msg == NULL)
goto error_return;
- strcpy (msg, gnu_warning_prefix);
- if (! bfd_get_section_contents (abfd, s, msg + prefix_len, 0, sz))
+ if (! bfd_get_section_contents (abfd, s, msg, 0, sz))
goto error_return;
- msg[prefix_len + sz] = '\0';
+ msg[sz] = '\0';
if (! (_bfd_generic_link_add_one_symbol
(info, abfd, name, BSF_WARNING, s, 0, msg,
file. */
bfd_section_list_clear (abfd);
- /* If this is the first dynamic object found in the link, create
- the special sections required for dynamic linking. */
- if (! _bfd_elf_link_create_dynamic_sections (abfd, info))
- goto error_return;
-
/* Find the name to use in a DT_NEEDED entry that refers to this
object. If the object has a DT_SONAME entry, we use it.
Otherwise, if the generic linker stuck something in
will need to know it. */
elf_dt_name (abfd) = soname;
- ret = elf_add_dt_needed_tag (info, soname, add_needed);
+ ret = elf_add_dt_needed_tag (abfd, info, soname, add_needed);
if (ret < 0)
goto error_return;
{
int bind;
bfd_vma value;
- asection *sec;
+ asection *sec, *new_sec;
flagword flags;
const char *name;
struct elf_link_hash_entry *h;
sec = bfd_abs_section_ptr;
else if (sec->kept_section)
{
- /* Symbols from discarded section are undefined. */
+ /* Symbols from discarded section are undefined, and have
+ default visibility. */
sec = bfd_und_section_ptr;
isym->st_shndx = SHN_UNDEF;
+ isym->st_other = STV_DEFAULT
+ | (isym->st_other & ~ ELF_ST_VISIBILITY(-1));
}
else if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
value -= sec->vma;
type_change_ok = get_elf_backend_data (abfd)->type_change_ok;
old_alignment = 0;
old_bfd = NULL;
+ new_sec = sec;
if (is_elf_hash_table (hash_table))
{
name = newname;
}
- if (!_bfd_elf_merge_symbol (abfd, info, name, isym, &sec, &value,
+ if (!_bfd_elf_merge_symbol (abfd, info, name, isym, &sec,
+ &value, &old_alignment,
sym_hash, &skip, &override,
&type_change_ok, &size_change_ok))
goto error_free_vers;
}
/* Set the alignment of a common symbol. */
- if (isym->st_shndx == SHN_COMMON
+ if ((isym->st_shndx == SHN_COMMON
+ || bfd_is_com_section (sec))
&& h->root.type == bfd_link_hash_common)
{
unsigned int align;
- align = bfd_log2 (isym->st_value);
+ if (isym->st_shndx == SHN_COMMON)
+ align = bfd_log2 (isym->st_value);
+ else
+ {
+ /* The new symbol is a common symbol in a shared object.
+ We need to get the alignment from the section. */
+ align = new_sec->alignment_power;
+ }
if (align > old_alignment
/* Permit an alignment power of zero if an alignment of one
is specified and no other alignments have been specified. */
goto error_free_vers;
}
+ elf_dyn_lib_class (abfd) &= ~DYN_AS_NEEDED;
+
add_needed = TRUE;
- ret = elf_add_dt_needed_tag (info, soname, add_needed);
+ ret = elf_add_dt_needed_tag (abfd, info, soname, add_needed);
if (ret < 0)
goto error_free_vers;
free (isymbuf);
isymbuf = NULL;
+ if (!add_needed
+ && (elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0)
+ {
+ /* Remove symbols defined in an as-needed shared lib that wasn't
+ needed. */
+ struct elf_smash_syms_data inf;
+ inf.not_needed = abfd;
+ inf.htab = hash_table;
+ inf.twiddled = FALSE;
+ elf_link_hash_traverse (hash_table, elf_smash_syms, &inf);
+ if (inf.twiddled)
+ bfd_link_repair_undef_list (&hash_table->root);
+ weaks = NULL;
+ }
+
/* Now set the weakdefs field correctly for all the weak defined
symbols we found. The only way to do this is to search all the
symbols. Since we only need the information for non functions in
}
}
- if (is_elf_hash_table (hash_table))
+ if (is_elf_hash_table (hash_table) && add_needed)
{
/* Add this bfd to the loaded list. */
struct elf_link_loaded_list *n;
{
asection *s;
- if (inputobj->flags & DYNAMIC)
+ if (inputobj->flags & (DYNAMIC | BFD_LINKER_CREATED))
continue;
s = bfd_get_section_by_name (inputobj, ".note.GNU-stack");
if (s)
if (h->indx == -2)
strip = FALSE;
else if ((h->def_dynamic
- || h->ref_dynamic)
+ || h->ref_dynamic
+ || h->root.type == bfd_link_hash_new)
&& !h->def_regular
&& !h->ref_regular)
strip = TRUE;
For the benefit of the MIPS ELF linker, we check SEC_EXCLUDE
as well as linker_mark. */
if ((isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE)
- && isec != NULL
- && ((! isec->linker_mark && (isec->flags & SEC_HAS_CONTENTS) != 0)
+ && (isec == NULL
+ || (! isec->linker_mark && (isec->flags & SEC_HAS_CONTENTS) != 0)
|| (! finfo->info->relocatable
&& (isec->flags & SEC_EXCLUDE) != 0)))
continue;
goto error_return;
}
-#if 0
- /* Some standard ELF linkers do this, but we don't because it causes
- bootstrap comparison failures. */
- /* Output a file symbol for the output file as the second symbol.
- We output this even if we are discarding local symbols, although
- I'm not sure if this is correct. */
- elfsym.st_value = 0;
- elfsym.st_size = 0;
- elfsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE);
- elfsym.st_other = 0;
- elfsym.st_shndx = SHN_ABS;
- if (! elf_link_output_sym (&finfo, bfd_get_filename (abfd),
- &elfsym, bfd_abs_section_ptr, NULL))
- goto error_return;
-#endif
-
/* Output a symbol for each section. We output these even if we are
discarding local symbols, since they are used for relocs. These
symbols have no names. We store the index of each one in the
long last_local = 0;
/* Write out the section symbols for the output sections. */
- if (info->shared)
+ if (info->shared || elf_hash_table (info)->is_relocatable_executable)
{
asection *s;