#define ARCH_SIZE 0
#include "elf-bfd.h"
-static bfd_boolean elf_link_read_relocs_from_section
- PARAMS ((bfd *, Elf_Internal_Shdr *, PTR, Elf_Internal_Rela *));
-
bfd_boolean
-_bfd_elf_create_got_section (abfd, info)
- bfd *abfd;
- struct bfd_link_info *info;
+_bfd_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
{
flagword flags;
asection *s;
struct elf_link_hash_entry *h;
struct bfd_link_hash_entry *bh;
- struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
int ptralign;
/* This function may be called more than once. */
bh = NULL;
if (!(_bfd_generic_link_add_one_symbol
(info, abfd, "_GLOBAL_OFFSET_TABLE_", BSF_GLOBAL, s,
- bed->got_symbol_offset, (const char *) NULL, FALSE,
- bed->collect, &bh)))
+ bed->got_symbol_offset, NULL, FALSE, bed->collect, &bh)))
return FALSE;
h = (struct elf_link_hash_entry *) bh;
h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
actual contents and size of these sections later. */
bfd_boolean
-_bfd_elf_link_create_dynamic_sections (abfd, info)
- bfd *abfd;
- struct bfd_link_info *info;
+_bfd_elf_link_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
{
flagword flags;
register asection *s;
struct elf_link_hash_entry *h;
struct bfd_link_hash_entry *bh;
- struct elf_backend_data *bed;
+ const struct elf_backend_data *bed;
- if (! is_elf_hash_table (info))
+ if (! is_elf_hash_table (info->hash))
return FALSE;
if (elf_hash_table (info)->dynamic_sections_created)
return FALSE;
}
- if (! info->traditional_format
- && info->hash->creator->flavour == bfd_target_elf_flavour)
+ if (! info->traditional_format)
{
s = bfd_make_section (abfd, ".eh_frame_hdr");
if (s == NULL
code examines it to decide how to initialize the process. */
bh = NULL;
if (! (_bfd_generic_link_add_one_symbol
- (info, abfd, "_DYNAMIC", BSF_GLOBAL, s, (bfd_vma) 0,
- (const char *) 0, FALSE, get_elf_backend_data (abfd)->collect, &bh)))
+ (info, abfd, "_DYNAMIC", BSF_GLOBAL, s, 0, NULL, FALSE,
+ get_elf_backend_data (abfd)->collect, &bh)))
return FALSE;
h = (struct elf_link_hash_entry *) bh;
h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
/* Create dynamic sections when linking against a dynamic object. */
bfd_boolean
-_bfd_elf_create_dynamic_sections (abfd, info)
- bfd *abfd;
- struct bfd_link_info *info;
+_bfd_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
{
flagword flags, pltflags;
asection *s;
- struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
/* We need to create .plt, .rel[a].plt, .got, .got.plt, .dynbss, and
.rel[a].bss sections. */
struct bfd_link_hash_entry *bh = NULL;
if (! (_bfd_generic_link_add_one_symbol
- (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s,
- (bfd_vma) 0, (const char *) NULL, FALSE,
- get_elf_backend_data (abfd)->collect, &bh)))
+ (info, abfd, "_PROCEDURE_LINKAGE_TABLE_", BSF_GLOBAL, s, 0, NULL,
+ FALSE, get_elf_backend_data (abfd)->collect, &bh)))
return FALSE;
h = (struct elf_link_hash_entry *) bh;
h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
section into the .bss section of the final image. */
s = bfd_make_section (abfd, ".dynbss");
if (s == NULL
- || ! bfd_set_section_flags (abfd, s, SEC_ALLOC))
+ || ! bfd_set_section_flags (abfd, s, SEC_ALLOC | SEC_LINKER_CREATED))
return FALSE;
/* The .rel[a].bss section holds copy relocs. This section is not
one. */
bfd_boolean
-_bfd_elf_link_record_dynamic_symbol (info, h)
- struct bfd_link_info *info;
- struct elf_link_hash_entry *h;
+_bfd_elf_link_record_dynamic_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
{
if (h->dynindx == -1)
{
struct elf_strtab_hash *dynstr;
- char *p, *alc;
+ char *p;
const char *name;
- bfd_boolean copy;
bfd_size_type indx;
/* XXX: The ABI draft says the linker must turn hidden and
table. */
name = h->root.root.string;
p = strchr (name, ELF_VER_CHR);
- if (p == NULL)
- {
- alc = NULL;
- copy = FALSE;
- }
- else
- {
- size_t len = p - name + 1;
+ if (p != NULL)
+ /* We know that the p points into writable memory. In fact,
+ there are only a few symbols that have read-only names, being
+ those like _GLOBAL_OFFSET_TABLE_ that are created specially
+ by the backends. Most symbols will have names pointing into
+ an ELF string table read from a file, or to objalloc memory. */
+ *p = 0;
- alc = bfd_malloc ((bfd_size_type) len);
- if (alc == NULL)
- return FALSE;
- memcpy (alc, name, len - 1);
- alc[len - 1] = '\0';
- name = alc;
- copy = TRUE;
- }
-
- indx = _bfd_elf_strtab_add (dynstr, name, copy);
+ indx = _bfd_elf_strtab_add (dynstr, name, p != NULL);
- if (alc != NULL)
- free (alc);
+ if (p != NULL)
+ *p = ELF_VER_CHR;
if (indx == (bfd_size_type) -1)
return FALSE;
this in case some dynamic object refers to this symbol. */
bfd_boolean
-bfd_elf_record_link_assignment (output_bfd, info, name, provide)
- bfd *output_bfd ATTRIBUTE_UNUSED;
- struct bfd_link_info *info;
- const char *name;
- bfd_boolean provide;
+bfd_elf_record_link_assignment (bfd *output_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info,
+ const char *name,
+ bfd_boolean provide)
{
struct elf_link_hash_entry *h;
- if (info->hash->creator->flavour != bfd_target_elf_flavour)
+ if (!is_elf_hash_table (info->hash))
return TRUE;
h = elf_link_hash_lookup (elf_hash_table (info), name, TRUE, TRUE, FALSE);
in a discarded section, eg. a discarded link-once section symbol. */
int
-elf_link_record_local_dynamic_symbol (info, input_bfd, input_indx)
- struct bfd_link_info *info;
- bfd *input_bfd;
- long input_indx;
+elf_link_record_local_dynamic_symbol (struct bfd_link_info *info,
+ bfd *input_bfd,
+ long input_indx)
{
bfd_size_type amt;
struct elf_link_local_dynamic_entry *entry;
Elf_External_Sym_Shndx eshndx;
char esym[sizeof (Elf64_External_Sym)];
- if (! is_elf_hash_table (info))
+ if (! is_elf_hash_table (info->hash))
return 0;
/* See if the entry exists already. */
return 1;
amt = sizeof (*entry);
- entry = (struct elf_link_local_dynamic_entry *) bfd_alloc (input_bfd, amt);
+ entry = bfd_alloc (input_bfd, amt);
if (entry == NULL)
return 0;
/* Go find the symbol, so that we can find it's name. */
if (!bfd_elf_get_elf_syms (input_bfd, &elf_tdata (input_bfd)->symtab_hdr,
- (size_t) 1, (size_t) input_indx,
- &entry->isym, esym, &eshndx))
+ 1, input_indx, &entry->isym, esym, &eshndx))
{
bfd_release (input_bfd, entry);
return 0;
/* Return the dynindex of a local dynamic symbol. */
long
-_bfd_elf_link_lookup_local_dynindx (info, input_bfd, input_indx)
- struct bfd_link_info *info;
- bfd *input_bfd;
- long input_indx;
+_bfd_elf_link_lookup_local_dynindx (struct bfd_link_info *info,
+ bfd *input_bfd,
+ long input_indx)
{
struct elf_link_local_dynamic_entry *e;
them are removed because they are marked as local. This is called
via elf_link_hash_traverse. */
-static bfd_boolean elf_link_renumber_hash_table_dynsyms
- PARAMS ((struct elf_link_hash_entry *, PTR));
-
static bfd_boolean
-elf_link_renumber_hash_table_dynsyms (h, data)
- struct elf_link_hash_entry *h;
- PTR data;
+elf_link_renumber_hash_table_dynsyms (struct elf_link_hash_entry *h,
+ void *data)
{
- size_t *count = (size_t *) data;
+ size_t *count = data;
if (h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
the global symbols. */
unsigned long
-_bfd_elf_link_renumber_dynsyms (output_bfd, info)
- bfd *output_bfd;
- struct bfd_link_info *info;
+_bfd_elf_link_renumber_dynsyms (bfd *output_bfd, struct bfd_link_info *info)
{
unsigned long dynsymcount = 0;
a shared object. */
bfd_boolean
-_bfd_elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash, skip,
- override, type_change_ok, size_change_ok, dt_needed)
- bfd *abfd;
- struct bfd_link_info *info;
- const char *name;
- Elf_Internal_Sym *sym;
- asection **psec;
- bfd_vma *pvalue;
- struct elf_link_hash_entry **sym_hash;
- bfd_boolean *skip;
- bfd_boolean *override;
- bfd_boolean *type_change_ok;
- bfd_boolean *size_change_ok;
- bfd_boolean dt_needed;
+_bfd_elf_merge_symbol (bfd *abfd,
+ struct bfd_link_info *info,
+ const char *name,
+ Elf_Internal_Sym *sym,
+ asection **psec,
+ bfd_vma *pvalue,
+ struct elf_link_hash_entry **sym_hash,
+ bfd_boolean *skip,
+ bfd_boolean *override,
+ bfd_boolean *type_change_ok,
+ bfd_boolean *size_change_ok,
+ bfd_boolean dt_needed)
{
asection *sec;
struct elf_link_hash_entry *h;
else
olddef = TRUE;
- /* We need to rememeber if a symbol has a definition in a dynamic
+ /* We need to remember if a symbol has a definition in a dynamic
object or is weak in all dynamic objects. Internal and hidden
visibility will make it unavailable to dynamic objects. */
if (newdyn && (h->elf_link_hash_flags & ELF_LINK_DYNAMIC_DEF) == 0)
return TRUE;
}
- /* We need to treat weak definiton right, depending on if there is a
+ /* We need to treat weak definition right, depending on if there is a
definition from a dynamic object. */
if (bind == STB_WEAK)
{
/* It's OK to change the type if either the existing symbol or the
new symbol is weak unless it comes from a DT_NEEDED entry of
a shared object, in which case, the DT_NEEDED entry may not be
- required at the run time. */
+ required at the run time. The type change is also OK if the
+ old symbol is undefined and the new symbol is defined. */
if ((! dt_needed && oldweakdef)
|| oldweakundef
|| newweakdef
- || newweakundef)
+ || newweakundef
+ || (newdef
+ && (h->root.type == bfd_link_hash_undefined
+ || h->root.type == bfd_link_hash_undefweak)))
*type_change_ok = TRUE;
/* It's OK to change the size if either the existing symbol or the
h->size, abfd, bfd_link_hash_common, sym->st_size)))
return FALSE;
- /* If the predumed common symbol in the dynamic object is
+ /* If the presumed common symbol in the dynamic object is
larger, pretend that the new symbol has its size. */
if (h->size > *pvalue)
/* Handle the case where we had a versioned symbol in a dynamic
library and now find a definition in a normal object. In this
case, we make the versioned symbol point to the normal one. */
- struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
flip->root.type = h->root.type;
h->root.type = bfd_link_hash_indirect;
h->root.u.i.link = (struct bfd_link_hash_entry *) flip;
indicates if it comes from a DT_NEEDED entry of a shared object. */
bfd_boolean
-_bfd_elf_add_default_symbol (abfd, info, h, name, sym, psec, value,
- dynsym, override, dt_needed)
- bfd *abfd;
- struct bfd_link_info *info;
- struct elf_link_hash_entry *h;
- const char *name;
- Elf_Internal_Sym *sym;
- asection **psec;
- bfd_vma *value;
- bfd_boolean *dynsym;
- bfd_boolean override;
- bfd_boolean dt_needed;
+_bfd_elf_add_default_symbol (bfd *abfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ const char *name,
+ Elf_Internal_Sym *sym,
+ asection **psec,
+ bfd_vma *value,
+ bfd_boolean *dynsym,
+ bfd_boolean override,
+ bfd_boolean dt_needed)
{
bfd_boolean type_change_ok;
bfd_boolean size_change_ok;
char *shortname;
struct elf_link_hash_entry *hi;
struct bfd_link_hash_entry *bh;
- struct elf_backend_data *bed;
+ const struct elf_backend_data *bed;
bfd_boolean collect;
bfd_boolean dynamic;
char *p;
if (override)
{
- /* We are overridden by an old defition. We need to check if we
+ /* We are overridden by an old definition. We need to check if we
need to create the indirect symbol from the default name. */
hi = elf_link_hash_lookup (elf_hash_table (info), name, TRUE,
FALSE, FALSE);
bh = &hi->root;
if (! (_bfd_generic_link_add_one_symbol
(info, abfd, shortname, BSF_INDIRECT, bfd_ind_section_ptr,
- (bfd_vma) 0, name, FALSE, collect, &bh)))
+ 0, name, FALSE, collect, &bh)))
return FALSE;
hi = (struct elf_link_hash_entry *) bh;
}
{
/* Here SHORTNAME is a versioned name, so we don't expect to see
the type of override we do in the case above unless it is
- overridden by a versioned definiton. */
+ overridden by a versioned definition. */
if (hi->root.type != bfd_link_hash_defined
&& hi->root.type != bfd_link_hash_defweak)
(*_bfd_error_handler)
bh = &hi->root;
if (! (_bfd_generic_link_add_one_symbol
(info, abfd, shortname, BSF_INDIRECT,
- bfd_ind_section_ptr, (bfd_vma) 0, name, FALSE, collect, &bh)))
+ bfd_ind_section_ptr, 0, name, FALSE, collect, &bh)))
return FALSE;
hi = (struct elf_link_hash_entry *) bh;
symbol table. It is called via elf_link_hash_traverse. */
bfd_boolean
-_bfd_elf_export_symbol (h, data)
- struct elf_link_hash_entry *h;
- PTR data;
+_bfd_elf_export_symbol (struct elf_link_hash_entry *h, void *data)
{
- struct elf_info_failed *eif = (struct elf_info_failed *) data;
+ struct elf_info_failed *eif = data;
/* Ignore indirect symbols. These are added by the versioning code. */
if (h->root.type == bfd_link_hash_indirect)
for (t = eif->verdefs; t != NULL; t = t->next)
{
- if (t->globals != NULL)
+ if (t->globals.list != NULL)
{
- for (d = t->globals; d != NULL; d = d->next)
- {
- if ((*d->match) (d, h->root.root.string))
- goto doit;
- }
+ d = (*t->match) (&t->globals, NULL, h->root.root.string);
+ if (d != NULL)
+ goto doit;
}
- if (t->locals != NULL)
+ if (t->locals.list != NULL)
{
- for (d = t->locals ; d != NULL; d = d->next)
- {
- if ((*d->match) (d, h->root.root.string))
- return TRUE;
- }
+ d = (*t->match) (&t->locals, NULL, h->root.root.string);
+ if (d != NULL)
+ return TRUE;
}
}
This function is called via elf_link_hash_traverse. */
bfd_boolean
-_bfd_elf_link_find_version_dependencies (h, data)
- struct elf_link_hash_entry *h;
- PTR data;
+_bfd_elf_link_find_version_dependencies (struct elf_link_hash_entry *h,
+ void *data)
{
- struct elf_find_verdep_info *rinfo = (struct elf_find_verdep_info *) data;
+ struct elf_find_verdep_info *rinfo = data;
Elf_Internal_Verneed *t;
Elf_Internal_Vernaux *a;
bfd_size_type amt;
if (t == NULL)
{
amt = sizeof *t;
- t = (Elf_Internal_Verneed *) bfd_zalloc (rinfo->output_bfd, amt);
+ t = bfd_zalloc (rinfo->output_bfd, amt);
if (t == NULL)
{
rinfo->failed = TRUE;
}
amt = sizeof *a;
- a = (Elf_Internal_Vernaux *) bfd_zalloc (rinfo->output_bfd, amt);
+ a = bfd_zalloc (rinfo->output_bfd, amt);
/* Note that we are copying a string pointer here, and testing it
above. If bfd_elf_string_from_elf_section is ever changed to
local. This function is called via elf_link_hash_traverse. */
bfd_boolean
-_bfd_elf_link_assign_sym_version (h, data)
- struct elf_link_hash_entry *h;
- PTR data;
+_bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data)
{
struct elf_assign_sym_version_info *sinfo;
struct bfd_link_info *info;
- struct elf_backend_data *bed;
+ const struct elf_backend_data *bed;
struct elf_info_failed eif;
char *p;
bfd_size_type amt;
- sinfo = (struct elf_assign_sym_version_info *) data;
+ sinfo = data;
info = sinfo->info;
if (h->root.type == bfd_link_hash_warning)
struct bfd_elf_version_expr *d;
len = p - h->root.root.string;
- alc = bfd_malloc ((bfd_size_type) len);
+ alc = bfd_malloc (len);
if (alc == NULL)
return FALSE;
memcpy (alc, h->root.root.string, len - 1);
t->used = TRUE;
d = NULL;
- if (t->globals != NULL)
- {
- for (d = t->globals; d != NULL; d = d->next)
- if ((*d->match) (d, alc))
- break;
- }
+ if (t->globals.list != NULL)
+ d = (*t->match) (&t->globals, NULL, alc);
/* See if there is anything to force this symbol to
local scope. */
- if (d == NULL && t->locals != NULL)
+ if (d == NULL && t->locals.list != NULL)
{
- for (d = t->locals; d != NULL; d = d->next)
- {
- if ((*d->match) (d, alc))
- {
- if (h->dynindx != -1
- && info->shared
- && ! info->export_dynamic)
- {
- (*bed->elf_backend_hide_symbol) (info, h, TRUE);
- }
-
- break;
- }
- }
+ d = (*t->match) (&t->locals, NULL, alc);
+ if (d != NULL
+ && h->dynindx != -1
+ && info->shared
+ && ! info->export_dynamic)
+ (*bed->elf_backend_hide_symbol) (info, h, TRUE);
}
free (alc);
return TRUE;
amt = sizeof *t;
- t = ((struct bfd_elf_version_tree *)
- bfd_alloc (sinfo->output_bfd, amt));
+ t = bfd_zalloc (sinfo->output_bfd, amt);
if (t == NULL)
{
sinfo->failed = TRUE;
return FALSE;
}
- t->next = NULL;
t->name = p;
- t->globals = NULL;
- t->locals = NULL;
- t->deps = NULL;
t->name_indx = (unsigned int) -1;
t->used = TRUE;
local_ver = NULL;
for (t = sinfo->verdefs; t != NULL; t = t->next)
{
- if (t->globals != NULL)
+ if (t->globals.list != NULL)
{
bfd_boolean matched;
matched = FALSE;
- for (d = t->globals; d != NULL; d = d->next)
- {
- if ((*d->match) (d, h->root.root.string))
- {
- if (d->symver)
- matched = TRUE;
- else
- {
- /* There is a version without definition. Make
- the symbol the default definition for this
- version. */
- h->verinfo.vertree = t;
- local_ver = NULL;
- d->script = 1;
- break;
- }
- }
- }
-
+ d = NULL;
+ while ((d = (*t->match) (&t->globals, d,
+ h->root.root.string)) != NULL)
+ if (d->symver)
+ matched = TRUE;
+ else
+ {
+ /* There is a version without definition. Make
+ the symbol the default definition for this
+ version. */
+ h->verinfo.vertree = t;
+ local_ver = NULL;
+ d->script = 1;
+ break;
+ }
if (d != NULL)
break;
else if (matched)
(*bed->elf_backend_hide_symbol) (info, h, TRUE);
}
- if (t->locals != NULL)
+ if (t->locals.list != NULL)
{
- for (d = t->locals; d != NULL; d = d->next)
+ d = NULL;
+ while ((d = (*t->match) (&t->locals, d,
+ h->root.root.string)) != NULL)
{
+ local_ver = t;
/* If the match is "*", keep looking for a more
- explicit, perhaps even global, match. */
- if (d->pattern[0] == '*' && d->pattern[1] == '\0')
- local_ver = t;
- else if ((*d->match) (d, h->root.root.string))
- {
- local_ver = t;
- break;
- }
+ explicit, perhaps even global, match.
+ XXX: Shouldn't this be !d->wildcard instead? */
+ if (d->pattern[0] != '*' || d->pattern[1] != '\0')
+ break;
}
if (d != NULL)
Returns FALSE if something goes wrong. */
static bfd_boolean
-elf_link_read_relocs_from_section (abfd, shdr, external_relocs,
- internal_relocs)
- bfd *abfd;
- Elf_Internal_Shdr *shdr;
- PTR external_relocs;
- Elf_Internal_Rela *internal_relocs;
+elf_link_read_relocs_from_section (bfd *abfd,
+ asection *sec,
+ Elf_Internal_Shdr *shdr,
+ void *external_relocs,
+ Elf_Internal_Rela *internal_relocs)
{
- struct elf_backend_data *bed;
- void (*swap_in) PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rela *));
+ const struct elf_backend_data *bed;
+ void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *);
const bfd_byte *erela;
const bfd_byte *erelaend;
Elf_Internal_Rela *irela;
+ Elf_Internal_Shdr *symtab_hdr;
+ size_t nsyms;
/* If there aren't any relocations, that's OK. */
if (!shdr)
if (bfd_bread (external_relocs, shdr->sh_size, abfd) != shdr->sh_size)
return FALSE;
+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ nsyms = symtab_hdr->sh_size / symtab_hdr->sh_entsize;
+
bed = get_elf_backend_data (abfd);
/* Convert the external relocations to the internal format. */
irela = internal_relocs;
while (erela < erelaend)
{
+ bfd_vma r_symndx;
+
(*swap_in) (abfd, erela, irela);
+ r_symndx = ELF32_R_SYM (irela->r_info);
+ if (bed->s->arch_size == 64)
+ r_symndx >>= 24;
+ if ((size_t) r_symndx >= nsyms)
+ {
+ (*_bfd_error_handler)
+ (_("%s: bad reloc symbol index (0x%lx >= 0x%lx) for offset 0x%lx in section `%s'"),
+ bfd_archive_filename (abfd), (unsigned long) r_symndx,
+ (unsigned long) nsyms, irela->r_offset, sec->name);
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
irela += bed->s->int_rels_per_ext_rel;
erela += shdr->sh_entsize;
}
REL_HDR2 relocations. */
Elf_Internal_Rela *
-_bfd_elf_link_read_relocs (abfd, o, external_relocs, internal_relocs,
- keep_memory)
- bfd *abfd;
- asection *o;
- PTR external_relocs;
- Elf_Internal_Rela *internal_relocs;
- bfd_boolean keep_memory;
+_bfd_elf_link_read_relocs (bfd *abfd,
+ asection *o,
+ void *external_relocs,
+ Elf_Internal_Rela *internal_relocs,
+ bfd_boolean keep_memory)
{
Elf_Internal_Shdr *rel_hdr;
- PTR alloc1 = NULL;
+ void *alloc1 = NULL;
Elf_Internal_Rela *alloc2 = NULL;
- struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
if (elf_section_data (o)->relocs != NULL)
return elf_section_data (o)->relocs;
size = o->reloc_count;
size *= bed->s->int_rels_per_ext_rel * sizeof (Elf_Internal_Rela);
if (keep_memory)
- internal_relocs = (Elf_Internal_Rela *) bfd_alloc (abfd, size);
+ internal_relocs = bfd_alloc (abfd, size);
else
- internal_relocs = alloc2 = (Elf_Internal_Rela *) bfd_malloc (size);
+ internal_relocs = alloc2 = bfd_malloc (size);
if (internal_relocs == NULL)
goto error_return;
}
if (elf_section_data (o)->rel_hdr2)
size += elf_section_data (o)->rel_hdr2->sh_size;
- alloc1 = (PTR) bfd_malloc (size);
+ alloc1 = bfd_malloc (size);
if (alloc1 == NULL)
goto error_return;
external_relocs = alloc1;
}
- if (!elf_link_read_relocs_from_section (abfd, rel_hdr,
+ if (!elf_link_read_relocs_from_section (abfd, o, rel_hdr,
external_relocs,
internal_relocs))
goto error_return;
if (!elf_link_read_relocs_from_section
- (abfd,
+ (abfd, o,
elf_section_data (o)->rel_hdr2,
((bfd_byte *) external_relocs) + rel_hdr->sh_size,
internal_relocs + (NUM_SHDR_ENTRIES (rel_hdr)
section header for a section containing relocations for O. */
bfd_boolean
-_bfd_elf_link_size_reloc_section (abfd, rel_hdr, o)
- bfd *abfd;
- Elf_Internal_Shdr *rel_hdr;
- asection *o;
+_bfd_elf_link_size_reloc_section (bfd *abfd,
+ Elf_Internal_Shdr *rel_hdr,
+ asection *o)
{
bfd_size_type reloc_count;
bfd_size_type num_rel_hashes;
allocate it with bfd_alloc rather than malloc. Also since we
cannot be sure that the contents will actually be filled in,
we zero the allocated space. */
- rel_hdr->contents = (PTR) bfd_zalloc (abfd, rel_hdr->sh_size);
+ rel_hdr->contents = bfd_zalloc (abfd, rel_hdr->sh_size);
if (rel_hdr->contents == NULL && rel_hdr->sh_size != 0)
return FALSE;
{
struct elf_link_hash_entry **p;
- p = ((struct elf_link_hash_entry **)
- bfd_zmalloc (num_rel_hashes
- * sizeof (struct elf_link_hash_entry *)));
+ p = bfd_zmalloc (num_rel_hashes * sizeof (struct elf_link_hash_entry *));
if (p == NULL)
return FALSE;
OUTPUT_BFD. */
bfd_boolean
-_bfd_elf_link_output_relocs (output_bfd, input_section, input_rel_hdr,
- internal_relocs)
- bfd *output_bfd;
- asection *input_section;
- Elf_Internal_Shdr *input_rel_hdr;
- Elf_Internal_Rela *internal_relocs;
+_bfd_elf_link_output_relocs (bfd *output_bfd,
+ asection *input_section,
+ Elf_Internal_Shdr *input_rel_hdr,
+ Elf_Internal_Rela *internal_relocs)
{
Elf_Internal_Rela *irela;
Elf_Internal_Rela *irelaend;
Elf_Internal_Shdr *output_rel_hdr;
asection *output_section;
unsigned int *rel_countp = NULL;
- struct elf_backend_data *bed;
- void (*swap_out) PARAMS ((bfd *, const Elf_Internal_Rela *, bfd_byte *));
+ const struct elf_backend_data *bed;
+ void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
output_section = input_section->output_section;
output_rel_hdr = NULL;
the face of future changes. */
bfd_boolean
-_bfd_elf_fix_symbol_flags (h, eif)
- struct elf_link_hash_entry *h;
- struct elf_info_failed *eif;
+_bfd_elf_fix_symbol_flags (struct elf_link_hash_entry *h,
+ struct elf_info_failed *eif)
{
/* If this symbol was mentioned in a non-ELF file, try to set
DEF_REGULAR and REF_REGULAR correctly. This is the only way to
will force it local. */
if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0
&& eif->info->shared
- && is_elf_hash_table (eif->info)
+ && is_elf_hash_table (eif->info->hash)
&& (eif->info->symbolic
|| ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0)
{
- struct elf_backend_data *bed;
+ const struct elf_backend_data *bed;
bfd_boolean force_local;
bed = get_elf_backend_data (elf_hash_table (eif->info)->dynobj);
if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
&& h->root.type == bfd_link_hash_undefweak)
{
- struct elf_backend_data *bed;
+ const struct elf_backend_data *bed;
bed = get_elf_backend_data (elf_hash_table (eif->info)->dynobj);
(*bed->elf_backend_hide_symbol) (eif->info, h, TRUE);
}
h->weakdef = NULL;
else
{
- struct elf_backend_data *bed;
+ const struct elf_backend_data *bed;
bed = get_elf_backend_data (elf_hash_table (eif->info)->dynobj);
(*bed->elf_backend_copy_indirect_symbol) (bed, weakdef, h);
recursively. */
bfd_boolean
-_bfd_elf_adjust_dynamic_symbol (h, data)
- struct elf_link_hash_entry *h;
- PTR data;
+_bfd_elf_adjust_dynamic_symbol (struct elf_link_hash_entry *h, void *data)
{
- struct elf_info_failed *eif = (struct elf_info_failed *) data;
+ struct elf_info_failed *eif = data;
bfd *dynobj;
- struct elf_backend_data *bed;
+ const struct elf_backend_data *bed;
- if (! is_elf_hash_table (eif->info))
+ if (! is_elf_hash_table (eif->info->hash))
return FALSE;
if (h->root.type == bfd_link_hash_warning)
H->WEAKDEF before it finds H? */
h->weakdef->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
- if (! _bfd_elf_adjust_dynamic_symbol (h->weakdef, (PTR) eif))
+ if (! _bfd_elf_adjust_dynamic_symbol (h->weakdef, eif))
return FALSE;
}
to reflect the object merging within the sections. */
bfd_boolean
-_bfd_elf_link_sec_merge_syms (h, data)
- struct elf_link_hash_entry *h;
- PTR data;
+_bfd_elf_link_sec_merge_syms (struct elf_link_hash_entry *h, void *data)
{
asection *sec;
&& ((sec = h->root.u.def.section)->flags & SEC_MERGE)
&& sec->sec_info_type == ELF_INFO_TYPE_MERGE)
{
- bfd *output_bfd = (bfd *) data;
+ bfd *output_bfd = data;
h->root.u.def.value =
_bfd_merged_section_offset (output_bfd,
&h->root.u.def.section,
elf_section_data (sec)->sec_info,
- h->root.u.def.value, (bfd_vma) 0);
+ h->root.u.def.value, 0);
}
return TRUE;
considered to bind dynamically. */
bfd_boolean
-_bfd_elf_dynamic_symbol_p (h, info, ignore_protected)
- struct elf_link_hash_entry *h;
- struct bfd_link_info *info;
- bfd_boolean ignore_protected;
+_bfd_elf_dynamic_symbol_p (struct elf_link_hash_entry *h,
+ struct bfd_link_info *info,
+ bfd_boolean ignore_protected)
{
bfd_boolean binding_stays_local_p;
break;
default:
- /* With STV_DEFAULT, weak symbols do not bind locally. */
- if (h->root.type == bfd_link_hash_undefweak
- || h->root.type == bfd_link_hash_defweak)
- return TRUE;
break;
}
undefined symbols and weak symbols. */
bfd_boolean
-_bfd_elf_symbol_refs_local_p (h, info, local_protected)
- struct elf_link_hash_entry *h;
- struct bfd_link_info *info;
- bfd_boolean local_protected;
+_bfd_elf_symbol_refs_local_p (struct elf_link_hash_entry *h,
+ struct bfd_link_info *info,
+ bfd_boolean local_protected)
{
/* If it's a local sym, of course we resolve locally. */
if (h == NULL)
dynamic linker will resolve them locally. */
return local_protected;
}
+
+/* Caches some TLS segment info, and ensures that the TLS segment vma is
+ aligned. Returns the first TLS output section. */
+
+struct bfd_section *
+_bfd_elf_tls_setup (bfd *obfd, struct bfd_link_info *info)
+{
+ struct bfd_section *sec, *tls;
+ unsigned int align = 0;
+
+ for (sec = obfd->sections; sec != NULL; sec = sec->next)
+ if ((sec->flags & SEC_THREAD_LOCAL) != 0)
+ break;
+ tls = sec;
+
+ for (; sec != NULL && (sec->flags & SEC_THREAD_LOCAL) != 0; sec = sec->next)
+ if (sec->alignment_power > align)
+ align = sec->alignment_power;
+
+ elf_hash_table (info)->tls_sec = tls;
+
+ /* Ensure the alignment of the first section is the largest alignment,
+ so that the tls segment starts aligned. */
+ if (tls != NULL)
+ tls->alignment_power = align;
+
+ return tls;
+}