Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 6323 → Rev 6324

/contrib/toolchain/binutils/bfd/elflink.c
1,5 → 1,5
/* ELF linking support for BFD.
Copyright 1995-2013 Free Software Foundation, Inc.
Copyright (C) 1995-2015 Free Software Foundation, Inc.
 
This file is part of BFD, the Binary File Descriptor library.
 
20,6 → 20,7
 
#include "sysdep.h"
#include "bfd.h"
#include "bfd_stdint.h"
#include "bfdlink.h"
#include "libbfd.h"
#define ARCH_SIZE 0
53,6 → 54,47
static bfd_boolean _bfd_elf_fix_symbol_flags
(struct elf_link_hash_entry *, struct elf_info_failed *);
 
asection *
_bfd_elf_section_for_symbol (struct elf_reloc_cookie *cookie,
unsigned long r_symndx,
bfd_boolean discard)
{
if (r_symndx >= cookie->locsymcount
|| ELF_ST_BIND (cookie->locsyms[r_symndx].st_info) != STB_LOCAL)
{
struct elf_link_hash_entry *h;
 
h = cookie->sym_hashes[r_symndx - cookie->extsymoff];
 
while (h->root.type == bfd_link_hash_indirect
|| h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
 
if ((h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
&& discarded_section (h->root.u.def.section))
return h->root.u.def.section;
else
return NULL;
}
else
{
/* It's not a relocation against a global symbol,
but it could be a relocation against a local
symbol for a discarded section. */
asection *isec;
Elf_Internal_Sym *isym;
 
/* Need to: get the symbol; get the section. */
isym = &cookie->locsyms[r_symndx];
isec = bfd_section_from_elf_index (cookie->abfd, isym->st_shndx);
if (isec != NULL
&& discard ? discarded_section (isec) : 1)
return isec;
}
return NULL;
}
 
/* Define a symbol in a dynamic linkage section. */
 
struct elf_link_hash_entry *
76,19 → 118,19
}
 
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;
h->def_regular = 1;
h->non_elf = 0;
h->root.linker_def = 1;
h->type = STT_OBJECT;
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;
}
204,7 → 246,7
 
