This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
alpha linker fix
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: binutils at sources dot redhat dot com, Richard Henderson <rth at redhat dot com>
- Date: Thu, 23 Jun 2005 11:46:33 +0930
- Subject: alpha linker fix
This fixes an alpha backend problem discovered when looking at testsuite
results with http://sources.redhat.com/ml/binutils/2005-06/msg00257.html
applied locally. The problem is that create_dynamic_sections will create
the linker .got, .plt etc. sections in the bfd that happens to trigger
the create_dynamic_sections call. When the bfd is one for a shared lib,
you very likely already have a .got section, breaking the assumption
in elf64_alpha_create_got_section that .got is linker created. I think
we can test tdata->gotobj rather than doing bfd_get_section_by_name,
but I may be missing some reason why gotobj should not be set on all
elf64_alpha_create_got_section calls. Richard?
* elf64-alpha.c (elf64_alpha_create_got_section): Always create
a new .got section. Assign gotobj here.
(elf64_alpha_create_dynamic_sections): Always make new sections
by using bfd_make_section_anyway_with_flags. Check that .got not
already created.
(elf64_alpha_check_relocs): Delete "got_created". Use tdata->gotobj
instead.
Index: bfd/elf64-alpha.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-alpha.c,v
retrieving revision 1.141
diff -u -p -r1.141 elf64-alpha.c
--- bfd/elf64-alpha.c 31 May 2005 22:53:44 -0000 1.141
+++ bfd/elf64-alpha.c 23 Jun 2005 02:01:15 -0000
@@ -1204,26 +1204,23 @@ static bfd_boolean
elf64_alpha_create_got_section (bfd *abfd,
struct bfd_link_info *info ATTRIBUTE_UNUSED)
{
+ flagword flags;
asection *s;
- if ((s = bfd_get_section_by_name (abfd, ".got")))
- {
- /* Check for a non-linker created .got? */
- if (alpha_elf_tdata (abfd)->got == NULL)
- alpha_elf_tdata (abfd)->got = s;
- return TRUE;
- }
-
- s = bfd_make_section_with_flags (abfd, ".got", (SEC_ALLOC | SEC_LOAD
- | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_LINKER_CREATED));
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED);
+ s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
if (s == NULL
|| !bfd_set_section_alignment (abfd, s, 3))
return FALSE;
alpha_elf_tdata (abfd)->got = s;
+ /* Make sure the object's gotobj is set to itself so that we default
+ to every object with its own .got. We'll merge .gots later once
+ we've collected each object's info. */
+ alpha_elf_tdata (abfd)->gotobj = abfd;
+
return TRUE;
}
@@ -1233,18 +1230,16 @@ static bfd_boolean
elf64_alpha_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
{
asection *s;
+ flagword flags;
struct elf_link_hash_entry *h;
struct bfd_link_hash_entry *bh;
/* We need to create .plt, .rela.plt, .got, and .rela.got sections. */
- s = bfd_make_section_with_flags (abfd, ".plt",
- (SEC_ALLOC | SEC_LOAD | SEC_CODE
- | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_LINKER_CREATED
- | (elf64_alpha_use_secureplt
- ? SEC_READONLY : 0)));
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED
+ | (elf64_alpha_use_secureplt ? SEC_READONLY : 0));
+ s = bfd_make_section_anyway_with_flags (abfd, ".plt", flags);
if (s == NULL || ! bfd_set_section_alignment (abfd, s, 4))
return FALSE;
@@ -1263,19 +1258,16 @@ elf64_alpha_create_dynamic_sections (bfd
if (info->shared && ! bfd_elf_link_record_dynamic_symbol (info, h))
return FALSE;
- s = bfd_make_section_with_flags (abfd, ".rela.plt",
- (SEC_ALLOC | SEC_LOAD
- | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_LINKER_CREATED
- | SEC_READONLY));
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED | SEC_READONLY);
+ s = bfd_make_section_anyway_with_flags (abfd, ".rela.plt", flags);
if (s == NULL || ! bfd_set_section_alignment (abfd, s, 3))
return FALSE;
if (elf64_alpha_use_secureplt)
{
- s = bfd_make_section_with_flags (abfd, ".got.plt",
- SEC_ALLOC | SEC_LINKER_CREATED);
+ flags = SEC_ALLOC | SEC_LINKER_CREATED;
+ s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
if (s == NULL || ! bfd_set_section_alignment (abfd, s, 3))
return FALSE;
}
@@ -1283,15 +1275,15 @@ elf64_alpha_create_dynamic_sections (bfd
/* We may or may not have created a .got section for this object, but
we definitely havn't done the rest of the work. */
- if (!elf64_alpha_create_got_section (abfd, info))
- return FALSE;
+ if (alpha_elf_tdata(abfd)->gotobj == NULL)
+ {
+ if (!elf64_alpha_create_got_section (abfd, info))
+ return FALSE;
+ }
- s = bfd_make_section_with_flags (abfd, ".rela.got",
- (SEC_ALLOC | SEC_LOAD
- | SEC_HAS_CONTENTS
- | SEC_IN_MEMORY
- | SEC_LINKER_CREATED
- | SEC_READONLY));
+ flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+ | SEC_LINKER_CREATED | SEC_READONLY);
+ s = bfd_make_section_anyway_with_flags (abfd, ".rela.got", flags);
if (s == NULL
|| !bfd_set_section_alignment (abfd, s, 3))
return FALSE;
@@ -1746,7 +1738,6 @@ elf64_alpha_check_relocs (bfd *abfd, str
Elf_Internal_Shdr *symtab_hdr;
struct alpha_elf_link_hash_entry **sym_hashes;
const Elf_Internal_Rela *rel, *relend;
- bfd_boolean got_created;
bfd_size_type amt;
if (info->relocatable)
@@ -1769,7 +1760,6 @@ elf64_alpha_check_relocs (bfd *abfd, str
rel_sec_name = NULL;
symtab_hdr = &elf_tdata(abfd)->symtab_hdr;
sym_hashes = alpha_elf_sym_hashes(abfd);
- got_created = FALSE;
relend = relocs + sec->reloc_count;
for (rel = relocs; rel < relend; ++rel)
@@ -1881,18 +1871,10 @@ elf64_alpha_check_relocs (bfd *abfd, str
if (need & NEED_GOT)
{
- if (!got_created)
+ if (alpha_elf_tdata(abfd)->gotobj == NULL)
{
if (!elf64_alpha_create_got_section (abfd, info))
return FALSE;
-
- /* Make sure the object's gotobj is set to itself so
- that we default to every object with its own .got.
- We'll merge .gots later once we've collected each
- object's info. */
- alpha_elf_tdata(abfd)->gotobj = abfd;
-
- got_created = 1;
}
}
--
Alan Modra
IBM OzLabs - Linux Technology Centre