static boolean elf_s390_check_relocs
PARAMS ((bfd *, struct bfd_link_info *, asection *,
const Elf_Internal_Rela *));
+static asection *elf_s390_gc_mark_hook
+ PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *,
+ struct elf_link_hash_entry *, Elf_Internal_Sym *));
+static boolean elf_s390_gc_sweep_hook
+ PARAMS ((bfd *, struct bfd_link_info *, asection *,
+ const Elf_Internal_Rela *));
static boolean elf_s390_adjust_dynamic_symbol
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
static boolean elf_s390_size_dynamic_sections
Elf_Internal_Sym *));
static boolean elf_s390_finish_dynamic_sections
PARAMS ((bfd *, struct bfd_link_info *));
+static boolean elf_s390_object_p PARAMS ((bfd *));
+static enum elf_reloc_type_class elf_s390_reloc_type_class PARAMS ((int));
#define USE_RELA 1 /* We want RELA relocations, not REL. */
static reloc_howto_type elf64_s390_vtinherit_howto =
HOWTO (R_390_GNU_VTINHERIT, 0,4,0,false,0,complain_overflow_dont, NULL, "R_390_GNU_VTINHERIT", false,0, 0, false);
static reloc_howto_type elf64_s390_vtentry_howto =
- HOWTO (R_390_GNU_VTENTRY, 0,4,0,false,0,complain_overflow_dont, _bfd_elf_rel_vtable_reloc_fn,"R_390_GNU_VTENTRY", false,0,0, false);
+ HOWTO (R_390_GNU_VTENTRY, 0,4,0,false,0,complain_overflow_dont, _bfd_elf_rel_vtable_reloc_fn,"R_390_GNU_VTENTRY", false,0,0, false);
static reloc_howto_type *
elf_s390_reloc_type_lookup (abfd, code)
case BFD_RELOC_390_GOTENT:
return &elf_howto_table[(int) R_390_GOTENT];
default:
- break;
+ break;
}
return 0;
}
default:
BFD_ASSERT (ELF64_R_TYPE(dst->r_info) < (unsigned int) R_390_max);
cache_ptr->howto = &elf_howto_table[ELF64_R_TYPE(dst->r_info)];
- }
+ }
}
static boolean
/* The size in bytes of the first entry in the procedure linkage table. */
#define PLT_FIRST_ENTRY_SIZE 32
/* The size in bytes of an entry in the procedure linkage table. */
-#define PLT_ENTRY_SIZE 32
+#define PLT_ENTRY_SIZE 32
#define GOT_ENTRY_SIZE 8
are needed to load an address in a register and execute
a branch( or just saving the address)
- Furthermore, only r 0 and 1 are free to use!!! */
+ Furthermore, only r 0 and 1 are free to use!!! */
/* The first 3 words in the GOT are then reserved.
Word 0 is the address of the dynamic table.
The GOT holds the address in the PLT to be executed.
The loader then gets:
24(15) = Pointer to the structure describing the object.
- 28(15) = Offset in symbol table
+ 28(15) = Offset in symbol table
The loader must then find the module where the function is
and insert the address in the GOT.
the program that manages to have a symbol table of more than 2 GB with a
total size of at max 4 GB. */
-#define PLT_ENTRY_WORD0 0xc0100000
-#define PLT_ENTRY_WORD1 0x0000e310
-#define PLT_ENTRY_WORD2 0x10000004
-#define PLT_ENTRY_WORD3 0x07f10d10
-#define PLT_ENTRY_WORD4 0xe310100c
-#define PLT_ENTRY_WORD5 0x0014c0f4
-#define PLT_ENTRY_WORD6 0x00000000
-#define PLT_ENTRY_WORD7 0x00000000
+#define PLT_ENTRY_WORD0 (bfd_vma) 0xc0100000
+#define PLT_ENTRY_WORD1 (bfd_vma) 0x0000e310
+#define PLT_ENTRY_WORD2 (bfd_vma) 0x10000004
+#define PLT_ENTRY_WORD3 (bfd_vma) 0x07f10d10
+#define PLT_ENTRY_WORD4 (bfd_vma) 0xe310100c
+#define PLT_ENTRY_WORD5 (bfd_vma) 0x0014c0f4
+#define PLT_ENTRY_WORD6 (bfd_vma) 0x00000000
+#define PLT_ENTRY_WORD7 (bfd_vma) 0x00000000
/* The first PLT entry pushes the offset into the symbol table
from R1 onto the stack at 8(15) and the loader object info
Fixup at offset 8: relative address to start of GOT. */
-#define PLT_FIRST_ENTRY_WORD0 0xe310f038
-#define PLT_FIRST_ENTRY_WORD1 0x0024c010
-#define PLT_FIRST_ENTRY_WORD2 0x00000000
-#define PLT_FIRST_ENTRY_WORD3 0xd207f030
-#define PLT_FIRST_ENTRY_WORD4 0x1008e310
-#define PLT_FIRST_ENTRY_WORD5 0x10100004
-#define PLT_FIRST_ENTRY_WORD6 0x07f10700
-#define PLT_FIRST_ENTRY_WORD7 0x07000700
+#define PLT_FIRST_ENTRY_WORD0 (bfd_vma) 0xe310f038
+#define PLT_FIRST_ENTRY_WORD1 (bfd_vma) 0x0024c010
+#define PLT_FIRST_ENTRY_WORD2 (bfd_vma) 0x00000000
+#define PLT_FIRST_ENTRY_WORD3 (bfd_vma) 0xd207f030
+#define PLT_FIRST_ENTRY_WORD4 (bfd_vma) 0x1008e310
+#define PLT_FIRST_ENTRY_WORD5 (bfd_vma) 0x10100004
+#define PLT_FIRST_ENTRY_WORD6 (bfd_vma) 0x07f10700
+#define PLT_FIRST_ENTRY_WORD7 (bfd_vma) 0x07000700
/* The s390 linker needs to keep track of the number of relocs that it
decides to copy in check_relocs for each symbol. This is so that
bfd *abfd;
{
struct elf_s390_link_hash_table *ret;
+ bfd_size_type amt = sizeof (struct elf_s390_link_hash_table);
- ret = ((struct elf_s390_link_hash_table *)
- bfd_alloc (abfd, sizeof (struct elf_s390_link_hash_table)));
+ ret = ((struct elf_s390_link_hash_table *) bfd_alloc (abfd, amt));
if (ret == (struct elf_s390_link_hash_table *) NULL)
return NULL;
if (r_symndx < symtab_hdr->sh_info)
h = NULL;
else
- h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
/* Some relocs require a global offset table. */
if (dynobj == NULL)
if (! bfd_elf64_link_record_dynamic_symbol (info, h))
return false;
}
-
+
sgot->_raw_size += 8;
srelgot->_raw_size += sizeof (Elf64_External_Rela);
}
}
else
{
- /* This is a global offset table entry for a local symbol. */
+ /* This is a global offset table entry for a local symbol. */
if (local_got_refcounts == NULL)
{
- size_t size;
+ bfd_size_type size;
size = symtab_hdr->sh_info * sizeof (bfd_vma);
- local_got_refcounts = (bfd_signed_vma *)
- bfd_alloc (abfd, size);
+ local_got_refcounts = ((bfd_signed_vma *)
+ bfd_alloc (abfd, size));
if (local_got_refcounts == NULL)
return false;
elf_local_got_refcounts (abfd) = local_got_refcounts;
- memset (local_got_refcounts, -1, size);
+ memset (local_got_refcounts, -1, (size_t) size);
}
if (local_got_refcounts[r_symndx] == -1)
{
if (info->shared
&& (sec->flags & SEC_ALLOC) != 0
&& (ELF64_R_TYPE (rel->r_info) == R_390_8
- || ELF64_R_TYPE (rel->r_info) == R_390_16
+ || ELF64_R_TYPE (rel->r_info) == R_390_16
|| ELF64_R_TYPE (rel->r_info) == R_390_32
|| ELF64_R_TYPE (rel->r_info) == R_390_64
|| (h != NULL
|| ! bfd_set_section_alignment (dynobj, sreloc, 2))
return false;
}
+ if (sec->flags & SEC_READONLY)
+ info->flags |= DF_TEXTREL;
}
sreloc->_raw_size += sizeof (Elf64_External_Rela);
if (p == NULL)
{
p = ((struct elf_s390_pcrel_relocs_copied *)
- bfd_alloc (dynobj, sizeof *p));
+ bfd_alloc (dynobj, (bfd_size_type) sizeof *p));
if (p == NULL)
return false;
p->next = eh->pcrel_relocs_copied;
if (!_bfd_elf64_gc_record_vtentry (abfd, sec, h, rel->r_addend))
return false;
break;
-
+
default:
break;
}
static boolean
elf_s390_size_dynamic_sections (output_bfd, info)
- bfd *output_bfd;
+ bfd *output_bfd ATTRIBUTE_UNUSED;
struct bfd_link_info *info;
{
bfd *dynobj;
asection *s;
- boolean reltext;
boolean relocs;
boolean plt;
determined the sizes of the various dynamic sections. Allocate
memory for them. */
plt = false;
- reltext = false;
relocs = false;
for (s = dynobj->sections; s != NULL; s = s->next)
{
}
else
{
- asection *target;
-
/* Remember whether there are any reloc sections other
than .rela.plt. */
if (strcmp (name, ".rela.plt") != 0)
- {
- const char *outname;
-
- relocs = true;
-
- /* If this relocation section applies to a read only
- section, then we probably need a DT_TEXTREL
- entry. The entries in the .rela.plt section
- really apply to the .got section, which we
- created ourselves and so know is not readonly. */
- outname = bfd_get_section_name (output_bfd,
- s->output_section);
- target = bfd_get_section_by_name (output_bfd, outname + 5);
- if (target != NULL
- && (target->flags & SEC_READONLY) != 0
- && (target->flags & SEC_ALLOC) != 0)
- reltext = true;
- }
+ relocs = true;
/* We use the reloc_count field as a counter if we need
to copy relocs into the output file. */
must add the entries now so that we get the correct size for
the .dynamic section. The DT_DEBUG entry is filled in by the
dynamic linker and used by the debugger. */
+#define add_dynamic_entry(TAG, VAL) \
+ bfd_elf64_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
+
if (! info->shared)
{
- if (! bfd_elf64_add_dynamic_entry (info, DT_DEBUG, 0))
+ if (!add_dynamic_entry (DT_DEBUG, 0))
return false;
}
if (plt)
{
- if (! bfd_elf64_add_dynamic_entry (info, DT_PLTGOT, 0)
- || ! bfd_elf64_add_dynamic_entry (info, DT_PLTRELSZ, 0)
- || ! bfd_elf64_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
- || ! bfd_elf64_add_dynamic_entry (info, DT_JMPREL, 0))
+ if (!add_dynamic_entry (DT_PLTGOT, 0)
+ || !add_dynamic_entry (DT_PLTRELSZ, 0)
+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
+ || !add_dynamic_entry (DT_JMPREL, 0))
return false;
}
if (relocs)
{
- if (! bfd_elf64_add_dynamic_entry (info, DT_RELA, 0)
- || ! bfd_elf64_add_dynamic_entry (info, DT_RELASZ, 0)
- || ! bfd_elf64_add_dynamic_entry (info, DT_RELAENT,
- sizeof (Elf64_External_Rela)))
+ if (!add_dynamic_entry (DT_RELA, 0)
+ || !add_dynamic_entry (DT_RELASZ, 0)
+ || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela)))
return false;
}
- if (reltext)
+ if ((info->flags & DF_TEXTREL) != 0)
{
- if (! bfd_elf64_add_dynamic_entry (info, DT_TEXTREL, 0))
+ if (!add_dynamic_entry (DT_TEXTREL, 0))
return false;
info->flags |= DF_TEXTREL;
}
}
+#undef add_dynamic_entry
return true;
}
{
if (! ((*info->callbacks->undefined_symbol)
(info, h->root.root.string, input_bfd,
- input_section, rel->r_offset,
- (!info->shared || info->no_undefined
+ input_section, rel->r_offset,
+ (!info->shared || info->no_undefined
|| ELF_ST_VISIBILITY (h->other)))))
return false;
relocation = 0;
relocation += sgot->output_section->vma;
break;
-
+
case R_390_GOTOFF:
/* Relocation is relative to the start of the global offset
table. */
}
else if (r_type == R_390_PC16 ||
r_type == R_390_PC16DBL ||
- r_type == R_390_PC32 ||
+ r_type == R_390_PC32 ||
r_type == R_390_PC32DBL ||
r_type == R_390_PC64)
{
srela = bfd_get_section_by_name (dynobj, ".rela.plt");
BFD_ASSERT (splt != NULL && sgot != NULL && srela != NULL);
- /* Calc. index no.
+ /* Calc. index no.
Current offset - size first entry / entry size. */
plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) / PLT_ENTRY_SIZE;
rela.r_offset = (sgot->output_section->vma
+ sgot->output_offset
- + (h->got.offset &~ 1));
+ + (h->got.offset &~ (bfd_vma) 1));
/* If this is a static link, or it is a -Bsymbolic link and the
symbol is defined locally or was forced to be local because
splt->contents + 8);
}
- elf_section_data (splt->output_section)->this_hdr.sh_entsize =
+ elf_section_data (splt->output_section)->this_hdr.sh_entsize =
PLT_ENTRY_SIZE;
}
return bfd_default_set_arch_mach (abfd, bfd_arch_s390, bfd_mach_s390_esame);
}
+
+static enum elf_reloc_type_class
+elf_s390_reloc_type_class (type)
+ int type;
+{
+ switch (type)
+ {
+ case R_390_RELATIVE:
+ return reloc_class_relative;
+ case R_390_JMP_SLOT:
+ return reloc_class_plt;
+ case R_390_COPY:
+ return reloc_class_copy;
+ default:
+ return reloc_class_normal;
+ }
+}
+
/*
* Why was the hash table entry size definition changed from
* ARCH_SIZE/8 to 4? This breaks the 64 bit dynamic linker and
#define elf_backend_gc_sweep_hook elf_s390_gc_sweep_hook
#define elf_backend_relocate_section elf_s390_relocate_section
#define elf_backend_size_dynamic_sections elf_s390_size_dynamic_sections
+#define elf_backend_reloc_type_class elf_s390_reloc_type_class
#define elf_backend_object_p elf_s390_object_p