/* A dynamically linked executable has a .interp section, but a
shared library does not. */
if (info->executable)
if (bfd_link_executable (info) && !info->nointerp)
{
s = bfd_make_section_anyway_with_flags (abfd, ".interp",
flags | SEC_READONLY);
237,6 → 279,7
if (s == NULL
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
return FALSE;
elf_hash_table (info)->dynsym = s;
 
s = bfd_make_section_anyway_with_flags (abfd, ".dynstr",
flags | SEC_READONLY);
376,7 → 419,7
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)
if (! bfd_link_pic (info))
{
s = bfd_make_section_anyway_with_flags (abfd,
(bed->rela_plts_and_copies_p
477,7 → 520,7
struct bfd_elf_dynamic_list *d = info->dynamic_list;
 
/* It may be called more than once on the same H. */
if(h->dynamic || info->relocatable)
if(h->dynamic || bfd_link_relocatable (info))
return;
 
if ((info->dynamic_data
581,7 → 624,7
 
/* STV_HIDDEN and STV_INTERNAL symbols must be STB_LOCAL in shared objects
and executables. */
if (!info->relocatable
if (!bfd_link_relocatable (info)
&& h->dynindx != -1
&& (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
|| ELF_ST_VISIBILITY (h->other) == STV_INTERNAL))
589,8 → 632,9
 
if ((h->def_dynamic
|| h->ref_dynamic
|| info->shared
|| (info->executable && elf_hash_table (info)->is_relocatable_executable))
|| bfd_link_pic (info)
|| (bfd_link_pde (info)
&& elf_hash_table (info)->is_relocatable_executable))
&& h->dynindx == -1)
{
if (! bfd_elf_link_record_dynamic_symbol (info, h))
760,6 → 804,7
asection *p)
{
struct elf_link_hash_table *htab;
asection *ip;
 
switch (elf_section_data (p)->this_hdr.sh_type)
{
775,18 → 820,9
if (htab->text_index_section != NULL)
return p != htab->text_index_section && p != htab->data_index_section;
 
if (strcmp (p->name, ".got") == 0
|| strcmp (p->name, ".got.plt") == 0
|| strcmp (p->name, ".plt") == 0)
{
asection *ip;
 
if (htab->dynobj != NULL
return (htab->dynobj != NULL
&& (ip = bfd_get_linker_section (htab->dynobj, p->name)) != NULL
&& ip->output_section == p)
return TRUE;
}
return FALSE;
&& ip->output_section == p);
 
/* There shouldn't be section relative relocations
against any other section. */
808,7 → 844,8
{
unsigned long dynsymcount = 0;
 
if (info->shared || elf_hash_table (info)->is_relocatable_executable)
if (bfd_link_pic (info)
|| elf_hash_table (info)->is_relocatable_executable)
{
const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
asection *p;
851,48 → 888,31
 
static void
elf_merge_st_other (bfd *abfd, struct elf_link_hash_entry *h,
Elf_Internal_Sym *isym, bfd_boolean definition,
bfd_boolean dynamic)
const Elf_Internal_Sym *isym, asection *sec,
bfd_boolean definition, bfd_boolean dynamic)
{
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
/* If st_other has a processor-specific meaning, specific
code might be needed here. We never merge the visibility
attribute with the one from a dynamic object. */
code might be needed here. */
if (bed->elf_backend_merge_symbol_attribute)
(*bed->elf_backend_merge_symbol_attribute) (h, isym, definition,
dynamic);
 
/* If this symbol has default visibility and the user has 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))
&& ELF_ST_VISIBILITY (isym->st_other) != STV_INTERNAL)
isym->st_other = (STV_HIDDEN
| (isym->st_other & ~ELF_ST_VISIBILITY (-1)));
 
if (!dynamic && ELF_ST_VISIBILITY (isym->st_other) != 0)
if (!dynamic)
{
unsigned char hvis, symvis, other, nvis;
unsigned symvis = ELF_ST_VISIBILITY (isym->st_other);
unsigned hvis = ELF_ST_VISIBILITY (h->other);
 
/* Only merge the visibility. Leave the remainder of the
st_other field to elf_backend_merge_symbol_attribute. */
other = h->other & ~ELF_ST_VISIBILITY (-1);
 
/* Combine visibilities, using the most constraining one. */
hvis = ELF_ST_VISIBILITY (h->other);
symvis = ELF_ST_VISIBILITY (isym->st_other);
if (! hvis)
nvis = symvis;
else if (! symvis)
nvis = hvis;
else
nvis = hvis < symvis ? hvis : symvis;
 
h->other = other | nvis;
/* Keep the most constraining visibility. Leave the remainder
of the st_other field to elf_backend_merge_symbol_attribute. */
if (symvis - 1 < hvis - 1)
h->other = symvis | (h->other & ~ELF_ST_VISIBILITY (-1));
}
else if (definition
&& ELF_ST_VISIBILITY (isym->st_other) != STV_DEFAULT
&& (sec->flags & SEC_READONLY) == 0)
h->protected_def = 1;
}
 
/* This function is called when we want to merge a new symbol with an
922,7 → 942,8
bfd_boolean *skip,
bfd_boolean *override,
bfd_boolean *type_change_ok,
bfd_boolean *size_change_ok)
bfd_boolean *size_change_ok,
bfd_boolean *matched)
{
asection *sec, *oldsec;
struct elf_link_hash_entry *h;
933,6 → 954,7
bfd_boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon;
bfd_boolean newweak, oldweak, newfunc, oldfunc;
const struct elf_backend_data *bed;
char *new_version;
 
*skip = FALSE;
*override = FALSE;
951,6 → 973,30
 
bed = get_elf_backend_data (abfd);
 
/* NEW_VERSION is the symbol version of the new symbol. */
if (h->versioned != unversioned)
{
/* Symbol version is unknown or versioned. */
new_version = strrchr (name, ELF_VER_CHR);
if (new_version)
{
if (h->versioned == unknown)
{
if (new_version > name && new_version[-1] != ELF_VER_CHR)
h->versioned = versioned_hidden;
else
h->versioned = versioned;
}
new_version += 1;
if (new_version[0] == '\0')
new_version = NULL;
}
else
h->versioned = unversioned;
}
else
new_version = NULL;
 
/* For merging, we only care about real symbols. But we need to make
sure that indirect symbol dynamic flags are updated. */
hi = h;
958,6 → 1004,44
|| h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
 
if (!*matched)
{
if (hi == h || h->root.type == bfd_link_hash_new)
*matched = TRUE;
else
{
/* OLD_HIDDEN is true if the existing symbol is only visible
to the symbol with the same symbol version. NEW_HIDDEN is
true if the new symbol is only visible to the symbol with
the same symbol version. */
bfd_boolean old_hidden = h->versioned == versioned_hidden;
bfd_boolean new_hidden = hi->versioned == versioned_hidden;
if (!old_hidden && !new_hidden)
/* The new symbol matches the existing symbol if both
aren't hidden. */
*matched = TRUE;
else
{
/* OLD_VERSION is the symbol version of the existing
symbol. */
char *old_version;
 
if (h->versioned >= versioned)
old_version = strrchr (h->root.root.string,
ELF_VER_CHR) + 1;
else
old_version = NULL;
 
/* The new symbol matches the existing symbol if they
have the same symbol version. */
*matched = (old_version == new_version
|| (old_version != NULL
&& new_version != NULL
&& strcmp (old_version, new_version) == 0));
}
}
}
 
/* OLDBFD and OLDSEC are a BFD and an ASECTION associated with the
existing symbol. */
 
1030,6 → 1114,8
}
else
{
/* Update the existing symbol only if they match. */
if (*matched)
h->dynamic_def = 1;
hi->dynamic_def = 1;
}
1087,32 → 1173,30
 
/* When we try to create a default indirect symbol from the dynamic
definition with the default version, we skip it if its type and
the type of existing regular definition mismatch. We only do it
if the existing regular definition won't be dynamic. */
the type of existing regular definition mismatch. */
if (pold_alignment == NULL
&& !info->shared
&& !info->export_dynamic
&& !h->ref_dynamic
&& newdyn
&& newdef
&& !olddyn
&& (olddef || h->root.type == bfd_link_hash_common)
&& (((olddef || h->root.type == bfd_link_hash_common)
&& ELF_ST_TYPE (sym->st_info) != h->type
&& ELF_ST_TYPE (sym->st_info) != STT_NOTYPE
&& h->type != STT_NOTYPE
&& !(newfunc && oldfunc))
|| (olddef
&& ((h->type == STT_GNU_IFUNC)
!= (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)))))
{
*skip = TRUE;
return TRUE;
}
 
/* Plugin symbol type isn't currently set. Stop bogus errors. */
if (oldbfd != NULL && (oldbfd->flags & BFD_PLUGIN) != 0)
*type_change_ok = TRUE;
 
/* Check TLS symbol. We don't check undefined symbol introduced by
"ld -u". */
else if (oldbfd != NULL
/* Check TLS symbols. We don't check undefined symbols introduced
by "ld -u" which have no type (and oldbfd NULL), and we don't
check symbols from plugins because they also have no type. */
if (oldbfd != NULL
&& (oldbfd->flags & BFD_PLUGIN) == 0
&& (abfd->flags & BFD_PLUGIN) == 0
&& ELF_ST_TYPE (sym->st_info) != h->type
&& (ELF_ST_TYPE (sym->st_info) == STT_TLS || h->type == STT_TLS))
{
1437,12 → 1521,15
if (!(oldbfd != NULL
&& (oldbfd->flags & BFD_PLUGIN) != 0
&& (abfd->flags & BFD_PLUGIN) == 0))
{
newdef = FALSE;
*skip = TRUE;
}
 
/* Merge st_other. If the symbol already has a dynamic index,
but visibility says it should not be visible, turn it into a
local symbol. */
elf_merge_st_other (abfd, h, sym, newdef, newdyn);
elf_merge_st_other (abfd, h, sym, sec, newdef, newdyn);
if (h->dynindx != -1)
switch (ELF_ST_VISIBILITY (h->other))
{
1600,14 → 1687,41
char *p;
size_t len, shortlen;
asection *tmp_sec;
bfd_boolean matched;
 
if (h->versioned == unversioned || h->versioned == versioned_hidden)
return TRUE;
 
/* If this symbol has a version, and it is the default version, we
create an indirect symbol from the default name to the fully
decorated name. This will cause external references which do not
specify a version to be bound to this version of the symbol. */
p = strchr (name, ELF_VER_CHR);
if (p == NULL || p[1] != ELF_VER_CHR)
if (h->versioned == unknown)
{
if (p == NULL)
{
h->versioned = unversioned;
return TRUE;
}
else
{
if (p[1] != ELF_VER_CHR)
{
h->versioned = versioned_hidden;
return TRUE;
}
else
h->versioned = versioned;
}
}
else
{
/* PR ld/19073: We may see an unversioned definition after the
default version. */
if (p == NULL)
return TRUE;
}
 
bed = get_elf_backend_data (abfd);
collect = bed->collect;
1626,10 → 1740,11
actually going to define an indirect symbol. */
type_change_ok = FALSE;
size_change_ok = FALSE;
matched = TRUE;
tmp_sec = sec;
if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &tmp_sec, &value,
&hi, poldbfd, NULL, NULL, &skip, &override,
&type_change_ok, &size_change_ok))
&type_change_ok, &size_change_ok, &matched))
return FALSE;
 
if (skip)
1637,13 → 1752,18
 
if (! override)
{
/* Add the default symbol if not performing a relocatable link. */
if (! bfd_link_relocatable (info))
{
bh = &hi->root;
if (! (_bfd_generic_link_add_one_symbol
(info, abfd, shortname, BSF_INDIRECT, bfd_ind_section_ptr,
(info, abfd, shortname, BSF_INDIRECT,
bfd_ind_section_ptr,
0, name, FALSE, collect, &bh)))
return FALSE;
hi = (struct elf_link_hash_entry *) bh;
}
}
else
{
/* In this case the symbol named SHORTNAME is overriding the
1702,6 → 1822,12
ht = (struct elf_link_hash_entry *) hi->root.u.i.link;
(*bed->elf_backend_copy_indirect_symbol) (info, ht, hi);
 
/* A reference to the SHORTNAME symbol from a dynamic library
will be satisfied by the versioned symbol at runtime. In
effect, we have a reference to the versioned symbol. */
ht->ref_dynamic_nonweak |= hi->ref_dynamic_nonweak;
hi->dynamic_def |= ht->dynamic_def;
 
/* See if the new flags lead us to realize that the symbol must
be dynamic. */
if (! *dynsym)
1708,7 → 1834,7
{
if (! dynamic)
{
if (! info->executable
if (! bfd_link_executable (info)
|| hi->def_dynamic
|| hi->ref_dynamic)
*dynsym = TRUE;
1737,8 → 1863,8
size_change_ok = FALSE;
tmp_sec = sec;
if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &tmp_sec, &value,
&hi, NULL, NULL, NULL, &skip, &override,
&type_change_ok, &size_change_ok))
&hi, poldbfd, NULL, NULL, &skip, &override,
&type_change_ok, &size_change_ok, &matched))
return FALSE;
 
if (skip)
1771,6 → 1897,8
if (hi->root.type == bfd_link_hash_indirect)
{
(*bed->elf_backend_copy_indirect_symbol) (info, h, hi);
h->ref_dynamic_nonweak |= hi->ref_dynamic_nonweak;
hi->dynamic_def |= h->dynamic_def;
 
/* See if the new flags lead us to realize that the symbol
must be dynamic. */
1778,7 → 1906,7
{
if (! dynamic)
{
if (! info->executable
if (! bfd_link_executable (info)
|| hi->ref_dynamic)
*dynsym = TRUE;
}
1844,7 → 1972,9
if (!h->def_dynamic
|| h->def_regular
|| h->dynindx == -1
|| h->verinfo.verdef == NULL)
|| h->verinfo.verdef == NULL
|| (elf_dyn_lib_class (h->verinfo.verdef->vd_bfd)
& (DYN_AS_NEEDED | DYN_DT_NEEDED | DYN_NO_NEEDED)))
return TRUE;
 
/* See if we already know about this version. */
1944,26 → 2074,14
if (p != NULL && h->verinfo.vertree == NULL)
{
struct bfd_elf_version_tree *t;
bfd_boolean hidden;
 
hidden = TRUE;
 
/* There are two consecutive ELF_VER_CHR characters if this is
not a hidden symbol. */
++p;
if (*p == ELF_VER_CHR)
{
hidden = FALSE;
++p;
}
 
/* If there is no version string, we can just return out. */
if (*p == '\0')
{
if (hidden)
h->hidden = 1;
return TRUE;
}
 
/* Look for the version. If we find it, it is no longer weak. */
for (t = sinfo->info->version_info; t != NULL; t = t->next)
2011,7 → 2129,7
 
/* If we are building an application, we need to create a
version node for this version. */
if (t == NULL && info->executable)
if (t == NULL && bfd_link_executable (info))
{
struct bfd_elf_version_tree **pp;
int version_index;
2059,9 → 2177,6
sinfo->failed = TRUE;
return FALSE;
}
 
if (hidden)
h->hidden = 1;
}
 
/* If we don't have a version for this symbol, see if we can find
2295,8 → 2410,8
{
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;
 
2376,7 → 2491,7
_bfd_elf_link_hash_fixup_symbol (struct bfd_link_info *info,
struct elf_link_hash_entry *h)
{
if (info->pie
if (bfd_link_pie (info)
&& h->dynindx == -1
&& h->root.type == bfd_link_hash_undefweak)
return bfd_elf_link_record_dynamic_symbol (info, h);
2479,7 → 2594,7
visibility. If the symbol has hidden or internal visibility, we
will force it local. */
if (h->needs_plt
&& eif->info->shared
&& bfd_link_pic (eif->info)
&& is_elf_hash_table (eif->info->hash)
&& (SYMBOLIC_BIND (eif->info, h)
|| ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
2646,7 → 2761,8
DYNBSS. */
 
bfd_boolean
_bfd_elf_adjust_dynamic_copy (struct elf_link_hash_entry *h,
_bfd_elf_adjust_dynamic_copy (struct bfd_link_info *info,
struct elf_link_hash_entry *h,
asection *dynbss)
{
unsigned int power_of_two;
2685,6 → 2801,15
/* Increment the size of DYNBSS to make room for the symbol. */
dynbss->size += h->size;
 
/* No error if extern_protected_data is true. */
if (h->protected_def
&& (!info->extern_protected_data
|| (info->extern_protected_data < 0
&& !get_elf_backend_data (dynbss->owner)->extern_protected_data)))
info->callbacks->einfo
(_("%P: copy reloc against protected `%T' is dangerous\n"),
h->root.root.string);
 
return TRUE;
}
 
2741,7 → 2866,8
 
/* Identify the cases where name binding rules say that a
visible symbol resolves locally. */
binding_stays_local_p = info->executable || SYMBOLIC_BIND (info, h);
binding_stays_local_p = (bfd_link_executable (info)
|| SYMBOLIC_BIND (info, h));
 
switch (ELF_ST_VISIBILITY (h->other))
{
2826,7 → 2952,7
/* 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 || SYMBOLIC_BIND (info, h))
if (bfd_link_executable (info) || SYMBOLIC_BIND (info, h))
return TRUE;
 
/* Now deal with defined dynamic symbols in shared libraries. Ones
2840,8 → 2966,12
 
bed = get_elf_backend_data (hash_table->dynobj);
 
/* STV_PROTECTED non-function symbols are local. */
if (!bed->is_function_type (h->type))
/* If extern_protected_data is false, STV_PROTECTED non-function
symbols are local. */
if ((!info->extern_protected_data
|| (info->extern_protected_data < 0
&& !bed->extern_protected_data))
&& !bed->is_function_type (h->type))
return TRUE;
 
/* Function pointer equality tests may require that STV_PROTECTED
2940,14 → 3070,11
if (abfd == NULL)
return FALSE;
 
if (! bfd_check_format (abfd, bfd_object))
/* Return FALSE if the object has been claimed by plugin. */
if (abfd->plugin_format == bfd_plugin_yes)
return FALSE;
 
/* If we have already included the element containing this symbol in the
link then we do not need to include it again. Just claim that any symbol
it contains is not a definition, so that our caller will not decide to
(re)include this element. */
if (abfd->archive_pass)
if (! bfd_check_format (abfd, bfd_object))
return FALSE;
 
/* Select the appropriate symbol table. */
3105,7 → 3232,8
on_needed_list (const char *soname, struct bfd_link_needed_list *needed)
{
for (; needed != NULL; needed = needed->next)
if (strcmp (soname, needed->name) == 0)
if ((elf_dyn_lib_class (needed->by) & DYN_AS_NEEDED) == 0
&& strcmp (soname, needed->name) == 0)
return TRUE;
 
return FALSE;
3126,7 → 3254,7
return vdiff > 0 ? 1 : -1;
else
{
long sdiff = h1->root.u.def.section->id - h2->root.u.def.section->id;
int sdiff = h1->root.u.def.section->id - h2->root.u.def.section->id;
if (sdiff != 0)
return sdiff > 0 ? 1 : -1;
}
3318,7 → 3446,7
struct bfd_link_info *info,
enum notice_asneeded_action act)
{
return (*info->callbacks->notice) (info, NULL, ibfd, NULL, act, 0, NULL);
return (*info->callbacks->notice) (info, NULL, NULL, ibfd, NULL, act, 0);
}
 
/* Add symbols from an ELF object file to the linker hash table. */
3357,6 → 3485,7
bfd_size_type old_dynstr_size = 0;
size_t tabsize = 0;
asection *s;
bfd_boolean just_syms;
 
htab = elf_hash_table (info);
bed = get_elf_backend_data (abfd);
3370,11 → 3499,11
/* You can't use -r against a dynamic object. Also, there's no
hope of using a dynamic object which does not exactly match
the format of the output file. */
if (info->relocatable
if (bfd_link_relocatable (info)
|| !is_elf_hash_table (htab)
|| info->output_bfd->xvec != abfd->xvec)
{
if (info->relocatable)
if (bfd_link_relocatable (info))
bfd_set_error (bfd_error_invalid_operation);
else
bfd_set_error (bfd_error_wrong_format);
3447,7 → 3576,7
FALSE, bed->collect, NULL)))
goto error_return;
 
if (!info->relocatable && info->executable)
if (bfd_link_executable (info))
{
/* Clobber the section size so that the warning does
not get copied into the output file. */
3460,6 → 3589,9
}
}
 
just_syms = ((s = abfd->sections) != NULL
&& s->sec_info_type == SEC_INFO_TYPE_JUST_SYMS);
 
add_needed = TRUE;
if (! dynamic)
{
3466,9 → 3598,11
/* If we are creating a shared library, create all the dynamic
sections immediately. We need to attach them to something,
so we attach them to this BFD, provided it is the right
format. FIXME: If there are no input BFD's of the same
format as the output, we can't make a shared library. */
if (info->shared
format and is not from ld --just-symbols. FIXME: If there
are no input BFD's of the same format as the output, we can't
make a shared library. */
if (!just_syms
&& bfd_link_pic (info)
&& is_elf_hash_table (htab)
&& info->output_bfd->xvec == abfd->xvec
&& !htab->dynamic_sections_created)
3488,8 → 3622,7
 
/* ld --just-symbols and dynamic objects don't mix very well.
ld shouldn't allow it. */
if ((s = abfd->sections) != NULL
&& s->sec_info_type == SEC_INFO_TYPE_JUST_SYMS)
if (just_syms)
abort ();
 
/* If this dynamic lib was specified on the command line with
3835,6 → 3968,7
bfd_boolean common;
unsigned int old_alignment;
bfd *old_bfd;
bfd_boolean matched;
 
override = FALSE;
 
3920,7 → 4054,7
}
else if (isym->st_shndx == SHN_COMMON
&& ELF_ST_TYPE (isym->st_info) == STT_TLS
&& !info->relocatable)
&& !bfd_link_relocatable (info))
{
asection *tcomm = bfd_get_section_by_name (abfd, ".tcommon");
 
3969,6 → 4103,7
size_change_ok = FALSE;
type_change_ok = bed->type_change_ok;
old_weak = FALSE;
matched = FALSE;
old_alignment = 0;
old_bfd = NULL;
new_sec = sec;
4086,16 → 4221,28
name = newname;
}
 
/* If this symbol has default visibility and the user has
requested we not re-export it, then mark it as hidden. */
if (!bfd_is_und_section (sec)
&& !dynamic
&& abfd->no_export
&& ELF_ST_VISIBILITY (isym->st_other) != STV_INTERNAL)
isym->st_other = (STV_HIDDEN
| (isym->st_other & ~ELF_ST_VISIBILITY (-1)));
 
if (!_bfd_elf_merge_symbol (abfd, info, name, isym, &sec, &value,
sym_hash, &old_bfd, &old_weak,
&old_alignment, &skip, &override,
&type_change_ok, &size_change_ok))
&type_change_ok, &size_change_ok,
&matched))
goto error_free_vers;
 
if (skip)
continue;
 
if (override)
/* Override a definition only if the new symbol matches the
existing one. */
if (override && matched)
definition = FALSE;
 
h = *sym_hash;
4203,7 → 4350,7
/* If the indirect symbol has been forced local, don't
make the real symbol dynamic. */
if ((h == hi || !hi->forced_local)
&& (! info->executable
&& (bfd_link_dll (info)
|| h->def_dynamic
|| h->ref_dynamic))
dynsym = TRUE;
4352,10 → 4499,12
}
 
/* Merge st_other field. */
elf_merge_st_other (abfd, h, isym, definition, dynamic);
elf_merge_st_other (abfd, h, isym, sec, definition, dynamic);
 
/* We don't want to make debug symbol dynamic. */
if (definition && (sec->flags & SEC_DEBUGGING) && !info->relocatable)
if (definition
&& (sec->flags & SEC_DEBUGGING)
&& !bfd_link_relocatable (info))
dynsym = FALSE;
 
/* Nor should we make plugin symbols dynamic. */
4379,8 → 4528,8
{
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;
}
4427,6 → 4576,9
int ret;
const char *soname = elf_dt_name (abfd);
 
info->callbacks->minfo ("%!", soname, old_bfd,
h->root.root.string);
 
/* A symbol from a library loaded via DT_NEEDED of some
other library is referenced by a regular object.
Add a DT_NEEDED entry for it. Issue an error if
4552,9 → 4704,10
old_tab = NULL;
}
 
/* Now that all the symbols from this input file are created, handle
.symver foo, foo@BAR such that any relocs against foo become foo@BAR. */
if (nondeflt_vers != NULL)
/* Now that all the symbols from this input file are created, if
not performing a relocatable link, handle .symver foo, foo@BAR
such that any relocs against foo become foo@BAR. */
if (!bfd_link_relocatable (info) && nondeflt_vers != NULL)
{
bfd_size_type cnt, symidx;
 
4684,7 → 4837,7
i = idx + 1;
else
{
long sdiff = slook->id - h->root.u.def.section->id;
int sdiff = slook->id - h->root.u.def.section->id;
if (sdiff < 0)
j = idx;
else if (sdiff > 0)
4852,8 → 5005,7
/* 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;
4927,20 → 5079,8
}
 
/* Add symbols from an ELF archive file to the linker hash table. We
don't use _bfd_generic_link_add_archive_symbols because of a
problem which arises on UnixWare. The UnixWare libc.so is an
archive which includes an entry libc.so.1 which defines a bunch of
symbols. The libc.so archive also includes a number of other
object files, which also define symbols, some of which are the same
as those defined in libc.so.1. Correct linking requires that we
consider each object file in turn, and include it if it defines any
symbols we need. _bfd_generic_link_add_archive_symbols does not do
this; it looks through the list of undefined symbols, and includes
any object file which defines them. When this algorithm is used on
UnixWare, it winds up pulling in libc.so.1 early and defining a
bunch of symbols. This means that some of the other objects in the
archive are not included in the link, which is incorrect since they
precede libc.so.1 in the archive.
don't use _bfd_generic_link_add_archive_symbols because we need to
handle versioned symbols.
 
Fortunately, ELF archive handling is simpler than that done by
_bfd_generic_link_add_archive_symbols, which has to allow for a.out
4955,8 → 5095,7
elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
{
symindex c;
bfd_boolean *defined = NULL;
bfd_boolean *included = NULL;
unsigned char *included = NULL;
carsym *symdefs;
bfd_boolean loop;
bfd_size_type amt;
4980,11 → 5119,10
if (c == 0)
return TRUE;
amt = c;
amt *= sizeof (bfd_boolean);
defined = (bfd_boolean *) bfd_zmalloc (amt);
included = (bfd_boolean *) bfd_zmalloc (amt);
if (defined == NULL || included == NULL)
goto error_return;
amt *= sizeof (*included);
included = (unsigned char *) bfd_zmalloc (amt);
if (included == NULL)
return FALSE;
 
symdefs = bfd_ardata (abfd)->symdefs;
bed = get_elf_backend_data (abfd);
5009,7 → 5147,7
struct bfd_link_hash_entry *undefs_tail;
symindex mark;
 
if (defined[i] || included[i])
if (included[i])
continue;
if (symdef->file_offset == last)
{
5044,7 → 5182,8
else if (h->root.type != bfd_link_hash_undefined)
{
if (h->root.type != bfd_link_hash_undefweak)
defined[i] = TRUE;
/* Symbol must be defined. Don't check it again. */
included[i] = TRUE;
continue;
}
 
5056,16 → 5195,6
if (! bfd_check_format (element, bfd_object))
goto error_return;
 
/* Doublecheck that we have not included this object
already--it should be impossible, but there may be
something wrong with the archive. */
if (element->archive_pass != 0)
{
bfd_set_error (bfd_error_bad_value);
goto error_return;
}
element->archive_pass = 1;
 
undefs_tail = info->hash->undefs_tail;
 
if (!(*info->callbacks
5103,14 → 5232,11
}
while (loop);
 
free (defined);
free (included);
 
return TRUE;
 
error_return:
if (defined != NULL)
free (defined);
if (included != NULL)
free (included);
return FALSE;
5148,7 → 5274,6
{
struct hash_codes_info *inf = (struct hash_codes_info *) data;
const char *name;
char *p;
unsigned long ha;
char *alc = NULL;
 
5157,7 → 5282,9
return TRUE;
 
name = h->root.root.string;
p = strchr (name, ELF_VER_CHR);
if (h->versioned >= versioned)
{
char *p = strchr (name, ELF_VER_CHR);
if (p != NULL)
{
alc = (char *) bfd_malloc (p - name + 1);
5170,6 → 5297,7
alc[p - name] = '\0';
name = alc;
}
}
 
/* Compute the hash value. */
ha = bfd_elf_hash (name);
5216,7 → 5344,6
{
struct collect_gnu_hash_codes *s = (struct collect_gnu_hash_codes *) data;
const char *name;
char *p;
unsigned long ha;
char *alc = NULL;
 
5229,7 → 5356,9
return TRUE;
 
name = h->root.root.string;
p = strchr (name, ELF_VER_CHR);
if (h->versioned >= versioned)
{
char *p = strchr (name, ELF_VER_CHR);
if (p != NULL)
{
alc = (char *) bfd_malloc (p - name + 1);
5242,6 → 5371,7
alc[p - name] = '\0';
name = alc;
}
}
 
/* Compute the hash value. */
ha = bfd_elf_gnu_hash (name);
5476,7 → 5606,7
{
bfd *ibfd;
 
for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
&& !_bfd_elf_fixup_group_sections (ibfd, bfd_abs_section_ptr))
return FALSE;
5579,7 → 5709,7
elf_hash_table (info)->init_plt_refcount
= elf_hash_table (info)->init_plt_offset;
 
if (info->relocatable
if (bfd_link_relocatable (info)
&& !_bfd_elf_size_group_sections (info))
return FALSE;
 
5603,7 → 5733,7
 
for (inputobj = info->input_bfds;
inputobj;
inputobj = inputobj->link_next)
inputobj = inputobj->link.next)
{
asection *s;
 
5622,7 → 5752,7
}
if (notesec || info->stacksize > 0)
elf_stack_flags (output_bfd) = PF_R | PF_W | exec;
if (notesec && exec && info->relocatable
if (notesec && exec && bfd_link_relocatable (info)
&& notesec->output_section != bfd_abs_section_ptr)
notesec->output_section->flags |= SEC_CODE;
}
5640,7 → 5770,7
bfd_boolean all_defined;
 
*sinterpptr = bfd_get_linker_section (dynobj, ".interp");
BFD_ASSERT (*sinterpptr != NULL || !info->executable);
BFD_ASSERT (*sinterpptr != NULL || !bfd_link_executable (info) || info->nointerp);
 
if (soname != NULL)
{
5728,7 → 5858,7
/* 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
|| (info->executable && info->dynamic))
|| (bfd_link_executable (info) && info->dynamic))
{
elf_link_hash_traverse (elf_hash_table (info),
_bfd_elf_export_symbol,
5863,13 → 5993,13
if (s != NULL && s->linker_has_input)
{
/* DT_PREINIT_ARRAY is not allowed in shared library. */
if (! info->executable)
if (! bfd_link_executable (info))
{
bfd *sub;
asection *o;
 
for (sub = info->input_bfds; sub != NULL;
sub = sub->link_next)
sub = sub->link.next)
if (bfd_get_flavour (sub) == bfd_target_elf_flavour)
for (o = sub->sections; o != NULL; o = o->next)
if (elf_section_data (o)->this_hdr.sh_type
5927,6 → 6057,9
}
}
 
if (! _bfd_elf_maybe_strip_eh_frame_hdr (info))
return FALSE;
 
/* The backend must work out the sizes of all the other dynamic
sections. */
if (dynobj != NULL
5934,9 → 6067,6
&& ! (*bed->elf_backend_size_dynamic_sections) (output_bfd, info))
return FALSE;
 
if (! _bfd_elf_maybe_strip_eh_frame_hdr (info))
return FALSE;
 
if (dynobj != NULL && elf_hash_table (info)->dynamic_sections_created)
{
unsigned long section_sym_count;
6197,7 → 6327,7
 
if (info->flags_1)
{
if (info->executable)
if (bfd_link_executable (info))
info->flags_1 &= ~ (DF_1_INITFIRST
| DF_1_NODELETE
| DF_1_NOOPEN);
6423,7 → 6553,7
the final symbol table, because until then we do not know the
correct value to give the symbols. We built the .dynstr
section as we went along in elf_link_add_object_symbols. */
s = bfd_get_linker_section (dynobj, ".dynsym");
s = elf_hash_table (info)->dynsym;
BFD_ASSERT (s != NULL);
s->size = dynsymcount * bed->s->sizeof_sym;
 
6691,7 → 6821,7
/* Finish SHF_MERGE section merging. */
 
bfd_boolean
_bfd_elf_merge_sections (bfd *abfd, struct bfd_link_info *info)
_bfd_elf_merge_sections (bfd *obfd, struct bfd_link_info *info)
{
bfd *ibfd;
asection *sec;
6699,8 → 6829,11
if (!is_elf_hash_table (info->hash))
return FALSE;
 
for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
if ((ibfd->flags & DYNAMIC) == 0)
for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
if ((ibfd->flags & DYNAMIC) == 0
&& bfd_get_flavour (ibfd) == bfd_target_elf_flavour
&& (elf_elfheader (ibfd)->e_ident[EI_CLASS]
== get_elf_backend_data (obfd)->s->elfclass))
for (sec = ibfd->sections; sec != NULL; sec = sec->next)
if ((sec->flags & SEC_MERGE) != 0
&& !bfd_is_abs_section (sec->output_section))
6708,7 → 6841,7
struct bfd_elf_section_data *secdata;
 
secdata = elf_section_data (sec);
if (! _bfd_add_merge_section (abfd,
if (! _bfd_add_merge_section (obfd,
&elf_hash_table (info)->merge_info,
sec, &secdata->sec_info))
return FALSE;
6717,7 → 6850,7
}
 
if (elf_hash_table (info)->merge_info != NULL)
_bfd_merge_sections (abfd, info, elf_hash_table (info)->merge_info,
_bfd_merge_sections (obfd, info, elf_hash_table (info)->merge_info,
merge_sections_remove_hook);
return TRUE;
}
6774,8 → 6907,11
struct elf_link_hash_table *htab;
 
/* Copy down any references that we may have already seen to the
symbol which just became indirect. */
symbol which just became indirect if DIR isn't a hidden versioned
symbol. */
 
if (dir->versioned != versioned_hidden)
{
dir->ref_dynamic |= ind->ref_dynamic;
dir->ref_regular |= ind->ref_regular;
dir->ref_regular_nonweak |= ind->ref_regular_nonweak;
6782,6 → 6918,7
dir->non_got_ref |= ind->non_got_ref;
dir->needs_plt |= ind->needs_plt;
dir->pointer_equality_needed |= ind->pointer_equality_needed;
}
 
if (ind->root.type != bfd_link_hash_indirect)
return;
6889,6 → 7026,7
free (ret);
return NULL;
}
ret->root.hash_table_free = _bfd_elf_link_hash_table_free;
 
return &ret->root;
}
6896,13 → 7034,15
/* Destroy an ELF linker hash table. */
 
void
_bfd_elf_link_hash_table_free (struct bfd_link_hash_table *hash)
_bfd_elf_link_hash_table_free (bfd *obfd)
{
struct elf_link_hash_table *htab = (struct elf_link_hash_table *) hash;
struct elf_link_hash_table *htab;
 
htab = (struct elf_link_hash_table *) obfd->link.hash;
if (htab->dynstr != NULL)
_bfd_elf_strtab_free (htab->dynstr);
_bfd_merge_sections_free (htab->merge_info);
_bfd_generic_link_hash_table_free (hash);
_bfd_generic_link_hash_table_free (obfd);
}
 
/* This is a hook for the ELF emulation code in the generic linker to
7282,10 → 7422,10
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;
 
7411,9 → 7551,7
/* Output BFD. */
bfd *output_bfd;
/* Symbol string table. */
struct bfd_strtab_hash *symstrtab;
/* .dynsym section. */
asection *dynsym_sec;
struct elf_strtab_hash *symstrtab;
/* .hash section. */
asection *hash_sec;
/* symbol version section (.gnu.version). */
7438,16 → 7576,8
/* Array large enough to hold a section pointer for each local
symbol of any input BFD. */
asection **sections;
/* Buffer to hold swapped out symbols. */
bfd_byte *symbuf;
/* And one for symbol section indices. */
/* Buffer for SHT_SYMTAB_SHNDX section. */
Elf_External_Sym_Shndx *symshndxbuf;
/* Number of swapped out symbols in buffer. */
size_t symbuf_count;
/* Number of symbols which fit in symbuf. */
size_t symbuf_size;
/* And same for symshndxbuf. */
size_t shndxbuf_size;
/* Number of STT_FILE syms seen. */
size_t filesym_count;
};
7458,8 → 7588,7
{
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;
};
 
7809,28 → 7938,34
{
location += (size - chunksz);
 
for (; size; size -= chunksz, location -= chunksz, x >>= (chunksz * 8))
for (; size; size -= chunksz, location -= chunksz)
{
switch (chunksz)
{
default:
case 0:
abort ();
case 1:
bfd_put_8 (input_bfd, x, location);
x >>= 8;
break;
case 2:
bfd_put_16 (input_bfd, x, location);
x >>= 16;
break;
case 4:
bfd_put_32 (input_bfd, x, location);
/* Computed this way because x >>= 32 is undefined if x is a 32-bit value. */
x >>= 16;
x >>= 16;
break;
#ifdef BFD64
case 8:
#ifdef BFD64
bfd_put_64 (input_bfd, x, location);
#else
/* Computed this way because x >>= 64 is undefined if x is a 64-bit value. */
x >>= 32;
x >>= 32;
break;
#endif
default:
abort ();
#endif
break;
}
}
7977,14 → 8112,101
return r;
}
 
/* Functions to read r_offset from external (target order) reloc
entry. Faster than bfd_getl32 et al, because we let the compiler
know the value is aligned. */
 
static bfd_vma
ext32l_r_offset (const void *p)
{
union aligned32
{
uint32_t v;
unsigned char c[4];
};
const union aligned32 *a
= (const union aligned32 *) &((const Elf32_External_Rel *) p)->r_offset;
 
uint32_t aval = ( (uint32_t) a->c[0]
| (uint32_t) a->c[1] << 8
| (uint32_t) a->c[2] << 16
| (uint32_t) a->c[3] << 24);
return aval;
}
 
static bfd_vma
ext32b_r_offset (const void *p)
{
union aligned32
{
uint32_t v;
unsigned char c[4];
};
const union aligned32 *a
= (const union aligned32 *) &((const Elf32_External_Rel *) p)->r_offset;
 
uint32_t aval = ( (uint32_t) a->c[0] << 24
| (uint32_t) a->c[1] << 16
| (uint32_t) a->c[2] << 8
| (uint32_t) a->c[3]);
return aval;
}
 
#ifdef BFD_HOST_64_BIT
static bfd_vma
ext64l_r_offset (const void *p)
{
union aligned64
{
uint64_t v;
unsigned char c[8];
};
const union aligned64 *a
= (const union aligned64 *) &((const Elf64_External_Rel *) p)->r_offset;
 
uint64_t aval = ( (uint64_t) a->c[0]
| (uint64_t) a->c[1] << 8
| (uint64_t) a->c[2] << 16
| (uint64_t) a->c[3] << 24
| (uint64_t) a->c[4] << 32
| (uint64_t) a->c[5] << 40
| (uint64_t) a->c[6] << 48
| (uint64_t) a->c[7] << 56);
return aval;
}
 
static bfd_vma
ext64b_r_offset (const void *p)
{
union aligned64
{
uint64_t v;
unsigned char c[8];
};
const union aligned64 *a
= (const union aligned64 *) &((const Elf64_External_Rel *) p)->r_offset;
 
uint64_t aval = ( (uint64_t) a->c[0] << 56
| (uint64_t) a->c[1] << 48
| (uint64_t) a->c[2] << 40
| (uint64_t) a->c[3] << 32
| (uint64_t) a->c[4] << 24
| (uint64_t) a->c[5] << 16
| (uint64_t) a->c[6] << 8
| (uint64_t) a->c[7]);
return aval;
}
#endif
 
/* When performing a relocatable link, the input relocations are
preserved. But, if they reference global symbols, the indices
referenced must be updated. Update all the relocations found in
RELDATA. */
 
static void
static bfd_boolean
elf_link_adjust_relocs (bfd *abfd,
struct bfd_elf_section_reloc_data *reldata)
struct bfd_elf_section_reloc_data *reldata,
bfd_boolean sort)
{
unsigned int i;
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
8040,8 → 8262,120
| (irela[j].r_info & r_type_mask));
(*swap_out) (abfd, irela, erela);
}
 
if (sort && count != 0)
{
bfd_vma (*ext_r_off) (const void *);
bfd_vma r_off;
size_t elt_size;
bfd_byte *base, *end, *p, *loc;
bfd_byte *buf = NULL;
 
if (bed->s->arch_size == 32)
{
if (abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)
ext_r_off = ext32l_r_offset;
else if (abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
ext_r_off = ext32b_r_offset;
else
abort ();
}
else
{
#ifdef BFD_HOST_64_BIT
if (abfd->xvec->header_byteorder == BFD_ENDIAN_LITTLE)
ext_r_off = ext64l_r_offset;
else if (abfd->xvec->header_byteorder == BFD_ENDIAN_BIG)
ext_r_off = ext64b_r_offset;
else
#endif
abort ();
}
 
/* Must use a stable sort here. A modified insertion sort,
since the relocs are mostly sorted already. */
elt_size = reldata->hdr->sh_entsize;
base = reldata->hdr->contents;
end = base + count * elt_size;
if (elt_size > sizeof (Elf64_External_Rela))
abort ();
 
/* Ensure the first element is lowest. This acts as a sentinel,
speeding the main loop below. */
r_off = (*ext_r_off) (base);
for (p = loc = base; (p += elt_size) < end; )
{
bfd_vma r_off2 = (*ext_r_off) (p);
if (r_off > r_off2)
{
r_off = r_off2;
loc = p;
}
}
if (loc != base)
{
/* Don't just swap *base and *loc as that changes the order
of the original base[0] and base[1] if they happen to
have the same r_offset. */
bfd_byte onebuf[sizeof (Elf64_External_Rela)];
memcpy (onebuf, loc, elt_size);
memmove (base + elt_size, base, loc - base);
memcpy (base, onebuf, elt_size);
}
 
for (p = base + elt_size; (p += elt_size) < end; )
{
/* base to p is sorted, *p is next to insert. */
r_off = (*ext_r_off) (p);
/* Search the sorted region for location to insert. */
loc = p - elt_size;
while (r_off < (*ext_r_off) (loc))
loc -= elt_size;
loc += elt_size;
if (loc != p)
{
/* Chances are there is a run of relocs to insert here,
from one of more input files. Files are not always
linked in order due to the way elf_link_input_bfd is
called. See pr17666. */
size_t sortlen = p - loc;
bfd_vma r_off2 = (*ext_r_off) (loc);
size_t runlen = elt_size;
size_t buf_size = 96 * 1024;
while (p + runlen < end
&& (sortlen <= buf_size
|| runlen + elt_size <= buf_size)
&& r_off2 > (*ext_r_off) (p + runlen))
runlen += elt_size;
if (buf == NULL)
{
buf = bfd_malloc (buf_size);
if (buf == NULL)
return FALSE;
}
if (runlen < sortlen)
{
memcpy (buf, p, runlen);
memmove (loc + runlen, loc, sortlen);
memcpy (loc, buf, runlen);
}
else
{
memcpy (buf, loc, sortlen);
memmove (loc, p, runlen);
memcpy (loc + runlen, buf, sortlen);
}
p += runlen - elt_size;
}
}
/* Hashes are no longer valid. */
free (reldata->hashes);
reldata->hashes = NULL;
free (buf);
}
return TRUE;
}
 
struct elf_link_sort_rela
{
union {
8370,48 → 8704,24
return ret;
}
 
/* Flush the output symbols to the file. */
/* Add a symbol to the output symbol string table. */
 
static bfd_boolean
elf_link_flush_output_syms (struct elf_final_link_info *flinfo,
const struct elf_backend_data *bed)
{
if (flinfo->symbuf_count > 0)
{
Elf_Internal_Shdr *hdr;
file_ptr pos;
bfd_size_type amt;
 
hdr = &elf_tdata (flinfo->output_bfd)->symtab_hdr;
pos = hdr->sh_offset + hdr->sh_size;
amt = flinfo->symbuf_count * bed->s->sizeof_sym;
if (bfd_seek (flinfo->output_bfd, pos, SEEK_SET) != 0
|| bfd_bwrite (flinfo->symbuf, amt, flinfo->output_bfd) != amt)
return FALSE;
 
hdr->sh_size += amt;
flinfo->symbuf_count = 0;
}
 
return TRUE;
}
 
/* Add a symbol to the output symbol table. */
 
static int
elf_link_output_sym (struct elf_final_link_info *flinfo,
elf_link_output_symstrtab (struct elf_final_link_info *flinfo,
const char *name,
Elf_Internal_Sym *elfsym,
asection *input_sec,
struct elf_link_hash_entry *h)
{
bfd_byte *dest;
Elf_External_Sym_Shndx *destshndx;
int (*output_symbol_hook)
(struct bfd_link_info *, const char *, Elf_Internal_Sym *, asection *,
struct elf_link_hash_entry *);
struct elf_link_hash_table *hash_table;
const struct elf_backend_data *bed;
bfd_size_type strtabsize;
 
BFD_ASSERT (elf_onesymtab (flinfo->output_bfd));
 
bed = get_elf_backend_data (flinfo->output_bfd);
output_symbol_hook = bed->elf_backend_link_output_symbol_hook;
if (output_symbol_hook != NULL)
8421,49 → 8731,119
return ret;
}
 
if (name == NULL || *name == '\0')
elfsym->st_name = 0;
else if (input_sec->flags & SEC_EXCLUDE)
elfsym->st_name = 0;
if (name == NULL
|| *name == '\0'
|| (input_sec->flags & SEC_EXCLUDE))
elfsym->st_name = (unsigned long) -1;
else
{
elfsym->st_name = (unsigned long) _bfd_stringtab_add (flinfo->symstrtab,
name, TRUE, FALSE);
/* Call _bfd_elf_strtab_offset after _bfd_elf_strtab_finalize
to get the final offset for st_name. */
elfsym->st_name
= (unsigned long) _bfd_elf_strtab_add (flinfo->symstrtab,
name, FALSE);
if (elfsym->st_name == (unsigned long) -1)
return 0;
}
 
if (flinfo->symbuf_count >= flinfo->symbuf_size)
hash_table = elf_hash_table (flinfo->info);
strtabsize = hash_table->strtabsize;
if (strtabsize <= hash_table->strtabcount)
{
if (! elf_link_flush_output_syms (flinfo, bed))
strtabsize += strtabsize;
hash_table->strtabsize = strtabsize;
strtabsize *= sizeof (*hash_table->strtab);
hash_table->strtab
= (struct elf_sym_strtab *) bfd_realloc (hash_table->strtab,
strtabsize);
if (hash_table->strtab == NULL)
return 0;
}
hash_table->strtab[hash_table->strtabcount].sym = *elfsym;
hash_table->strtab[hash_table->strtabcount].dest_index
= hash_table->strtabcount;
hash_table->strtab[hash_table->strtabcount].destshndx_index
= flinfo->symshndxbuf ? bfd_get_symcount (flinfo->output_bfd) : 0;
 
dest = flinfo->symbuf + flinfo->symbuf_count * bed->s->sizeof_sym;
destshndx = flinfo->symshndxbuf;
if (destshndx != NULL)
bfd_get_symcount (flinfo->output_bfd) += 1;
hash_table->strtabcount += 1;
 
return 1;
}
 
/* Swap symbols out to the symbol table and flush the output symbols to
the file. */
 
static bfd_boolean
elf_link_swap_symbols_out (struct elf_final_link_info *flinfo)
{
if (bfd_get_symcount (flinfo->output_bfd) >= flinfo->shndxbuf_size)
struct elf_link_hash_table *hash_table = elf_hash_table (flinfo->info);
bfd_size_type amt, i;
const struct elf_backend_data *bed;
bfd_byte *symbuf;
Elf_Internal_Shdr *hdr;
file_ptr pos;
bfd_boolean ret;
 
if (!hash_table->strtabcount)
return TRUE;
 
BFD_ASSERT (elf_onesymtab (flinfo->output_bfd));
 
bed = get_elf_backend_data (flinfo->output_bfd);
 
amt = bed->s->sizeof_sym * hash_table->strtabcount;
symbuf = (bfd_byte *) bfd_malloc (amt);
if (symbuf == NULL)
return FALSE;
 
if (flinfo->symshndxbuf)
{
bfd_size_type amt;
amt = (sizeof (Elf_External_Sym_Shndx)
* (bfd_get_symcount (flinfo->output_bfd)));
flinfo->symshndxbuf = (Elf_External_Sym_Shndx *) bfd_zmalloc (amt);
if (flinfo->symshndxbuf == NULL)
{
free (symbuf);
return FALSE;
}
}
 
amt = flinfo->shndxbuf_size * sizeof (Elf_External_Sym_Shndx);
destshndx = (Elf_External_Sym_Shndx *) bfd_realloc (destshndx,
amt * 2);
if (destshndx == NULL)
return 0;
flinfo->symshndxbuf = destshndx;
memset ((char *) destshndx + amt, 0, amt);
flinfo->shndxbuf_size *= 2;
for (i = 0; i < hash_table->strtabcount; i++)
{
struct elf_sym_strtab *elfsym = &hash_table->strtab[i];
if (elfsym->sym.st_name == (unsigned long) -1)
elfsym->sym.st_name = 0;
else
elfsym->sym.st_name
= (unsigned long) _bfd_elf_strtab_offset (flinfo->symstrtab,
elfsym->sym.st_name);
bed->s->swap_symbol_out (flinfo->output_bfd, &elfsym->sym,
((bfd_byte *) symbuf
+ (elfsym->dest_index
* bed->s->sizeof_sym)),
(flinfo->symshndxbuf
+ elfsym->destshndx_index));
}
destshndx += bfd_get_symcount (flinfo->output_bfd);
 
hdr = &elf_tdata (flinfo->output_bfd)->symtab_hdr;
pos = hdr->sh_offset + hdr->sh_size;
amt = hash_table->strtabcount * bed->s->sizeof_sym;
if (bfd_seek (flinfo->output_bfd, pos, SEEK_SET) == 0
&& bfd_bwrite (symbuf, amt, flinfo->output_bfd) == amt)
{
hdr->sh_size += amt;
ret = TRUE;
}
else
ret = FALSE;
 
bed->s->swap_symbol_out (flinfo->output_bfd, elfsym, dest, destshndx);
flinfo->symbuf_count += 1;
bfd_get_symcount (flinfo->output_bfd) += 1;
free (symbuf);
 
return 1;
free (hash_table->strtab);
hash_table->strtab = NULL;
 
return ret;
}
 
/* Return TRUE if the dynamic symbol SYM in ABFD is supported. */
8660,6 → 9040,16
const struct elf_backend_data *bed;
long indx;
int ret;
/* A symbol is bound locally if it is forced local or it is locally
defined, hidden versioned, not referenced by shared library and
not exported when linking executable. */
bfd_boolean local_bind = (h->forced_local
|| (bfd_link_executable (flinfo->info)
&& !flinfo->info->export_dynamic
&& !h->dynamic
&& !h->ref_dynamic
&& h->def_regular
&& h->versioned == versioned_hidden));
 
if (h->root.type == bfd_link_hash_warning)
{
8671,17 → 9061,12
/* Decide whether to output this symbol in this pass. */
if (eoinfo->localsyms)
{
if (!h->forced_local)
if (!local_bind)
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;
}
else
{
if (h->forced_local)
if (local_bind)
return TRUE;
}
 
8724,8 → 9109,7
 
/* We should also warn if a forced local symbol is referenced from
shared libraries. */
if (!flinfo->info->relocatable
&& flinfo->info->executable
if (bfd_link_executable (flinfo->info)
&& h->forced_local
&& h->ref_dynamic
&& h->def_regular
8779,7 → 9163,8
|| 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
8802,7 → 9187,7
sym.st_value = 0;
sym.st_size = h->size;
sym.st_other = h->other;
if (h->forced_local)
if (local_bind)
{
sym.st_info = ELF_ST_INFO (STB_LOCAL, h->type);
/* Turn off visibility on local symbol. */
8838,19 → 9223,6
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);
8868,7 → 9240,7
but in nonrelocatable files they are virtual
addresses. */
sym.st_value = h->root.u.def.value + input_sec->output_offset;
if (!flinfo->info->relocatable)
if (!bfd_link_relocatable (flinfo->info))
{
sym.st_value += input_sec->output_section->vma;
if (h->type == STT_TLS)
8876,15 → 9248,9
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);
}
}
}
}
else
{
BFD_ASSERT (input_sec->owner == NULL
8918,10 → 9284,10
STT_GNU_IFUNC symbol must go through PLT. */
if ((h->type == STT_GNU_IFUNC
&& h->def_regular
&& !flinfo->info->relocatable)
&& !bfd_link_relocatable (flinfo->info))
|| ((h->dynindx != -1
|| h->forced_local)
&& ((flinfo->info->shared
&& ((bfd_link_pic (flinfo->info)
&& (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|| h->root.type != bfd_link_hash_undefweak))
|| !h->forced_local)
8971,7 → 9337,7
 
/* If a non-weak symbol with non-default visibility is not defined
locally, it is a fatal error. */
if (!flinfo->info->relocatable
if (!bfd_link_relocatable (flinfo->info)
&& ELF_ST_VISIBILITY (sym.st_other) != STV_DEFAULT
&& ELF_ST_BIND (sym.st_info) != STB_WEAK
&& h->root.type == bfd_link_hash_undefined
8994,7 → 9360,7
/* If this symbol should be put in the .dynsym section, then put it
there now. We already know the symbol index. We also fill in
the entry in the .hash section. */
if (flinfo->dynsym_sec != NULL
if (elf_hash_table (flinfo->info)->dynsym != NULL
&& h->dynindx != -1
&& elf_hash_table (flinfo->info)->dynamic_sections_created)
{
9002,8 → 9368,14
 
/* Since there is no version information in the dynamic string,
if there is no version info in symbol version section, we will
have a run-time problem. */
if (h->verinfo.verdef == NULL)
have a run-time problem if not linking executable, referenced
by shared library, not locally defined, or not bound locally.
*/
if (h->verinfo.verdef == NULL
&& !local_bind
&& (!bfd_link_executable (flinfo->info)
|| h->ref_dynamic
|| !h->def_regular))
{
char *p = strrchr (h->root.root.string, ELF_VER_CHR);
 
9018,7 → 9390,8
}
 
sym.st_name = h->dynstr_index;
esym = flinfo->dynsym_sec->contents + h->dynindx * bed->s->sizeof_sym;
esym = (elf_hash_table (flinfo->info)->dynsym->contents
+ h->dynindx * bed->s->sizeof_sym);
if (!check_dynsym (flinfo->output_bfd, &sym))
{
eoinfo->failed = TRUE;
9056,7 → 9429,9
 
if (!h->def_regular)
{
if (h->verinfo.verdef == NULL)
if (h->verinfo.verdef == NULL
|| (elf_dyn_lib_class (h->verinfo.verdef->vd_bfd)
& (DYN_AS_NEEDED | DYN_DT_NEEDED | DYN_NO_NEEDED)))
iversym.vs_vers = 0;
else
iversym.vs_vers = h->verinfo.verdef->vd_exp_refno + 1;
9071,7 → 9446,9
iversym.vs_vers++;
}
 
if (h->hidden)
/* Turn on VERSYM_HIDDEN only if the hidden versioned symbol is
defined locally. */
if (h->versioned == versioned_hidden && h->def_regular)
iversym.vs_vers |= VERSYM_HIDDEN;
 
eversym = (Elf_External_Versym *) flinfo->symver_sec->contents;
9085,8 → 9462,32
if (strip || (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_symstrtab (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);
ret = elf_link_output_symstrtab (flinfo, h->root.root.string, &sym,
input_sec, h);
if (ret == 0)
{
eoinfo->failed = TRUE;
9112,6 → 9513,7
{
case SEC_INFO_TYPE_STABS:
case SEC_INFO_TYPE_EH_FRAME:
case SEC_INFO_TYPE_EH_FRAME_ENTRY:
return TRUE;
default:
break;
9351,7 → 9753,8
&& (bfd_hash_lookup (flinfo->info->keep_hash, name, FALSE, FALSE)
== NULL))
|| (((flinfo->info->discard == discard_sec_merge
&& (isec->flags & SEC_MERGE) && !flinfo->info->relocatable)
&& (isec->flags & SEC_MERGE)
&& !bfd_link_relocatable (flinfo->info))
|| flinfo->info->discard == discard_l)
&& bfd_is_local_label_name (input_bfd, name)))
continue;
9358,6 → 9761,10
 
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;
}
9374,8 → 9781,11
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_symstrtab (flinfo,
(input_bfd->lto_output ? NULL
: input_bfd->filename),
&osym, bfd_abs_section_ptr,
NULL))
return FALSE;
}
 
9395,7 → 9805,7
output_section. Any special sections must be set up to meet
these requirements. */
osym.st_value += isec->output_offset;
if (!flinfo->info->relocatable)
if (!bfd_link_relocatable (flinfo->info))
{
osym.st_value += isec->output_section->vma;
if (ELF_ST_TYPE (osym.st_info) == STT_TLS)
9407,7 → 9817,7
}
 
indx = bfd_get_symcount (output_bfd);
ret = elf_link_output_sym (flinfo, name, &osym, isec, NULL);
ret = elf_link_output_symstrtab (flinfo, name, &osym, isec, NULL);
if (ret == 0)
return FALSE;
else if (ret == 1)
9439,7 → 9849,7
continue;
}
 
if (flinfo->info->relocatable
if (bfd_link_relocatable (flinfo->info)
&& (o->flags & (SEC_LINKER_CREATED | SEC_GROUP)) == SEC_GROUP)
{
/* Deal with the group signature symbol. */
9490,7 → 9900,8
sym.st_value += o->output_offset;
 
indx = bfd_get_symcount (output_bfd);
ret = elf_link_output_sym (flinfo, name, &sym, o, NULL);
ret = elf_link_output_symstrtab (flinfo, name, &sym, o,
NULL);
if (ret == 0)
return FALSE;
else if (ret == 1)
9519,7 → 9930,16
file, so the contents field will not have been set by any of
the routines which work on output files. */
if (elf_section_data (o)->this_hdr.contents != NULL)
{
contents = elf_section_data (o)->this_hdr.contents;
if (bed->caches_rawsize
&& o->rawsize != 0
&& o->rawsize < o->size)
{
memcpy (flinfo->contents, contents, o->rawsize);
contents = flinfo->contents;
}
}
else
{
contents = flinfo->contents;
9616,6 → 10036,24
 
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)
9634,7 → 10072,7
}
 
if ((s_type == STT_RELC || s_type == STT_SRELC)
&& !flinfo->info->relocatable)
&& !bfd_link_relocatable (flinfo->info))
{
bfd_vma val;
bfd_vma dot = (rel->r_offset
9724,7 → 10162,7
return FALSE;
 
if (ret == 2
|| flinfo->info->relocatable
|| bfd_link_relocatable (flinfo->info)
|| flinfo->info->emitrelocations)
{
Elf_Internal_Rela *irela;
9755,7 → 10193,7
rel_hash_list = rel_hash;
rela_hash_list = NULL;
last_offset = o->output_offset;
if (!flinfo->info->relocatable)
if (!bfd_link_relocatable (flinfo->info))
last_offset += o->output_section->vma;
for (next_erel = 0; irela < irelaend; irela++, next_erel++)
{
9795,7 → 10233,7
irela->r_offset += o->output_offset;
 
/* Relocs in an executable have to be virtual addresses. */
if (!flinfo->info->relocatable)
if (!bfd_link_relocatable (flinfo->info))
irela->r_offset += o->output_section->vma;
 
last_offset = irela->r_offset;
9923,7 → 10361,7
return FALSE;
 
sym.st_value += sec->output_offset;
if (!flinfo->info->relocatable)
if (!bfd_link_relocatable (flinfo->info))
{
sym.st_value += osec->vma;
if (ELF_ST_TYPE (sym.st_info) == STT_TLS)
9938,7 → 10376,8
}
 
indx = bfd_get_symcount (output_bfd);
ret = elf_link_output_sym (flinfo, name, &sym, sec,
ret = elf_link_output_symstrtab (flinfo, name,
&sym, sec,
NULL);
if (ret == 0)
return FALSE;
10009,6 → 10448,14
return FALSE;
}
break;
case SEC_INFO_TYPE_EH_FRAME_ENTRY:
{
if (! _bfd_elf_write_section_eh_frame_entry (output_bfd,
flinfo->info,
o, contents))
return FALSE;
}
break;
default:
{
/* FIXME: octets_per_byte. */
10152,7 → 10599,7
 
size = (bfd_size_type) bfd_get_reloc_size (howto);
buf = (bfd_byte *) bfd_zmalloc (size);
if (buf == NULL)
if (buf == NULL && size != 0)
return FALSE;
rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf);
switch (rstat)
10190,7 → 10637,7
relocatable file, and is a virtual address in an executable
file. */
offset = link_order->offset;
if (! info->relocatable)
if (! bfd_link_relocatable (info))
offset += output_section->vma;
 
for (i = 0; i < bed->s->int_rels_per_ext_rel; i++)
10378,7 → 10825,7
asection *o;
 
if (flinfo->symstrtab != NULL)
_bfd_stringtab_free (flinfo->symstrtab);
_bfd_elf_strtab_free (flinfo->symstrtab);
if (flinfo->contents != NULL)
free (flinfo->contents);
if (flinfo->external_relocs != NULL)
10395,8 → 10842,6
free (flinfo->indices);
if (flinfo->sections != NULL)
free (flinfo->sections);
if (flinfo->symbuf != NULL)
free (flinfo->symbuf);
if (flinfo->symshndxbuf != NULL)
free (flinfo->symshndxbuf);
for (o = obfd->sections; o != NULL; o = o->next)
10426,12 → 10871,10
bfd_size_type max_internal_reloc_count;
bfd_size_type max_sym_count;
bfd_size_type max_sym_shndx_count;
file_ptr off;
Elf_Internal_Sym elfsym;
unsigned int i;
Elf_Internal_Shdr *symtab_hdr;
Elf_Internal_Shdr *symtab_shndx_hdr;
Elf_Internal_Shdr *symstrtab_hdr;
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
struct elf_outext_info eoinfo;
bfd_boolean merged;
10445,30 → 10888,28
if (! is_elf_hash_table (info->hash))
return FALSE;
 
if (info->shared)
if (bfd_link_pic (info))
abfd->flags |= DYNAMIC;
 
dynamic = elf_hash_table (info)->dynamic_sections_created;
dynobj = elf_hash_table (info)->dynobj;
 
emit_relocs = (info->relocatable
emit_relocs = (bfd_link_relocatable (info)
|| info->emitrelocations);
 
flinfo.info = info;
flinfo.output_bfd = abfd;
flinfo.symstrtab = _bfd_elf_stringtab_init ();
flinfo.symstrtab = _bfd_elf_strtab_init ();
if (flinfo.symstrtab == NULL)
return FALSE;
 
if (! dynamic)
{
flinfo.dynsym_sec = NULL;
flinfo.hash_sec = NULL;
flinfo.symver_sec = NULL;
}
else
{
flinfo.dynsym_sec = bfd_get_linker_section (dynobj, ".dynsym");
flinfo.hash_sec = bfd_get_linker_section (dynobj, ".hash");
/* Note that dynsym_sec can be NULL (on VMS). */
flinfo.symver_sec = bfd_get_linker_section (dynobj, ".gnu.version");
10483,10 → 10924,7
flinfo.internal_syms = NULL;
flinfo.indices = NULL;
flinfo.sections = NULL;
flinfo.symbuf = NULL;
flinfo.symshndxbuf = NULL;
flinfo.symbuf_count = 0;
flinfo.shndxbuf_size = 0;
flinfo.filesym_count = 0;
 
/* The object attributes have been merged. Remove the input
10567,7 → 11005,7
to count particular types of relocs. Of course,
reloc sections themselves can't have relocations. */
reloc_count = 0;
else if (info->relocatable || info->emitrelocations)
else if (emit_relocs)
reloc_count = sec->reloc_count;
else if (bed->elf_backend_count_relocs)
reloc_count = (*bed->elf_backend_count_relocs) (info, sec);
10594,7 → 11032,7
max_sym_count = sym_count;
 
if (sym_count > max_sym_shndx_count
&& elf_symtab_shndx (sec->owner) != 0)
&& elf_symtab_shndx_list (sec->owner) != NULL)
max_sym_shndx_count = sym_count;
 
if ((sec->flags & SEC_RELOC) != 0)
10619,8 → 11057,7
 
o->reloc_count += reloc_count;
 
if (p->type == bfd_indirect_link_order
&& (info->relocatable || info->emitrelocations))
if (p->type == bfd_indirect_link_order && emit_relocs)
{
if (esdi->rel.hdr)
esdo->rel.count += NUM_SHDR_ENTRIES (esdi->rel.hdr);
10655,7 → 11092,7
o->vma = 0;
}
 
if (! info->relocatable && merged)
if (! bfd_link_relocatable (info) && merged)
elf_link_hash_traverse (elf_hash_table (info),
_bfd_elf_link_sec_merge_syms, abfd);
 
10662,7 → 11099,7
/* Figure out the file positions for everything but the symbol table
and the relocs. We set symcount to force assign_section_numbers
to create a symbol table. */
bfd_get_symcount (abfd) = info->strip == strip_all ? 0 : 1;
bfd_get_symcount (abfd) = info->strip != strip_all || emit_relocs;
BFD_ASSERT (! abfd->output_has_begun);
if (! _bfd_elf_compute_section_file_positions (abfd, info))
goto error_return;
10686,14 → 11123,27
to count upwards while actually outputting the relocations. */
esdo->rel.count = 0;
esdo->rela.count = 0;
 
if (esdo->this_hdr.sh_offset == (file_ptr) -1)
{
/* Cache the section contents so that they can be compressed
later. Use bfd_malloc since it will be freed by
bfd_compress_section_contents. */
unsigned char *contents = esdo->this_hdr.contents;
if ((o->flags & SEC_ELF_COMPRESS) == 0 || contents != NULL)
abort ();
contents
= (unsigned char *) bfd_malloc (esdo->this_hdr.sh_size);
if (contents == NULL)
goto error_return;
esdo->this_hdr.contents = contents;
}
}
 
_bfd_elf_assign_file_positions_for_relocs (abfd);
 
/* We have now assigned file positions for all the sections except
.symtab and .strtab. We start the .symtab section at the current
file position, and write directly to it. We build the .strtab
section in memory. */
.symtab, .strtab, and non-loaded reloc sections. We start the
.symtab section at the current file position, and write directly
to it. We build the .strtab section in memory. */
bfd_get_symcount (abfd) = 0;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
/* sh_name is set in prep_headers. */
10705,40 → 11155,31
/* sh_offset is set just below. */
symtab_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align;
 
off = elf_next_file_pos (abfd);
off = _bfd_elf_assign_file_position_for_section (symtab_hdr, off, TRUE);
if (max_sym_count < 20)
max_sym_count = 20;
elf_hash_table (info)->strtabsize = max_sym_count;
amt = max_sym_count * sizeof (struct elf_sym_strtab);
elf_hash_table (info)->strtab
= (struct elf_sym_strtab *) bfd_malloc (amt);
if (elf_hash_table (info)->strtab == NULL)
goto error_return;
/* The real buffer will be allocated in elf_link_swap_symbols_out. */
flinfo.symshndxbuf
= (elf_numsections (abfd) > (SHN_LORESERVE & 0xFFFF)
? (Elf_External_Sym_Shndx *) -1 : NULL);
 
if (info->strip != strip_all || emit_relocs)
{
file_ptr off = elf_next_file_pos (abfd);
 
_bfd_elf_assign_file_position_for_section (symtab_hdr, off, TRUE);
 
/* Note that at this point elf_next_file_pos (abfd) is
incorrect. We do not yet know the size of the .symtab section.
We correct next_file_pos below, after we do know the size. */
 
/* Allocate a buffer to hold swapped out symbols. This is to avoid
continuously seeking to the right position in the file. */
if (! info->keep_memory || max_sym_count < 20)
flinfo.symbuf_size = 20;
else
flinfo.symbuf_size = max_sym_count;
amt = flinfo.symbuf_size;
amt *= bed->s->sizeof_sym;
flinfo.symbuf = (bfd_byte *) bfd_malloc (amt);
if (flinfo.symbuf == NULL)
goto error_return;
if (elf_numsections (abfd) > (SHN_LORESERVE & 0xFFFF))
{
/* Wild guess at number of output symbols. realloc'd as needed. */
amt = 2 * max_sym_count + elf_numsections (abfd) + 1000;
flinfo.shndxbuf_size = amt;
amt *= sizeof (Elf_External_Sym_Shndx);
flinfo.symshndxbuf = (Elf_External_Sym_Shndx *) bfd_zmalloc (amt);
if (flinfo.symshndxbuf == NULL)
goto error_return;
}
 
/* Start writing out the symbol table. The first symbol is always a
dummy symbol. */
if (info->strip != strip_all
|| emit_relocs)
{
elfsym.st_value = 0;
elfsym.st_size = 0;
elfsym.st_info = 0;
10745,10 → 11186,9
elfsym.st_other = 0;
elfsym.st_shndx = SHN_UNDEF;
elfsym.st_target_internal = 0;
if (elf_link_output_sym (&flinfo, NULL, &elfsym, bfd_und_section_ptr,
NULL) != 1)
if (elf_link_output_symstrtab (&flinfo, NULL, &elfsym,
bfd_und_section_ptr, NULL) != 1)
goto error_return;
}
 
/* Output a symbol for each section. We output these even if we are
discarding local symbols, since they are used for relocs. These
10755,9 → 11195,7
symbols have no names. We store the index of each one in the
index field of the section, so that we can find it again when
outputting relocs. */
if (info->strip != strip_all
|| emit_relocs)
{
 
elfsym.st_size = 0;
elfsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
elfsym.st_other = 0;
10770,9 → 11208,10
{
o->target_index = bfd_get_symcount (abfd);
elfsym.st_shndx = i;
if (!info->relocatable)
if (!bfd_link_relocatable (info))
elfsym.st_value = o->vma;
if (elf_link_output_sym (&flinfo, NULL, &elfsym, o, NULL) != 1)
if (elf_link_output_symstrtab (&flinfo, NULL, &elfsym, o,
NULL) != 1)
goto error_return;
}
}
10871,6 → 11310,9
return FALSE;
}
 
if (!_bfd_elf_fixup_eh_frame_hdr (info))
return FALSE;
 
/* Since ELF permits relocations to be against local symbols, we
must have the local symbols available when we do the relocations.
Since we would rather only read the local symbols once, and we
10891,7 → 11333,7
we could write the relocs out and then read them again; I don't
know how bad the memory loss will be. */
 
for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
sub->output_has_begun = FALSE;
for (o = abfd->sections; o != NULL; o = o->next)
{
10953,7 → 11395,7
/* Free symbol buffer if needed. */
if (!info->reduce_memory_overheads)
{
for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
if (bfd_get_flavour (sub) == bfd_target_elf_flavour
&& elf_tdata (sub)->symbuf)
{
10962,17 → 11404,6
}
}
 
/* Output a FILE symbol so that following locals are not associated
with the wrong input file. */
memset (&elfsym, 0, sizeof (elfsym));
elfsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE);
elfsym.st_shndx = SHN_ABS;
 
if (flinfo.filesym_count > 1
&& !elf_link_output_sym (&flinfo, NULL, &elfsym,
bfd_und_section_ptr, NULL))
return FALSE;
 
/* Output any global symbols that got converted to local in a
version script or due to symbol visibility. We do this in a
separate step since ELF requires all local symbols to appear
10982,28 → 11413,15
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 (flinfo.filesym_count == 1
&& !elf_link_output_sym (&flinfo, NULL, &elfsym,
bfd_und_section_ptr, NULL))
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 (bed->elf_backend_output_arch_local_syms
&& (info->strip != strip_all || emit_relocs))
{
typedef int (*out_sym_func)
(void *, const char *, Elf_Internal_Sym *, asection *,
11010,7 → 11428,8
struct elf_link_hash_entry *);
 
if (! ((*bed->elf_backend_output_arch_local_syms)
(abfd, info, &flinfo, (out_sym_func) elf_link_output_sym)))
(abfd, info, &flinfo,
(out_sym_func) elf_link_output_symstrtab)))
return FALSE;
}
 
11023,15 → 11442,17
symtab_hdr->sh_info = bfd_get_symcount (abfd);
 
if (dynamic
&& flinfo.dynsym_sec != NULL
&& flinfo.dynsym_sec->output_section != bfd_abs_section_ptr)
&& elf_hash_table (info)->dynsym != NULL
&& (elf_hash_table (info)->dynsym->output_section
!= bfd_abs_section_ptr))
{
Elf_Internal_Sym sym;
bfd_byte *dynsym = flinfo.dynsym_sec->contents;
bfd_byte *dynsym = elf_hash_table (info)->dynsym->contents;
long last_local = 0;
 
/* Write out the section symbols for the output sections. */
if (info->shared || elf_hash_table (info)->is_relocatable_executable)
if (bfd_link_pic (info)
|| elf_hash_table (info)->is_relocatable_executable)
{
asection *s;
 
11099,7 → 11520,7
}
}
 
elf_section_data (flinfo.dynsym_sec->output_section)->this_hdr.sh_info =
elf_section_data (elf_hash_table (info)->dynsym->output_section)->this_hdr.sh_info =
last_local + 1;
}
 
11113,7 → 11534,8
 
/* If backend needs to output some symbols not present in the hash
table, do it now. */
if (bed->elf_backend_output_arch_syms)
if (bed->elf_backend_output_arch_syms
&& (info->strip != strip_all || emit_relocs))
{
typedef int (*out_sym_func)
(void *, const char *, Elf_Internal_Sym *, asection *,
11120,19 → 11542,28
struct elf_link_hash_entry *);
 
if (! ((*bed->elf_backend_output_arch_syms)
(abfd, info, &flinfo, (out_sym_func) elf_link_output_sym)))
(abfd, info, &flinfo,
(out_sym_func) elf_link_output_symstrtab)))
return FALSE;
}
 
/* Flush all symbols to the file. */
if (! elf_link_flush_output_syms (&flinfo, bed))
/* Finalize the .strtab section. */
_bfd_elf_strtab_finalize (flinfo.symstrtab);
 
/* Swap out the .strtab section. */
if (!elf_link_swap_symbols_out (&flinfo))
return FALSE;
 
/* Now we know the size of the symtab section. */
off += symtab_hdr->sh_size;
if (bfd_get_symcount (abfd) > 0)
{
/* Finish up and write out the symbol string table (.strtab)
section. */
Elf_Internal_Shdr *symstrtab_hdr;
file_ptr off = symtab_hdr->sh_offset + symtab_hdr->sh_size;
 
symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
if (symtab_shndx_hdr->sh_name != 0)
symtab_shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr;
if (symtab_shndx_hdr != NULL && symtab_shndx_hdr->sh_name != 0)
{
symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX;
symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx);
11148,15 → 11579,12
return FALSE;
}
 
 
/* Finish up and write out the symbol string table (.strtab)
section. */
symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
/* sh_name was set in prep_headers. */
symstrtab_hdr->sh_type = SHT_STRTAB;
symstrtab_hdr->sh_flags = 0;
symstrtab_hdr->sh_addr = 0;
symstrtab_hdr->sh_size = _bfd_stringtab_size (flinfo.symstrtab);
symstrtab_hdr->sh_size = _bfd_elf_strtab_size (flinfo.symstrtab);
symstrtab_hdr->sh_entsize = 0;
symstrtab_hdr->sh_link = 0;
symstrtab_hdr->sh_info = 0;
11163,13 → 11591,12
/* sh_offset is set just below. */
symstrtab_hdr->sh_addralign = 1;
 
off = _bfd_elf_assign_file_position_for_section (symstrtab_hdr, off, TRUE);
off = _bfd_elf_assign_file_position_for_section (symstrtab_hdr,
off, TRUE);
elf_next_file_pos (abfd) = off;
 
if (bfd_get_symcount (abfd) > 0)
{
if (bfd_seek (abfd, symstrtab_hdr->sh_offset, SEEK_SET) != 0
|| ! _bfd_stringtab_emit (abfd, flinfo.symstrtab))
|| ! _bfd_elf_strtab_emit (abfd, flinfo.symstrtab))
return FALSE;
}
 
11177,13 → 11604,17
for (o = abfd->sections; o != NULL; o = o->next)
{
struct bfd_elf_section_data *esdo = elf_section_data (o);
bfd_boolean sort;
if ((o->flags & SEC_RELOC) == 0)
continue;
 
if (esdo->rel.hdr != NULL)
elf_link_adjust_relocs (abfd, &esdo->rel);
if (esdo->rela.hdr != NULL)
elf_link_adjust_relocs (abfd, &esdo->rela);
sort = bed->sort_relocs_p == NULL || (*bed->sort_relocs_p) (o);
if (esdo->rel.hdr != NULL
&& !elf_link_adjust_relocs (abfd, &esdo->rel, sort))
return FALSE;
if (esdo->rela.hdr != NULL
&& !elf_link_adjust_relocs (abfd, &esdo->rela, sort))
return FALSE;
 
/* Set the reloc_count field to 0 to prevent write_relocs from
trying to swap the relocs out itself. */
11374,7 → 11805,7
goto error_return;
 
/* Check for DT_TEXTREL (late, in case the backend removes it). */
if (((info->warn_shared_textrel && info->shared)
if (((info->warn_shared_textrel && bfd_link_pic (info))
|| info->error_textrel)
&& (o = bfd_get_linker_section (dynobj, ".dynamic")) != NULL)
{
11430,6 → 11861,8
{
/* The contents of the .dynstr section are actually in a
stringtab. */
file_ptr off;
 
off = elf_section_data (o->output_section)->this_hdr.sh_offset;
if (bfd_seek (abfd, off, SEEK_SET) != 0
|| ! _bfd_elf_strtab_emit (abfd,
11439,7 → 11872,7
}
}
 
if (info->relocatable)
if (bfd_link_relocatable (info))
{
bfd_boolean failed = FALSE;
 
11623,8 → 12056,6
struct elf_link_hash_entry *h,
Elf_Internal_Sym *sym)
{
const char *sec_name;
 
if (h != NULL)
{
switch (h->root.type)
11636,33 → 12067,6
case bfd_link_hash_common:
return h->root.u.c.p->section;
 
case bfd_link_hash_undefined:
case bfd_link_hash_undefweak:
/* To work around a glibc bug, keep all XXX input sections
when there is an as yet undefined reference to __start_XXX
or __stop_XXX symbols. The linker will later define such
symbols for orphan input sections that have a name
representable as a C identifier. */
if (strncmp (h->root.root.string, "__start_", 8) == 0)
sec_name = h->root.root.string + 8;
else if (strncmp (h->root.root.string, "__stop_", 7) == 0)
sec_name = h->root.root.string + 7;
else
sec_name = NULL;
 
if (sec_name && *sec_name != '\0')
{
bfd *i;
 
for (i = info->input_bfds; i; i = i->link_next)
{
sec = bfd_get_section_by_name (i, sec_name);
if (sec)
sec->flags |= SEC_KEEP;
}
}
break;
 
default:
break;
}
11680,7 → 12084,8
asection *
_bfd_elf_gc_mark_rsec (struct bfd_link_info *info, asection *sec,
elf_gc_mark_hook_fn gc_mark_hook,
struct elf_reloc_cookie *cookie)
struct elf_reloc_cookie *cookie,
bfd_boolean *start_stop)
{
unsigned long r_symndx;
struct elf_link_hash_entry *h;
11693,6 → 12098,12
|| ELF_ST_BIND (cookie->locsyms[r_symndx].st_info) != STB_LOCAL)
{
h = cookie->sym_hashes[r_symndx - cookie->extsymoff];
if (h == NULL)
{
info->callbacks->einfo (_("%F%P: corrupt input: %B\n"),
sec->owner);
return NULL;
}
while (h->root.type == bfd_link_hash_indirect
|| h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
11703,6 → 12114,38
handling copy relocs. */
if (h->u.weakdef != NULL)
h->u.weakdef->mark = 1;
 
if (start_stop != NULL
&& (h->root.type == bfd_link_hash_undefined
|| h->root.type == bfd_link_hash_undefweak))
{
/* To work around a glibc bug, mark all XXX input sections
when there is an as yet undefined reference to __start_XXX
or __stop_XXX symbols. The linker will later define such
symbols for orphan input sections that have a name
representable as a C identifier. */
const char *sec_name = NULL;
if (strncmp (h->root.root.string, "__start_", 8) == 0)
sec_name = h->root.root.string + 8;
else if (strncmp (h->root.root.string, "__stop_", 7) == 0)
sec_name = h->root.root.string + 7;
 
if (sec_name != NULL && *sec_name != '\0')
{
bfd *i;
 
for (i = info->input_bfds; i != NULL; i = i->link.next)
{
asection *s = bfd_get_section_by_name (i, sec_name);
if (s != NULL && !s->gc_mark)
{
*start_stop = TRUE;
return s;
}
}
}
}
 
return (*gc_mark_hook) (sec, info, cookie->rel, h, NULL);
}
 
11721,10 → 12164,13
struct elf_reloc_cookie *cookie)
{
asection *rsec;
bfd_boolean start_stop = FALSE;
 
rsec = _bfd_elf_gc_mark_rsec (info, sec, gc_mark_hook, cookie);
if (rsec && !rsec->gc_mark)
rsec = _bfd_elf_gc_mark_rsec (info, sec, gc_mark_hook, cookie, &start_stop);
while (rsec != NULL)
{
if (!rsec->gc_mark)
{
if (bfd_get_flavour (rsec->owner) != bfd_target_elf_flavour
|| (rsec->owner->flags & DYNAMIC) != 0)
rsec->gc_mark = 1;
11731,6 → 12177,10
else if (!_bfd_elf_gc_mark (info, rsec, gc_mark_hook))
return FALSE;
}
if (!start_stop)
break;
rsec = bfd_get_next_section_by_name (rsec->owner, rsec);
}
return TRUE;
}
 
11792,9 → 12242,55
}
}
 
eh_frame = elf_section_eh_frame_entry (sec);
if (ret && eh_frame && !eh_frame->gc_mark)
if (!_bfd_elf_gc_mark (info, eh_frame, gc_mark_hook))
ret = FALSE;
 
return ret;
}
 
/* Scan and mark sections in a special or debug section group. */
 
static void
_bfd_elf_gc_mark_debug_special_section_group (asection *grp)
{
/* Point to first section of section group. */
asection *ssec;
/* Used to iterate the section group. */
asection *msec;
 
bfd_boolean is_special_grp = TRUE;
bfd_boolean is_debug_grp = TRUE;
 
/* First scan to see if group contains any section other than debug
and special section. */
ssec = msec = elf_next_in_group (grp);
do
{
if ((msec->flags & SEC_DEBUGGING) == 0)
is_debug_grp = FALSE;
 
if ((msec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) != 0)
is_special_grp = FALSE;
 
msec = elf_next_in_group (msec);
}
while (msec != ssec);
 
/* If this is a pure debug section group or pure special section group,
keep all sections in this group. */
if (is_debug_grp || is_special_grp)
{
do
{
msec->gc_mark = 1;
msec = elf_next_in_group (msec);
}
while (msec != ssec);
}
}
 
/* Keep debug and special sections. */
 
bfd_boolean
11803,7 → 12299,7
{
bfd *ibfd;
 
for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
{
asection *isec;
bfd_boolean some_kept;
11835,13 → 12331,17
continue;
 
/* Keep debug and special sections like .comment when they are
not part of a group, or when we have single-member groups. */
not part of a group. Also keep section groups that contain
just debug sections or special sections. */
for (isec = ibfd->sections; isec != NULL; isec = isec->next)
if ((elf_next_in_group (isec) == NULL
|| elf_next_in_group (isec) == isec)
&& ((isec->flags & SEC_DEBUGGING) != 0
|| (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0))
{
if ((isec->flags & SEC_GROUP) != 0)
_bfd_elf_gc_mark_debug_special_section_group (isec);
else if (((isec->flags & SEC_DEBUGGING) != 0
|| (isec->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0)
&& elf_next_in_group (isec) == NULL)
isec->gc_mark = 1;
}
 
if (! debug_frag_seen)
continue;
11877,7 → 12377,6
isec->name, ilen) == 0)
{
dsec->gc_mark = 0;
break;
}
}
}
11900,7 → 12399,7
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))
11931,11 → 12430,12
unsigned long section_sym_count;
struct elf_gc_sweep_symbol_info sweep_info;
 
for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
{
asection *o;
 
if (bfd_get_flavour (sub) != bfd_target_elf_flavour)
if (bfd_get_flavour (sub) != bfd_target_elf_flavour
|| !(*bed->relocs_compatible) (sub->xvec, abfd->xvec))
continue;
 
for (o = sub->sections; o != NULL; o = o->next)
11968,7 → 12468,9
info we collected before. */
if (gc_sweep_hook
&& (o->flags & SEC_RELOC) != 0
&& o->reloc_count > 0
&& o->reloc_count != 0
&& !((info->strip == strip_all || info->strip == strip_debugger)
&& (o->flags & SEC_DEBUGGING) != 0)
&& !bfd_is_abs_section (o->output_section))
{
Elf_Internal_Rela *internal_relocs;
12116,15 → 12618,20
bfd_elf_gc_mark_dynamic_ref_symbol (struct elf_link_hash_entry *h, void *inf)
{
struct bfd_link_info *info = (struct bfd_link_info *) inf;
struct bfd_elf_dynamic_list *d = info->dynamic_list;
 
if ((h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
&& (h->ref_dynamic
|| ((!info->executable || info->export_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
&& (strchr (h->root.root.string, ELF_VER_CHR) != NULL
&& (!bfd_link_executable (info)
|| info->export_dynamic
|| (h->dynamic
&& d != NULL
&& (*d->match) (&d->head, NULL, h->root.root.string)))
&& (h->versioned >= versioned
|| !bfd_hide_sym_by_version (info->version_info,
h->root.root.string)))))
h->root.u.def.section->flags |= SEC_KEEP;
12155,6 → 12662,36
}
}
 
bfd_boolean
bfd_elf_parse_eh_frame_entries (bfd *abfd ATTRIBUTE_UNUSED,
struct bfd_link_info *info)
{
bfd *ibfd = info->input_bfds;
 
for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
{
asection *sec;
struct elf_reloc_cookie cookie;
 
if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
continue;
 
if (!init_reloc_cookie (&cookie, info, ibfd))
return FALSE;
 
for (sec = ibfd->sections; sec; sec = sec->next)
{
if (CONST_STRNEQ (bfd_section_name (ibfd, sec), ".eh_frame_entry")
&& init_reloc_cookie_rels (&cookie, info, ibfd, sec))
{
_bfd_elf_parse_eh_frame_entry (info, sec, &cookie);
fini_reloc_cookie_rels (&cookie, sec);
}
}
}
return TRUE;
}
 
/* Do mark and sweep of unused sections. */
 
bfd_boolean
12164,6 → 12701,7
bfd *sub;
elf_gc_mark_hook_fn gc_mark_hook;
const struct elf_backend_data *bed = get_elf_backend_data (abfd);
struct elf_link_hash_table *htab;
 
if (!bed->can_gc_sections
|| !is_elf_hash_table (info->hash))
12173,11 → 12711,13
}
 
bed->gc_keep (info);
htab = elf_hash_table (info);
 
/* Try to parse each bfd's .eh_frame section. Point elf_eh_frame_section
at the .eh_frame section if we can mark the FDEs individually. */
_bfd_elf_begin_eh_frame_parsing (info);
for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
for (sub = info->input_bfds;
info->eh_frame_hdr_type != COMPACT_EH_HDR && sub != NULL;
sub = sub->link.next)
{
asection *sec;
struct elf_reloc_cookie cookie;
12190,38 → 12730,32
&& (sec->flags & SEC_LINKER_CREATED) == 0)
elf_eh_frame_section (sub) = sec;
fini_reloc_cookie_for_section (&cookie, sec);
sec = bfd_get_next_section_by_name (sec);
sec = bfd_get_next_section_by_name (NULL, sec);
}
}
_bfd_elf_end_eh_frame_parsing (info);
 
/* Apply transitive closure to the vtable entry usage info. */
elf_link_hash_traverse (elf_hash_table (info),
elf_gc_propagate_vtable_entries_used,
&ok);
elf_link_hash_traverse (htab, elf_gc_propagate_vtable_entries_used, &ok);
if (!ok)
return FALSE;
 
/* Kill the vtable relocations that were not used. */
elf_link_hash_traverse (elf_hash_table (info),
elf_gc_smash_unused_vtentry_relocs,
&ok);
elf_link_hash_traverse (htab, elf_gc_smash_unused_vtentry_relocs, &ok);
if (!ok)
return FALSE;
 
/* Mark dynamically referenced symbols. */
if (elf_hash_table (info)->dynamic_sections_created)
elf_link_hash_traverse (elf_hash_table (info),
bed->gc_mark_dynamic_ref,
info);
if (htab->dynamic_sections_created)
elf_link_hash_traverse (htab, bed->gc_mark_dynamic_ref, info);
 
/* Grovel through relocs to find out who stays ... */
gc_mark_hook = bed->gc_mark_hook;
for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
{
asection *o;
 
if (bfd_get_flavour (sub) != bfd_target_elf_flavour)
if (bfd_get_flavour (sub) != bfd_target_elf_flavour
|| !(*bed->relocs_compatible) (sub->xvec, abfd->xvec))
continue;
 
/* Start at sections marked with SEC_KEEP (ref _bfd_elf_gc_keep).
12289,8 → 12823,8
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;
}
12322,8 → 12856,8
 
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;
}
12526,7 → 13060,7
gotoff = bed->got_header_size;
 
/* Do the local .got entries first. */
for (i = info->input_bfds; i; i = i->link_next)
for (i = info->input_bfds; i; i = i->link.next)
{
bfd_signed_vma *local_got;
bfd_size_type j, locsymcount;
12615,10 → 13149,10
 
if ((h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
&& discarded_section (h->root.u.def.section))
&& (h->root.u.def.section->owner != rcookie->abfd
|| h->root.u.def.section->kept_section != NULL
|| discarded_section (h->root.u.def.section)))
return TRUE;
else
return FALSE;
}
else
{
12631,7 → 13165,9
/* Need to: get the symbol; get the section. */
isym = &rcookie->locsyms[r_symndx];
isec = bfd_section_from_elf_index (rcookie->abfd, isym->st_shndx);
if (isec != NULL && discarded_section (isec))
if (isec != NULL
&& (isec->kept_section != NULL
|| discarded_section (isec)))
return TRUE;
}
return FALSE;
12640,94 → 13176,110
}
 
/* Discard unneeded references to discarded sections.
Returns TRUE if any section's size was changed. */
/* This function assumes that the relocations are in sorted order,
which is true for all known assemblers. */
Returns -1 on error, 1 if any section's size was changed, 0 if
nothing changed. This function assumes that the relocations are in
sorted order, which is true for all known assemblers. */
 
bfd_boolean
int
bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
{
struct elf_reloc_cookie cookie;
asection *stab, *eh;
const struct elf_backend_data *bed;
asection *o;
bfd *abfd;
bfd_boolean ret = FALSE;
int changed = 0;
 
if (info->traditional_format
|| !is_elf_hash_table (info->hash))
return FALSE;
return 0;
 
_bfd_elf_begin_eh_frame_parsing (info);
for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
o = bfd_get_section_by_name (output_bfd, ".stab");
if (o != NULL)
{
asection *i;
 
for (i = o->map_head.s; i != NULL; i = i->map_head.s)
{
if (i->size == 0
|| i->reloc_count == 0
|| i->sec_info_type != SEC_INFO_TYPE_STABS)
continue;
 
abfd = i->owner;
if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
continue;
 
bed = get_elf_backend_data (abfd);
if (!init_reloc_cookie_for_section (&cookie, info, i))
return -1;
 
eh = NULL;
if (!info->relocatable)
{
eh = bfd_get_section_by_name (abfd, ".eh_frame");
while (eh != NULL
&& (eh->size == 0
|| bfd_is_abs_section (eh->output_section)))
eh = bfd_get_next_section_by_name (eh);
if (_bfd_discard_section_stabs (abfd, i,
elf_section_data (i)->sec_info,
bfd_elf_reloc_symbol_deleted_p,
&cookie))
changed = 1;
 
fini_reloc_cookie_for_section (&cookie, i);
}
}
 
stab = bfd_get_section_by_name (abfd, ".stab");
if (stab != NULL
&& (stab->size == 0
|| bfd_is_abs_section (stab->output_section)
|| stab->sec_info_type != SEC_INFO_TYPE_STABS))
stab = NULL;
o = NULL;
if (info->eh_frame_hdr_type != COMPACT_EH_HDR)
o = bfd_get_section_by_name (output_bfd, ".eh_frame");
if (o != NULL)
{
asection *i;
 
if (stab == NULL
&& eh == NULL
&& bed->elf_backend_discard_info == NULL)
for (i = o->map_head.s; i != NULL; i = i->map_head.s)
{
if (i->size == 0)
continue;
 
if (!init_reloc_cookie (&cookie, info, abfd))
return FALSE;
abfd = i->owner;
if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
continue;
 
if (stab != NULL
&& stab->reloc_count > 0
&& init_reloc_cookie_rels (&cookie, info, abfd, stab))
{
if (_bfd_discard_section_stabs (abfd, stab,
elf_section_data (stab)->sec_info,
if (!init_reloc_cookie_for_section (&cookie, info, i))
return -1;
 
_bfd_elf_parse_eh_frame (abfd, info, i, &cookie);
if (_bfd_elf_discard_section_eh_frame (abfd, info, i,
bfd_elf_reloc_symbol_deleted_p,
&cookie))
ret = TRUE;
fini_reloc_cookie_rels (&cookie, stab);
changed = 1;
 
fini_reloc_cookie_for_section (&cookie, i);
}
}
 
while (eh != NULL
&& init_reloc_cookie_rels (&cookie, info, abfd, eh))
for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
{
_bfd_elf_parse_eh_frame (abfd, info, eh, &cookie);
if (_bfd_elf_discard_section_eh_frame (abfd, info, eh,
bfd_elf_reloc_symbol_deleted_p,
&cookie))
ret = TRUE;
fini_reloc_cookie_rels (&cookie, eh);
eh = bfd_get_next_section_by_name (eh);
}
const struct elf_backend_data *bed;
 
if (bed->elf_backend_discard_info != NULL
&& (*bed->elf_backend_discard_info) (abfd, &cookie, info))
ret = TRUE;
if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
continue;
 
bed = get_elf_backend_data (abfd);
 
if (bed->elf_backend_discard_info != NULL)
{
if (!init_reloc_cookie (&cookie, info, abfd))
return -1;
 
if ((*bed->elf_backend_discard_info) (abfd, &cookie, info))
changed = 1;
 
fini_reloc_cookie (&cookie, abfd);
}
}
 
if (info->eh_frame_hdr_type == COMPACT_EH_HDR)
_bfd_elf_end_eh_frame_parsing (info);
 
if (info->eh_frame_hdr
&& !info->relocatable
if (info->eh_frame_hdr_type
&& !bfd_link_relocatable (info)
&& _bfd_elf_discard_section_eh_frame_hdr (output_bfd, info))
ret = TRUE;
changed = 1;
 
return ret;
return changed;
}
 
bfd_boolean
13011,17 → 13563,24
return reloc_sec;
}
 
/* Copy the ELF symbol type associated with a linker hash entry. */
/* Copy the ELF symbol type and other attributes for a linker script
assignment from HSRC to HDEST. Generally this should be treated as
if we found a strong non-dynamic definition for HDEST (except that
ld ignores multiple definition errors). */
void
_bfd_elf_copy_link_hash_symbol_type (bfd *abfd ATTRIBUTE_UNUSED,
_bfd_elf_copy_link_hash_symbol_type (bfd *abfd,
struct bfd_link_hash_entry * hdest,
struct bfd_link_hash_entry * hsrc)
{
struct elf_link_hash_entry *ehdest = (struct elf_link_hash_entry *)hdest;
struct elf_link_hash_entry *ehsrc = (struct elf_link_hash_entry *)hsrc;
Elf_Internal_Sym isym;
 
ehdest->type = ehsrc->type;
ehdest->target_internal = ehsrc->target_internal;
 
isym.st_other = ehsrc->other;
elf_merge_st_other (abfd, ehdest, &isym, NULL, TRUE, FALSE);
}
 
/* Append a RELA relocation REL to section S in BFD. */