Line 108... |
Line 108... |
if (s != NULL && (s->flags & SEC_LINKER_CREATED) != 0)
|
if (s != NULL && (s->flags & SEC_LINKER_CREATED) != 0)
|
return TRUE;
|
return TRUE;
|
|
|
flags = bed->dynamic_sec_flags;
|
flags = bed->dynamic_sec_flags;
|
|
|
s = bfd_make_section_with_flags (abfd,
|
s = bfd_make_section_anyway_with_flags (abfd,
|
(bed->rela_plts_and_copies_p
|
(bed->rela_plts_and_copies_p
|
? ".rela.got" : ".rel.got"),
|
? ".rela.got" : ".rel.got"),
|
(bed->dynamic_sec_flags
|
(bed->dynamic_sec_flags
|
| SEC_READONLY));
|
| SEC_READONLY));
|
if (s == NULL
|
if (s == NULL
|
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
|
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
|
return FALSE;
|
return FALSE;
|
htab->srelgot = s;
|
htab->srelgot = s;
|
|
|
s = bfd_make_section_with_flags (abfd, ".got", flags);
|
s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
|
if (s == NULL
|
if (s == NULL
|
|| !bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
|
|| !bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
|
return FALSE;
|
return FALSE;
|
htab->sgot = s;
|
htab->sgot = s;
|
|
|
if (bed->want_got_plt)
|
if (bed->want_got_plt)
|
{
|
{
|
s = bfd_make_section_with_flags (abfd, ".got.plt", flags);
|
s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
|
if (s == NULL
|
if (s == NULL
|
|| !bfd_set_section_alignment (abfd, s,
|
|| !bfd_set_section_alignment (abfd, s,
|
bed->s->log_file_align))
|
bed->s->log_file_align))
|
return FALSE;
|
return FALSE;
|
htab->sgotplt = s;
|
htab->sgotplt = s;
|
Line 204... |
Line 204... |
|
|
/* A dynamically linked executable has a .interp section, but a
|
/* A dynamically linked executable has a .interp section, but a
|
shared library does not. */
|
shared library does not. */
|
if (info->executable)
|
if (info->executable)
|
{
|
{
|
s = bfd_make_section_with_flags (abfd, ".interp",
|
s = bfd_make_section_anyway_with_flags (abfd, ".interp",
|
flags | SEC_READONLY);
|
flags | SEC_READONLY);
|
if (s == NULL)
|
if (s == NULL)
|
return FALSE;
|
return FALSE;
|
}
|
}
|
|
|
/* Create sections to hold version informations. These are removed
|
/* Create sections to hold version informations. These are removed
|
if they are not needed. */
|
if they are not needed. */
|
s = bfd_make_section_with_flags (abfd, ".gnu.version_d",
|
s = bfd_make_section_anyway_with_flags (abfd, ".gnu.version_d",
|
flags | SEC_READONLY);
|
flags | SEC_READONLY);
|
if (s == NULL
|
if (s == NULL
|
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
|
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
|
return FALSE;
|
return FALSE;
|
|
|
s = bfd_make_section_with_flags (abfd, ".gnu.version",
|
s = bfd_make_section_anyway_with_flags (abfd, ".gnu.version",
|
flags | SEC_READONLY);
|
flags | SEC_READONLY);
|
if (s == NULL
|
if (s == NULL
|
|| ! bfd_set_section_alignment (abfd, s, 1))
|
|| ! bfd_set_section_alignment (abfd, s, 1))
|
return FALSE;
|
return FALSE;
|
|
|
s = bfd_make_section_with_flags (abfd, ".gnu.version_r",
|
s = bfd_make_section_anyway_with_flags (abfd, ".gnu.version_r",
|
flags | SEC_READONLY);
|
flags | SEC_READONLY);
|
if (s == NULL
|
if (s == NULL
|
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
|
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
|
return FALSE;
|
return FALSE;
|
|
|
s = bfd_make_section_with_flags (abfd, ".dynsym",
|
s = bfd_make_section_anyway_with_flags (abfd, ".dynsym",
|
flags | SEC_READONLY);
|
flags | SEC_READONLY);
|
if (s == NULL
|
if (s == NULL
|
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
|
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
|
return FALSE;
|
return FALSE;
|
|
|
s = bfd_make_section_with_flags (abfd, ".dynstr",
|
s = bfd_make_section_anyway_with_flags (abfd, ".dynstr",
|
flags | SEC_READONLY);
|
flags | SEC_READONLY);
|
if (s == NULL)
|
if (s == NULL)
|
return FALSE;
|
return FALSE;
|
|
|
s = bfd_make_section_with_flags (abfd, ".dynamic", flags);
|
s = bfd_make_section_anyway_with_flags (abfd, ".dynamic", flags);
|
if (s == NULL
|
if (s == NULL
|
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
|
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
|
return FALSE;
|
return FALSE;
|
|
|
/* The special symbol _DYNAMIC is always set to the start of the
|
/* The special symbol _DYNAMIC is always set to the start of the
|
Line 257... |
Line 257... |
if (!_bfd_elf_define_linkage_sym (abfd, info, s, "_DYNAMIC"))
|
if (!_bfd_elf_define_linkage_sym (abfd, info, s, "_DYNAMIC"))
|
return FALSE;
|
return FALSE;
|
|
|
if (info->emit_hash)
|
if (info->emit_hash)
|
{
|
{
|
s = bfd_make_section_with_flags (abfd, ".hash", flags | SEC_READONLY);
|
s = bfd_make_section_anyway_with_flags (abfd, ".hash",
|
|
flags | SEC_READONLY);
|
if (s == NULL
|
if (s == NULL
|
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
|
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
|
return FALSE;
|
return FALSE;
|
elf_section_data (s)->this_hdr.sh_entsize = bed->s->sizeof_hash_entry;
|
elf_section_data (s)->this_hdr.sh_entsize = bed->s->sizeof_hash_entry;
|
}
|
}
|
|
|
if (info->emit_gnu_hash)
|
if (info->emit_gnu_hash)
|
{
|
{
|
s = bfd_make_section_with_flags (abfd, ".gnu.hash",
|
s = bfd_make_section_anyway_with_flags (abfd, ".gnu.hash",
|
flags | SEC_READONLY);
|
flags | SEC_READONLY);
|
if (s == NULL
|
if (s == NULL
|
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
|
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
|
return FALSE;
|
return FALSE;
|
/* For 64-bit ELF, .gnu.hash is a non-uniform entity size section:
|
/* For 64-bit ELF, .gnu.hash is a non-uniform entity size section:
|
Line 318... |
Line 319... |
else
|
else
|
pltflags |= SEC_ALLOC | SEC_CODE | SEC_LOAD;
|
pltflags |= SEC_ALLOC | SEC_CODE | SEC_LOAD;
|
if (bed->plt_readonly)
|
if (bed->plt_readonly)
|
pltflags |= SEC_READONLY;
|
pltflags |= SEC_READONLY;
|
|
|
s = bfd_make_section_with_flags (abfd, ".plt", pltflags);
|
s = bfd_make_section_anyway_with_flags (abfd, ".plt", pltflags);
|
if (s == NULL
|
if (s == NULL
|
|| ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
|
|| ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
|
return FALSE;
|
return FALSE;
|
htab->splt = s;
|
htab->splt = s;
|
|
|
Line 335... |
Line 336... |
elf_hash_table (info)->hplt = h;
|
elf_hash_table (info)->hplt = h;
|
if (h == NULL)
|
if (h == NULL)
|
return FALSE;
|
return FALSE;
|
}
|
}
|
|
|
s = bfd_make_section_with_flags (abfd,
|
s = bfd_make_section_anyway_with_flags (abfd,
|
(bed->rela_plts_and_copies_p
|
(bed->rela_plts_and_copies_p
|
? ".rela.plt" : ".rel.plt"),
|
? ".rela.plt" : ".rel.plt"),
|
flags | SEC_READONLY);
|
flags | SEC_READONLY);
|
if (s == NULL
|
if (s == NULL
|
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
|
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
|
Line 355... |
Line 356... |
by dynamic objects, are referenced by regular objects, and are
|
by dynamic objects, are referenced by regular objects, and are
|
not functions. We must allocate space for them in the process
|
not functions. We must allocate space for them in the process
|
image and use a R_*_COPY reloc to tell the dynamic linker to
|
image and use a R_*_COPY reloc to tell the dynamic linker to
|
initialize them at run time. The linker script puts the .dynbss
|
initialize them at run time. The linker script puts the .dynbss
|
section into the .bss section of the final image. */
|
section into the .bss section of the final image. */
|
s = bfd_make_section_with_flags (abfd, ".dynbss",
|
s = bfd_make_section_anyway_with_flags (abfd, ".dynbss",
|
(SEC_ALLOC
|
(SEC_ALLOC | SEC_LINKER_CREATED));
|
| SEC_LINKER_CREATED));
|
|
if (s == NULL)
|
if (s == NULL)
|
return FALSE;
|
return FALSE;
|
|
|
/* The .rel[a].bss section holds copy relocs. This section is not
|
/* The .rel[a].bss section holds copy relocs. This section is not
|
normally needed. We need to create it here, though, so that the
|
normally needed. We need to create it here, though, so that the
|
Line 374... |
Line 374... |
be needed, we can discard it later. We will never need this
|
be needed, we can discard it later. We will never need this
|
section when generating a shared object, since they do not use
|
section when generating a shared object, since they do not use
|
copy relocs. */
|
copy relocs. */
|
if (! info->shared)
|
if (! info->shared)
|
{
|
{
|
s = bfd_make_section_with_flags (abfd,
|
s = bfd_make_section_anyway_with_flags (abfd,
|
(bed->rela_plts_and_copies_p
|
(bed->rela_plts_and_copies_p
|
? ".rela.bss" : ".rel.bss"),
|
? ".rela.bss" : ".rel.bss"),
|
flags | SEC_READONLY);
|
flags | SEC_READONLY);
|
if (s == NULL
|
if (s == NULL
|
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
|
|| ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
|
Line 2508... |
Line 2508... |
/* If this is a weak defined symbol in a dynamic object, and we know
|
/* If this is a weak defined symbol in a dynamic object, and we know
|
the real definition in the dynamic object, copy interesting flags
|
the real definition in the dynamic object, copy interesting flags
|
over to the real definition. */
|
over to the real definition. */
|
if (h->u.weakdef != NULL)
|
if (h->u.weakdef != NULL)
|
{
|
{
|
struct elf_link_hash_entry *weakdef;
|
/* If the real definition is defined by a regular object file,
|
|
don't do anything special. See the longer description in
|
|
_bfd_elf_adjust_dynamic_symbol, below. */
|
|
if (h->u.weakdef->def_regular)
|
|
h->u.weakdef = NULL;
|
|
else
|
|
{
|
|
struct elf_link_hash_entry *weakdef = h->u.weakdef;
|
|
|
weakdef = h->u.weakdef;
|
|
while (h->root.type == bfd_link_hash_indirect)
|
while (h->root.type == bfd_link_hash_indirect)
|
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
|
|
BFD_ASSERT (h->root.type == bfd_link_hash_defined
|
BFD_ASSERT (h->root.type == bfd_link_hash_defined
|
|| h->root.type == bfd_link_hash_defweak);
|
|| h->root.type == bfd_link_hash_defweak);
|
BFD_ASSERT (weakdef->def_dynamic);
|
BFD_ASSERT (weakdef->def_dynamic);
|
|
|
/* If the real definition is defined by a regular object file,
|
|
don't do anything special. See the longer description in
|
|
_bfd_elf_adjust_dynamic_symbol, below. */
|
|
if (weakdef->def_regular)
|
|
h->u.weakdef = NULL;
|
|
else
|
|
{
|
|
BFD_ASSERT (weakdef->root.type == bfd_link_hash_defined
|
BFD_ASSERT (weakdef->root.type == bfd_link_hash_defined
|
|| weakdef->root.type == bfd_link_hash_defweak);
|
|| weakdef->root.type == bfd_link_hash_defweak);
|
(*bed->elf_backend_copy_indirect_symbol) (eif->info, weakdef, h);
|
(*bed->elf_backend_copy_indirect_symbol) (eif->info, weakdef, h);
|
}
|
}
|
}
|
}
|
Line 11186... |
Line 11184... |
{
|
{
|
if (! (*bed->elf_backend_finish_dynamic_sections) (abfd, info))
|
if (! (*bed->elf_backend_finish_dynamic_sections) (abfd, info))
|
goto error_return;
|
goto error_return;
|
|
|
/* Check for DT_TEXTREL (late, in case the backend removes it). */
|
/* Check for DT_TEXTREL (late, in case the backend removes it). */
|
if ((info->warn_shared_textrel && info->shared)
|
if (((info->warn_shared_textrel && info->shared)
|
|| info->error_textrel)
|
|| info->error_textrel)
|
|
&& (o = bfd_get_section_by_name (dynobj, ".dynamic")) != NULL)
|
{
|
{
|
bfd_byte *dyncon, *dynconend;
|
bfd_byte *dyncon, *dynconend;
|
|
|
/* Fix up .dynamic entries. */
|
|
o = bfd_get_section_by_name (dynobj, ".dynamic");
|
|
BFD_ASSERT (o != NULL);
|
|
|
|
dyncon = o->contents;
|
dyncon = o->contents;
|
dynconend = o->contents + o->size;
|
dynconend = o->contents + o->size;
|
for (; dyncon < dynconend; dyncon += bed->s->sizeof_dyn)
|
for (; dyncon < dynconend; dyncon += bed->s->sizeof_dyn)
|
{
|
{
|
Elf_Internal_Dyn dyn;
|
Elf_Internal_Dyn dyn;
|
Line 11576... |
Line 11571... |
h = cookie->sym_hashes[r_symndx - cookie->extsymoff];
|
h = cookie->sym_hashes[r_symndx - cookie->extsymoff];
|
while (h->root.type == bfd_link_hash_indirect
|
while (h->root.type == bfd_link_hash_indirect
|
|| h->root.type == bfd_link_hash_warning)
|
|| h->root.type == bfd_link_hash_warning)
|
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
h->mark = 1;
|
h->mark = 1;
|
|
/* If this symbol is weak and there is a non-weak definition, we
|
|
keep the non-weak definition because many backends put
|
|
dynamic reloc info on the non-weak definition for code
|
|
handling copy relocs. */
|
|
if (h->u.weakdef != NULL)
|
|
h->u.weakdef->mark = 1;
|
return (*gc_mark_hook) (sec, info, cookie->rel, h, NULL);
|
return (*gc_mark_hook) (sec, info, cookie->rel, h, NULL);
|
}
|
}
|
|
|
return (*gc_mark_hook) (sec, info, cookie->rel, NULL,
|
return (*gc_mark_hook) (sec, info, cookie->rel, NULL,
|
&cookie->locsyms[r_symndx]);
|
&cookie->locsyms[r_symndx]);
|
Line 11726... |
Line 11727... |
elf_gc_sweep_symbol (struct elf_link_hash_entry *h, void *data)
|
elf_gc_sweep_symbol (struct elf_link_hash_entry *h, void *data)
|
{
|
{
|
if (!h->mark
|
if (!h->mark
|
&& (((h->root.type == bfd_link_hash_defined
|
&& (((h->root.type == bfd_link_hash_defined
|
|| h->root.type == bfd_link_hash_defweak)
|
|| h->root.type == bfd_link_hash_defweak)
|
&& !h->root.u.def.section->gc_mark)
|
&& !(h->def_regular
|
|
&& h->root.u.def.section->gc_mark))
|
|| h->root.type == bfd_link_hash_undefined
|
|| h->root.type == bfd_link_hash_undefined
|
|| h->root.type == bfd_link_hash_undefweak))
|
|| h->root.type == bfd_link_hash_undefweak))
|
{
|
{
|
struct elf_gc_sweep_symbol_info *inf;
|
struct elf_gc_sweep_symbol_info *inf;
|
|
|