/* IBM S/390-specific support for 32-bit ELF
- Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
Contributed by Carl B. Pedersen and Martin Schwidefsky.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
-#include "bfd.h"
#include "sysdep.h"
+#include "bfd.h"
#include "bfdlink.h"
#include "libbfd.h"
#include "elf-bfd.h"
#define elf_s390_hash_entry(ent) \
((struct elf_s390_link_hash_entry *)(ent))
+/* NOTE: Keep this structure in sync with
+ the one declared in elf64-s390.c. */
struct elf_s390_obj_tdata
{
struct elf_obj_tdata root;
- /* tls_type for each local got entry. */
+ /* TLS type for each local got entry. */
char *local_got_tls_type;
};
#define elf_s390_local_got_tls_type(abfd) \
(elf_s390_tdata (abfd)->local_got_tls_type)
+#define is_s390_elf(bfd) \
+ (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
+ && elf_tdata (bfd) != NULL \
+ && elf_object_id (bfd) == S390_ELF_TDATA)
+
static bfd_boolean
elf_s390_mkobject (bfd *abfd)
{
- if (abfd->tdata.any == NULL)
- {
- bfd_size_type amt = sizeof (struct elf_s390_obj_tdata);
- abfd->tdata.any = bfd_zalloc (abfd, amt);
- if (abfd->tdata.any == NULL)
- return FALSE;
- }
- return bfd_elf_mkobject (abfd);
+ return bfd_elf_allocate_object (abfd, sizeof (struct elf_s390_obj_tdata),
+ S390_ELF_TDATA);
}
static bfd_boolean
if (info->relocatable)
return TRUE;
+ BFD_ASSERT (is_s390_elf (abfd));
+
htab = elf_s390_hash_table (info);
- symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ symtab_hdr = &elf_symtab_hdr (abfd);
sym_hashes = elf_sym_hashes (abfd);
local_got_refcounts = elf_local_got_refcounts (abfd);
/* This relocation describes which C++ vtable entries are actually
used. Record for later use during GC. */
case R_390_GNU_VTENTRY:
- if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ BFD_ASSERT (h != NULL);
+ if (h != NULL
+ && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
return FALSE;
break;
bfd_signed_vma *local_got_refcounts;
const Elf_Internal_Rela *rel, *relend;
+ if (info->relocatable)
+ return TRUE;
+
elf_section_data (sec)->local_dynrel = NULL;
- symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
+ symtab_hdr = &elf_symtab_hdr (abfd);
sym_hashes = elf_sym_hashes (abfd);
local_got_refcounts = elf_local_got_refcounts (abfd);
{
struct elf_s390_link_hash_table *htab;
asection *s;
- unsigned int power_of_two;
/* If this is a function, put it in the procedure linkage table. We
will fill in the contents of the procedure linkage table later
h->needs_copy = 1;
}
- /* We need to figure out the alignment required for this symbol. I
- have no idea how ELF linkers handle this. */
- power_of_two = bfd_log2 (h->size);
- if (power_of_two > 3)
- power_of_two = 3;
-
- /* Apply the required alignment. */
s = htab->sdynbss;
- s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
- if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s))
- {
- if (! bfd_set_section_alignment (htab->elf.dynobj, s, power_of_two))
- return FALSE;
- }
- /* Define the symbol as being at this point in the section. */
- h->root.u.def.section = s;
- h->root.u.def.value = s->size;
-
- /* Increment the section size to make room for the symbol. */
- s->size += h->size;
-
- return TRUE;
+ return _bfd_elf_adjust_dynamic_copy (h, s);
}
/* Allocate space in .plt, .got and associated reloc sections for
Elf_Internal_Shdr *symtab_hdr;
asection *srela;
- if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
+ if (! is_s390_elf (ibfd))
continue;
for (s = ibfd->sections; s != NULL; s = s->next)
if (!local_got)
continue;
- symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
+ symtab_hdr = &elf_symtab_hdr (ibfd);
locsymcount = symtab_hdr->sh_info;
end_local_got = local_got + locsymcount;
local_tls_type = elf_s390_local_got_tls_type (ibfd);
Elf_Internal_Rela *rel;
Elf_Internal_Rela *relend;
+ BFD_ASSERT (is_s390_elf (input_bfd));
+
htab = elf_s390_hash_table (info);
- symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ symtab_hdr = &elf_symtab_hdr (input_bfd);
sym_hashes = elf_sym_hashes (input_bfd);
local_got_offsets = elf_local_got_offsets (input_bfd);