// s390.cc -- s390 target support for gold.

// Copyright (C) 2015-2018 Free Software Foundation, Inc.
// Written by Marcin Kościelnicki <koriakin@0x04.net>.

// This file is part of gold.

// 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 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
// MA 02110-1301, USA.

#include "gold.h"

#include <cstring>

#include "elfcpp.h"
#include "dwarf.h"
#include "parameters.h"
#include "reloc.h"
#include "s390.h"
#include "object.h"
#include "symtab.h"
#include "layout.h"
#include "output.h"
#include "copy-relocs.h"
#include "target.h"
#include "target-reloc.h"
#include "target-select.h"
#include "tls.h"
#include "gc.h"
#include "icf.h"

namespace
{

using namespace gold;

// A class to handle the .got.plt section.

template<int size>
class Output_data_got_plt_s390 : public Output_section_data_build
{
 public:
  Output_data_got_plt_s390(Layout* layout)
    : Output_section_data_build(size/8),
      layout_(layout)
  { }

  Output_data_got_plt_s390(Layout* layout, off_t data_size)
    : Output_section_data_build(data_size, size/8),
      layout_(layout)
  { }

 protected:
  // Write out the PLT data.
  void
  do_write(Output_file*);

  // Write to a map file.
  void
  do_print_to_mapfile(Mapfile* mapfile) const
  { mapfile->print_output_data(this, "** GOT PLT"); }

 private:
  // A pointer to the Layout class, so that we can find the .dynamic
  // section when we write out the GOT PLT section.
  Layout* layout_;
};

// A class to handle the PLT data.

template<int size>
class Output_data_plt_s390 : public Output_section_data
{
 public:
  typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, true>
    Reloc_section;

  Output_data_plt_s390(Layout* layout,
                         Output_data_got<size, true>* got,
                         Output_data_got_plt_s390<size>* got_plt,
                         Output_data_space* got_irelative)
    : Output_section_data(4), layout_(layout),
      irelative_rel_(NULL), got_(got), got_plt_(got_plt),
      got_irelative_(got_irelative), count_(0),
      irelative_count_(0), free_list_()
  { this->init(layout); }

  Output_data_plt_s390(Layout* layout,
                         Output_data_got<size, true>* got,
                         Output_data_got_plt_s390<size>* got_plt,
                         Output_data_space* got_irelative,
                         unsigned int plt_count)
    : Output_section_data((plt_count + 1) * plt_entry_size,
                          4, false),
      layout_(layout), irelative_rel_(NULL), got_(got),
      got_plt_(got_plt), got_irelative_(got_irelative), count_(plt_count),
      irelative_count_(0), free_list_()
  {
    this->init(layout);

    // Initialize the free list and reserve the first entry.
    this->free_list_.init((plt_count + 1) * plt_entry_size, false);
    this->free_list_.remove(0, plt_entry_size);
  }

  // Initialize the PLT section.
  void
  init(Layout* layout);

  // Add an entry to the PLT.
  void
  add_entry(Symbol_table*, Layout*, Symbol* gsym);

  // Add an entry to the PLT for a local STT_GNU_IFUNC symbol.
  unsigned int
  add_local_ifunc_entry(Symbol_table*, Layout*,
    Sized_relobj_file<size, true>*, unsigned int);

  // Add the relocation for a PLT entry.
  void
  add_relocation(Symbol_table*, Layout*, Symbol*, unsigned int);

  // Return the .rela.plt section data.
  Reloc_section*
  rela_plt()
  { return this->rel_; }

  // Return where the IRELATIVE relocations should go in the PLT
  // relocations.
  Reloc_section*
  rela_irelative(Symbol_table*, Layout*);

  // Return whether we created a section for IRELATIVE relocations.
  bool
  has_irelative_section() const
  { return this->irelative_rel_ != NULL; }

  // Return the number of PLT entries.
  unsigned int
  entry_count() const
  { return this->count_ + this->irelative_count_; }

  // Return the offset of the first non-reserved PLT entry.
  unsigned int
  first_plt_entry_offset()
  { return plt_entry_size; }

  // Return the size of a PLT entry.
  unsigned int
  get_plt_entry_size() const
  { return plt_entry_size; }

  // Reserve a slot in the PLT for an existing symbol in an incremental update.
  void
  reserve_slot(unsigned int plt_index)
  {
    this->free_list_.remove((plt_index + 1) * plt_entry_size,
                            (plt_index + 2) * plt_entry_size);
  }

  // Return the PLT address to use for a global symbol.
  uint64_t
  address_for_global(const Symbol*);

  // Return the PLT address to use for a local symbol.
  uint64_t
  address_for_local(const Relobj*, unsigned int symndx);

  // Add .eh_frame information for the PLT.
  void
  add_eh_frame(Layout* layout)
  {
	  (void)layout;
    layout->add_eh_frame_for_plt(this,
				 plt_eh_frame_cie,
				 plt_eh_frame_cie_size,
				 plt_eh_frame_fde,
				 plt_eh_frame_fde_size);
  }

 protected:
  // Fill in the first PLT entry.
  void
  fill_first_plt_entry(unsigned char* pov,
		       typename elfcpp::Elf_types<size>::Elf_Addr got_address,
		       typename elfcpp::Elf_types<size>::Elf_Addr plt_address);

  // Fill in a normal PLT entry.  Returns the offset into the entry that
  // should be the initial GOT slot value.
  unsigned int
  fill_plt_entry(unsigned char* pov,
		 typename elfcpp::Elf_types<size>::Elf_Addr got_address,
		 typename elfcpp::Elf_types<size>::Elf_Addr plt_address,
		 unsigned int got_offset,
		 unsigned int plt_offset,
		 unsigned int plt_rel_offset);

  void
  do_adjust_output_section(Output_section* os);

  // Write to a map file.
  void
  do_print_to_mapfile(Mapfile* mapfile) const
  { mapfile->print_output_data(this, _("** PLT")); }

 private:
  // Set the final size.
  void
  set_final_data_size();

  // Write out the PLT data.
  void
  do_write(Output_file*);

  // A pointer to the Layout class, so that we can find the .dynamic
  // section when we write out the GOT PLT section.
  Layout* layout_;
  // The reloc section.
  Reloc_section* rel_;
  // The IRELATIVE relocs, if necessary.  These must follow the
  // regular PLT relocations.
  Reloc_section* irelative_rel_;
  // The .got section.
  Output_data_got<size, true>* got_;
  // The .got.plt section.
  Output_data_got_plt_s390<size>* got_plt_;
  // The part of the .got.plt section used for IRELATIVE relocs.
  Output_data_space* got_irelative_;
  // The number of PLT entries.
  unsigned int count_;
  // Number of PLT entries with R_TILEGX_IRELATIVE relocs.  These
  // follow the regular PLT entries.
  unsigned int irelative_count_;
  // List of available regions within the section, for incremental
  // update links.
  Free_list free_list_;

  // The size of an entry in the PLT.
  static const int plt_entry_size = 0x20;
  // The first entry in the PLT.
  static const unsigned char first_plt_entry_32_abs[plt_entry_size];
  static const unsigned char first_plt_entry_32_pic[plt_entry_size];
  static const unsigned char first_plt_entry_64[plt_entry_size];
  // Other entries in the PLT for an executable.
  static const unsigned char plt_entry_32_abs[plt_entry_size];
  static const unsigned char plt_entry_32_pic12[plt_entry_size];
  static const unsigned char plt_entry_32_pic16[plt_entry_size];
  static const unsigned char plt_entry_32_pic[plt_entry_size];
  static const unsigned char plt_entry_64[plt_entry_size];

  // The .eh_frame unwind information for the PLT.
  static const int plt_eh_frame_cie_size = 12;
  static const unsigned char plt_eh_frame_cie[plt_eh_frame_cie_size];
  static const int plt_eh_frame_fde_size = 12;
  static const unsigned char plt_eh_frame_fde[plt_eh_frame_fde_size];
};


template<int size>
class Target_s390 : public Sized_target<size, true>
{
 public:
  typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, true> Reloc_section;

  Target_s390()
    : Sized_target<size, true>(&s390_info),
      got_(NULL), plt_(NULL), got_plt_(NULL), got_irelative_(NULL),
      global_offset_table_(NULL), rela_dyn_(NULL),
      rela_irelative_(NULL), copy_relocs_(elfcpp::R_390_COPY),
      got_mod_index_offset_(-1U), tls_base_symbol_defined_(false),
      layout_(NULL)
  { }

  // Scan the relocations to look for symbol adjustments.
  void
  gc_process_relocs(Symbol_table* symtab,
		    Layout* layout,
		    Sized_relobj_file<size, true>* object,
		    unsigned int data_shndx,
		    unsigned int sh_type,
		    const unsigned char* prelocs,
		    size_t reloc_count,
		    Output_section* output_section,
		    bool needs_special_offset_handling,
		    size_t local_symbol_count,
		    const unsigned char* plocal_symbols);

  // Scan the relocations to look for symbol adjustments.
  void
  scan_relocs(Symbol_table* symtab,
	      Layout* layout,
	      Sized_relobj_file<size, true>* object,
	      unsigned int data_shndx,
	      unsigned int sh_type,
	      const unsigned char* prelocs,
	      size_t reloc_count,
	      Output_section* output_section,
	      bool needs_special_offset_handling,
	      size_t local_symbol_count,
	      const unsigned char* plocal_symbols);

  // Finalize the sections.
  void
  do_finalize_sections(Layout*, const Input_objects*, Symbol_table*);

  // Return the value to use for a dynamic which requires special
  // treatment.
  uint64_t
  do_dynsym_value(const Symbol*) const;

  // Relocate a section.
  void
  relocate_section(const Relocate_info<size, true>*,
		   unsigned int sh_type,
		   const unsigned char* prelocs,
		   size_t reloc_count,
		   Output_section* output_section,
		   bool needs_special_offset_handling,
		   unsigned char* view,
		   typename elfcpp::Elf_types<size>::Elf_Addr view_address,
		   section_size_type view_size,
		   const Reloc_symbol_changes*);

  // Scan the relocs during a relocatable link.
  void
  scan_relocatable_relocs(Symbol_table* symtab,
			  Layout* layout,
			  Sized_relobj_file<size, true>* object,
			  unsigned int data_shndx,
			  unsigned int sh_type,
			  const unsigned char* prelocs,
			  size_t reloc_count,
			  Output_section* output_section,
			  bool needs_special_offset_handling,
			  size_t local_symbol_count,
			  const unsigned char* plocal_symbols,
			  Relocatable_relocs*);

  // Scan the relocs for --emit-relocs.
  void
  emit_relocs_scan(Symbol_table* symtab,
		   Layout* layout,
		   Sized_relobj_file<size, true>* object,
		   unsigned int data_shndx,
		   unsigned int sh_type,
		   const unsigned char* prelocs,
		   size_t reloc_count,
		   Output_section* output_section,
		   bool needs_special_offset_handling,
		   size_t local_symbol_count,
		   const unsigned char* plocal_syms,
		   Relocatable_relocs* rr);

  // Return a string used to fill a code section with nops.
  std::string
  do_code_fill(section_size_type length) const;

  // Emit relocations for a section.
  void
  relocate_relocs(
      const Relocate_info<size, true>*,
      unsigned int sh_type,
      const unsigned char* prelocs,
      size_t reloc_count,
      Output_section* output_section,
      typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
      unsigned char* view,
      typename elfcpp::Elf_types<size>::Elf_Addr view_address,
      section_size_type view_size,
      unsigned char* reloc_view,
      section_size_type reloc_view_size);

  // Return whether SYM is defined by the ABI.
  bool
  do_is_defined_by_abi(const Symbol* sym) const
  { return strcmp(sym->name(), "__tls_get_offset") == 0; }

  // Return the PLT address to use for a global symbol.
  uint64_t
  do_plt_address_for_global(const Symbol* gsym) const
  { return this->plt_section()->address_for_global(gsym); }

  uint64_t
  do_plt_address_for_local(const Relobj* relobj, unsigned int symndx) const
  { return this->plt_section()->address_for_local(relobj, symndx); }

  // Return the offset to use for the GOT_INDX'th got entry which is
  // for a local tls symbol specified by OBJECT, SYMNDX.
  int64_t
  do_tls_offset_for_local(const Relobj* object,
			  unsigned int symndx,
			  unsigned int got_indx) const;

  // Return the offset to use for the GOT_INDX'th got entry which is
  // for global tls symbol GSYM.
  int64_t
  do_tls_offset_for_global(Symbol* gsym, unsigned int got_indx) const;

  // This function should be defined in targets that can use relocation
  // types to determine (implemented in local_reloc_may_be_function_pointer
  // and global_reloc_may_be_function_pointer)
  // if a function's pointer is taken.  ICF uses this in safe mode to only
  // fold those functions whose pointer is defintely not taken.
  bool
  do_can_check_for_function_pointers() const
  { return true; }

  // Return whether SYM is call to a non-split function.
  bool
  do_is_call_to_non_split(const Symbol* sym, const unsigned char* preloc,
			  const unsigned char* view,
			  section_size_type view_size) const;

  // Adjust -fsplit-stack code which calls non-split-stack code.
  void
  do_calls_non_split(Relobj* object, unsigned int shndx,
		     section_offset_type fnoffset, section_size_type fnsize,
		     const unsigned char* prelocs, size_t reloc_count,
		     unsigned char* view, section_size_type view_size,
		     std::string* from, std::string* to) const;

  // Return the size of the GOT section.
  section_size_type
  got_size() const
  {
    gold_assert(this->got_ != NULL);
    return this->got_->data_size();
  }

  // Return the number of entries in the GOT.
  unsigned int
  got_entry_count() const
  {
    if (this->got_ == NULL)
      return 0;
    return this->got_size() / (size / 8);
  }

  // Return the number of entries in the PLT.
  unsigned int
  plt_entry_count() const;

  // Return the offset of the first non-reserved PLT entry.
  unsigned int
  first_plt_entry_offset() const;

  // Return the size of each PLT entry.
  unsigned int
  plt_entry_size() const;

  // Create the GOT section for an incremental update.
  Output_data_got_base*
  init_got_plt_for_update(Symbol_table* symtab,
			  Layout* layout,
			  unsigned int got_count,
			  unsigned int plt_count);

  // Reserve a GOT entry for a local symbol, and regenerate any
  // necessary dynamic relocations.
  void
  reserve_local_got_entry(unsigned int got_index,
			  Sized_relobj<size, true>* obj,
			  unsigned int r_sym,
			  unsigned int got_type);

  // Reserve a GOT entry for a global symbol, and regenerate any
  // necessary dynamic relocations.
  void
  reserve_global_got_entry(unsigned int got_index, Symbol* gsym,
			   unsigned int got_type);

  // Register an existing PLT entry for a global symbol.
  void
  register_global_plt_entry(Symbol_table*, Layout*, unsigned int plt_index,
			    Symbol* gsym);

  // Force a COPY relocation for a given symbol.
  void
  emit_copy_reloc(Symbol_table*, Symbol*, Output_section*, off_t);

  // Apply an incremental relocation.
  void
  apply_relocation(const Relocate_info<size, true>* relinfo,
		   typename elfcpp::Elf_types<size>::Elf_Addr r_offset,
		   unsigned int r_type,
		   typename elfcpp::Elf_types<size>::Elf_Swxword r_addend,
		   const Symbol* gsym,
		   unsigned char* view,
		   typename elfcpp::Elf_types<size>::Elf_Addr address,
		   section_size_type view_size);

 private:

  // The class which scans relocations.
  class Scan
  {
  public:
    Scan()
      : issued_non_pic_error_(false)
    { }

    static inline int
    get_reference_flags(unsigned int r_type);

    inline void
    local(Symbol_table* symtab, Layout* layout, Target_s390* target,
	  Sized_relobj_file<size, true>* object,
	  unsigned int data_shndx,
	  Output_section* output_section,
	  const elfcpp::Rela<size, true>& reloc, unsigned int r_type,
	  const elfcpp::Sym<size, true>& lsym,
	  bool is_discarded);

    inline void
    global(Symbol_table* symtab, Layout* layout, Target_s390* target,
	   Sized_relobj_file<size, true>* object,
	   unsigned int data_shndx,
	   Output_section* output_section,
	   const elfcpp::Rela<size, true>& reloc, unsigned int r_type,
	   Symbol* gsym);

    inline bool
    local_reloc_may_be_function_pointer(Symbol_table* symtab, Layout* layout,
					Target_s390* target,
					Sized_relobj_file<size, true>* object,
					unsigned int data_shndx,
					Output_section* output_section,
					const elfcpp::Rela<size, true>& reloc,
					unsigned int r_type,
					const elfcpp::Sym<size, true>& lsym);

    inline bool
    global_reloc_may_be_function_pointer(Symbol_table* symtab, Layout* layout,
					 Target_s390* target,
					 Sized_relobj_file<size, true>* object,
					 unsigned int data_shndx,
					 Output_section* output_section,
					 const elfcpp::Rela<size, true>& reloc,
					 unsigned int r_type,
					 Symbol* gsym);

  private:
    static void
    unsupported_reloc_local(Sized_relobj_file<size, true>*,
			    unsigned int r_type);

    static void
    unsupported_reloc_global(Sized_relobj_file<size, true>*,
			     unsigned int r_type, Symbol*);

    void
    check_non_pic(Relobj*, unsigned int r_type);

    inline bool
    possible_function_pointer_reloc(unsigned int r_type);

    bool
    reloc_needs_plt_for_ifunc(Sized_relobj_file<size, true>*,
			      unsigned int r_type);

    // Whether we have issued an error about a non-PIC compilation.
    bool issued_non_pic_error_;
  };

  // The class which implements relocation.
  class Relocate
  {
   public:
    // Do a relocation.  Return false if the caller should not issue
    // any warnings about this relocation.
    inline bool
    relocate(const Relocate_info<size, true>*, unsigned int,
	     Target_s390*, Output_section*, size_t, const unsigned char*,
	     const Sized_symbol<size>*, const Symbol_value<size>*,
	     unsigned char*, typename elfcpp::Elf_types<size>::Elf_Addr,
	     section_size_type);

   private:
    // Do a TLS relocation.
    inline typename elfcpp::Elf_types<size>::Elf_Addr
    relocate_tls(const Relocate_info<size, true>*, Target_s390*,
		 size_t relnum, const elfcpp::Rela<size, true>&,
		 unsigned int r_type, const Sized_symbol<size>*,
		 const Symbol_value<size>*,
		 unsigned char*, section_size_type);

    // Do a TLS General-Dynamic to Initial-Exec transition.
    inline void
    tls_gd_to_ie(const Relocate_info<size, true>*, size_t relnum,
		 const elfcpp::Rela<size, true>&,
		 unsigned char* view,
		 section_size_type view_size);

    // Do a TLS General-Dynamic to Local-Exec transition.
    inline void
    tls_gd_to_le(const Relocate_info<size, true>*, size_t relnum,
		 const elfcpp::Rela<size, true>&,
		 unsigned char* view,
		 section_size_type view_size);

    // Do a TLS Local-Dynamic to Local-Exec transition.
    inline void
    tls_ld_to_le(const Relocate_info<size, true>*, size_t relnum,
		 const elfcpp::Rela<size, true>&,
		 unsigned char* view,
		 section_size_type view_size);

    // Do a TLS Initial-Exec to Local-Exec transition.
    static inline void
    tls_ie_to_le(const Relocate_info<size, true>*, size_t relnum,
		 const elfcpp::Rela<size, true>&,
		 unsigned char* view,
		 section_size_type view_size);
  };

  // Adjust TLS relocation type based on the options and whether this
  // is a local symbol.
  static tls::Tls_optimization
  optimize_tls_reloc(bool is_final, int r_type);

  // Get the GOT section.
  const Output_data_got<size, true>*
  got_section() const
  {
    gold_assert(this->got_ != NULL);
    return this->got_;
  }

  // Get the GOT section, creating it if necessary.
  Output_data_got<size, true>*
  got_section(Symbol_table*, Layout*);

  typename elfcpp::Elf_types<size>::Elf_Addr
  got_address() const
  {
    gold_assert(this->got_ != NULL);
    return this->got_plt_->address();
  }

  typename elfcpp::Elf_types<size>::Elf_Addr
  got_main_offset() const
  {
    gold_assert(this->got_ != NULL);
    return this->got_->address() - this->got_address();
  }

  // Create the PLT section.
  void
  make_plt_section(Symbol_table* symtab, Layout* layout);

  // Create a PLT entry for a global symbol.
  void
  make_plt_entry(Symbol_table*, Layout*, Symbol*);

  // Create a PLT entry for a local STT_GNU_IFUNC symbol.
  void
  make_local_ifunc_plt_entry(Symbol_table*, Layout*,
			     Sized_relobj_file<size, true>* relobj,
			     unsigned int local_sym_index);

  // Create a GOT entry for the TLS module index.
  unsigned int
  got_mod_index_entry(Symbol_table* symtab, Layout* layout,
		      Sized_relobj_file<size, true>* object);

  // Get the PLT section.
  Output_data_plt_s390<size>*
  plt_section() const
  {
    gold_assert(this->plt_ != NULL);
    return this->plt_;
  }

  // Get the dynamic reloc section, creating it if necessary.
  Reloc_section*
  rela_dyn_section(Layout*);

  // Get the section to use for IRELATIVE relocations.
  Reloc_section*
  rela_irelative_section(Layout*);

  // Add a potential copy relocation.
  void
  copy_reloc(Symbol_table* symtab, Layout* layout,
	     Sized_relobj_file<size, true>* object,
	     unsigned int shndx, Output_section* output_section,
	     Symbol* sym, const elfcpp::Rela<size, true>& reloc)
  {
    unsigned int r_type = elfcpp::elf_r_type<size>(reloc.get_r_info());
    this->copy_relocs_.copy_reloc(symtab, layout,
				  symtab->get_sized_symbol<size>(sym),
				  object, shndx, output_section,
				  r_type, reloc.get_r_offset(),
				  reloc.get_r_addend(),
				  this->rela_dyn_section(layout));
  }

  // A function for targets to call.  Return whether BYTES/LEN matches
  // VIEW/VIEW_SIZE at OFFSET.  Like the one in Target, but takes
  // an unsigned char * parameter.
  bool
  match_view_u(const unsigned char* view, section_size_type view_size,
     section_offset_type offset, const unsigned char* bytes, size_t len) const
    {
      return this->match_view(view, view_size, offset,
			      reinterpret_cast<const char*>(bytes), len);
    }

  // Information about this specific target which we pass to the
  // general Target structure.
  static Target::Target_info s390_info;

  // The types of GOT entries needed for this platform.
  // These values are exposed to the ABI in an incremental link.
  // Do not renumber existing values without changing the version
  // number of the .gnu_incremental_inputs section.
  enum Got_type
  {
    GOT_TYPE_STANDARD = 0,      // GOT entry for a regular symbol
    GOT_TYPE_TLS_OFFSET = 1,    // GOT entry for TLS offset
    GOT_TYPE_TLS_PAIR = 2,      // GOT entry for TLS module/offset pair
  };

  // The GOT section.
  Output_data_got<size, true>* got_;
  // The PLT section.
  Output_data_plt_s390<size>* plt_;
  // The GOT PLT section.
  Output_data_got_plt_s390<size>* got_plt_;
  // The GOT section for IRELATIVE relocations.
  Output_data_space* got_irelative_;
  // The _GLOBAL_OFFSET_TABLE_ symbol.
  Symbol* global_offset_table_;
  // The dynamic reloc section.
  Reloc_section* rela_dyn_;
  // The section to use for IRELATIVE relocs.
  Reloc_section* rela_irelative_;
  // Relocs saved to avoid a COPY reloc.
  Copy_relocs<elfcpp::SHT_RELA, size, true> copy_relocs_;
  // Offset of the GOT entry for the TLS module index.
  unsigned int got_mod_index_offset_;
  // True if the _TLS_MODULE_BASE_ symbol has been defined.
  bool tls_base_symbol_defined_;
  // For use in do_tls_offset_for_*
  Layout *layout_;

  // Code sequences for -fsplit-stack matching.
  static const unsigned char ss_code_bras_8[];
  static const unsigned char ss_code_l_basr[];
  static const unsigned char ss_code_a_basr[];
  static const unsigned char ss_code_larl[];
  static const unsigned char ss_code_brasl[];
  static const unsigned char ss_code_jg[];
  static const unsigned char ss_code_jgl[];

  // Variable code sequence matchers for -fsplit-stack.
  bool ss_match_st_r14(unsigned char* view,
		       section_size_type view_size,
		       section_offset_type *offset) const;
  bool ss_match_l_r14(unsigned char* view,
		      section_size_type view_size,
		      section_offset_type *offset) const;
  bool ss_match_mcount(unsigned char* view,
		       section_size_type view_size,
		       section_offset_type *offset) const;
  bool ss_match_ear(unsigned char* view,
		    section_size_type view_size,
		    section_offset_type *offset) const;
  bool ss_match_c(unsigned char* view,
		  section_size_type view_size,
		  section_offset_type *offset) const;
  bool ss_match_l(unsigned char* view,
		  section_size_type view_size,
		  section_offset_type *offset,
		  int *guard_reg) const;
  bool ss_match_ahi(unsigned char* view,
		    section_size_type view_size,
		    section_offset_type *offset,
		    int guard_reg,
		    uint32_t *arg) const;
  bool ss_match_alfi(unsigned char* view,
		     section_size_type view_size,
		     section_offset_type *offset,
		     int guard_reg,
		     uint32_t *arg) const;
  bool ss_match_cr(unsigned char* view,
		   section_size_type view_size,
		   section_offset_type *offset,
		   int guard_reg) const;
};

template<>
Target::Target_info Target_s390<32>::s390_info =
{
  32,			// size
  true,			// is_big_endian
  elfcpp::EM_S390,	// machine_code
  false,		// has_make_symbol
  false,		// has_resolve
  true,			// has_code_fill
  true,			// is_default_stack_executable
  true,			// can_icf_inline_merge_sections
  '\0',			// wrap_char
  "/lib/ld.so.1",	// dynamic_linker
  0x00400000,		// default_text_segment_address
  4 * 1024,		// abi_pagesize (overridable by -z max-page-size)
  4 * 1024,		// common_pagesize (overridable by -z common-page-size)
  false,                // isolate_execinstr
  0,                    // rosegment_gap
  elfcpp::SHN_UNDEF,	// small_common_shndx
  elfcpp::SHN_UNDEF,	// large_common_shndx
  0,			// small_common_section_flags
  0,			// large_common_section_flags
  NULL,			// attributes_section
  NULL,			// attributes_vendor
  "_start",		// entry_symbol_name
  32,			// hash_entry_size
};

template<>
Target::Target_info Target_s390<64>::s390_info =
{
  64,			// size
  true,			// is_big_endian
  elfcpp::EM_S390,	// machine_code
  false,		// has_make_symbol
  false,		// has_resolve
  true,			// has_code_fill
  true,			// is_default_stack_executable
  true,			// can_icf_inline_merge_sections
  '\0',			// wrap_char
  "/lib/ld64.so.1",	// dynamic_linker
  0x80000000ll,		// default_text_segment_address
  4 * 1024,		// abi_pagesize (overridable by -z max-page-size)
  4 * 1024,		// common_pagesize (overridable by -z common-page-size)
  false,                // isolate_execinstr
  0,                    // rosegment_gap
  elfcpp::SHN_UNDEF,	// small_common_shndx
  elfcpp::SHN_UNDEF,	// large_common_shndx
  0,			// small_common_section_flags
  0,			// large_common_section_flags
  NULL,			// attributes_section
  NULL,			// attributes_vendor
  "_start",		// entry_symbol_name
  64,			// hash_entry_size
};

template<int size>
class S390_relocate_functions
{
public:
  enum Overflow_check
  {
    CHECK_NONE,
    CHECK_SIGNED,
    CHECK_UNSIGNED,
    CHECK_BITFIELD,
    CHECK_LOW_INSN,
    CHECK_HIGH_INSN
  };

  enum Status
  {
    STATUS_OK,
    STATUS_OVERFLOW
  };

private:
  typedef S390_relocate_functions<size> This;
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;

  template<int valsize>
  static inline bool
  has_overflow_signed(Address value)
  {
    // limit = 1 << (valsize - 1) without shift count exceeding size of type
    Address limit = static_cast<Address>(1) << ((valsize - 1) >> 1);
    limit <<= ((valsize - 1) >> 1);
    limit <<= ((valsize - 1) - 2 * ((valsize - 1) >> 1));
    return value + limit > (limit << 1) - 1;
  }

  template<int valsize>
  static inline bool
  has_overflow_unsigned(Address value)
  {
    Address limit = static_cast<Address>(1) << ((valsize - 1) >> 1);
    limit <<= ((valsize - 1) >> 1);
    limit <<= ((valsize - 1) - 2 * ((valsize - 1) >> 1));
    return value > (limit << 1) - 1;
  }

  template<int fieldsize>
  static inline void
  rela(unsigned char* view, Address mask, Address value)
  {
    typedef typename elfcpp::Swap<fieldsize, true>::Valtype Valtype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Valtype val = elfcpp::Swap<fieldsize, true>::readval(view);
    val &= ~mask;
    value &= mask;
    elfcpp::Swap<fieldsize, true>::writeval(wv, val | value);
  }

public:
  // R_390_12, R_390_GOT12, R_390_GOTPLT12, R_390_GOTIE12
  static inline Status
  rela12(unsigned char* view, Address value)
  {
    if (This::template has_overflow_unsigned<12>(value))
      return STATUS_OVERFLOW;
    This::template rela<16>(view, 0x0fff, value);
    return STATUS_OK;
  }

  // R_390_16, R_390_GOT16, R_390_GOTPLT16, R_390_GOTOFF16, R_390_PLTOFF16
  static inline Status
  rela16(unsigned char* view, Address value)
  {
    if (This::template has_overflow_signed<16>(value))
      return STATUS_OVERFLOW;
    This::template rela<16>(view, 0xffff, value);
    return STATUS_OK;
  }

  // R_390_20, R_390_GOT20, R_390_GOTPLT20, R_390_GOTIE20
  static inline Status
  rela20(unsigned char* view, Address value)
  {
    if (This::template has_overflow_signed<20>(value))
      return STATUS_OVERFLOW;
    This::template rela<16>(view, 0x0fff, value);
    This::template rela<16>(view + 2, 0xff00, value >> (12 - 8));
    return STATUS_OK;
  }

  // R_390_PC12DBL, R_390_PLT12DBL
  static inline Status
  pcrela12dbl(unsigned char* view, Address value, Address address)
  {
    value -= address;
    if ((value & 1) != 0)
      return STATUS_OVERFLOW;
    if (This::template has_overflow_signed<13>(value))
      return STATUS_OVERFLOW;
    value >>= 1;
    This::template rela<16>(view, 0x0fff, value);
    return STATUS_OK;
  }

  // R_390_PC16DBL, R_390_PLT16DBL
  static inline Status
  pcrela16dbl(unsigned char* view, Address value, Address address)
  {
    value -= address;
    if ((value & 1) != 0)
      return STATUS_OVERFLOW;
    if (This::template has_overflow_signed<17>(value))
      return STATUS_OVERFLOW;
    value >>= 1;
    This::template rela<16>(view, 0xffff, value);
    return STATUS_OK;
  }

  // R_390_PC24DBL, R_390_PLT24DBL
  static inline Status
  pcrela24dbl(unsigned char* view, Address value, Address address)
  {
    value -= address;
    if ((value & 1) != 0)
      return STATUS_OVERFLOW;
    if (This::template has_overflow_signed<25>(value))
      return STATUS_OVERFLOW;
    value >>= 1;
    // Swap doesn't take 24-bit fields well...
    This::template rela<8>(view, 0xff, value >> 16);
    This::template rela<16>(view + 1, 0xffff, value);
    return STATUS_OK;
  }

  // R_390_PC32DBL, R_390_PLT32DBL, R_390_GOTPCDBL, R_390_GOTENT, R_390_GOTPLTENT
  static inline Status
  pcrela32dbl(unsigned char* view, Address value, Address address)
  {
    Address reloc = value - address;
    if ((reloc & 1) != 0)
      {
	gold_warning(_("R_390_PC32DBL target misaligned at %llx"), (long long)address);
	// Wait for a fix for https://sourceware.org/bugzilla/show_bug.cgi?id=18960
	// return STATUS_OVERFLOW;
      }
    if (This::template has_overflow_signed<33>(reloc))
      return STATUS_OVERFLOW;
    reloc >>= 1;
    if (value < address && size == 32)
      reloc |= 0x80000000;
    This::template rela<32>(view, 0xffffffff, reloc);
    return STATUS_OK;
  }

};

// Initialize the PLT section.

template<int size>
void
Output_data_plt_s390<size>::init(Layout* layout)
{
  this->rel_ = new Reloc_section(false);
  layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA,
				  elfcpp::SHF_ALLOC, this->rel_,
				  ORDER_DYNAMIC_PLT_RELOCS, false);
}

template<int size>
void
Output_data_plt_s390<size>::do_adjust_output_section(Output_section* os)
{
  os->set_entsize(plt_entry_size);
}

// Add an entry to the PLT.

template<int size>
void
Output_data_plt_s390<size>::add_entry(Symbol_table* symtab, Layout* layout,
					Symbol* gsym)
{
  gold_assert(!gsym->has_plt_offset());

  unsigned int plt_index;
  off_t plt_offset;
  section_offset_type got_offset;

  unsigned int* pcount;
  unsigned int offset;
  unsigned int reserved;
  Output_section_data_build* got;
  if (gsym->type() == elfcpp::STT_GNU_IFUNC
      && gsym->can_use_relative_reloc(false))
    {
      pcount = &this->irelative_count_;
      offset = 0;
      reserved = 0;
      got = this->got_irelative_;
    }
  else
    {
      pcount = &this->count_;
      offset = 1;
      reserved = 3;
      got = this->got_plt_;
    }

  if (!this->is_data_size_valid())
    {
      // Note that when setting the PLT offset for a non-IRELATIVE
      // entry we skip the initial reserved PLT entry.
      plt_index = *pcount + offset;
      plt_offset = plt_index * plt_entry_size;

      ++*pcount;

      got_offset = (plt_index - offset + reserved) * size / 8;
      gold_assert(got_offset == got->current_data_size());

      // Every PLT entry needs a GOT entry which points back to the PLT
      // entry (this will be changed by the dynamic linker, normally
      // lazily when the function is called).
      got->set_current_data_size(got_offset + size / 8);
    }
  else
    {
      // FIXME: This is probably not correct for IRELATIVE relocs.

      // For incremental updates, find an available slot.
      plt_offset = this->free_list_.allocate(plt_entry_size,
					     plt_entry_size, 0);
      if (plt_offset == -1)
	gold_fallback(_("out of patch space (PLT);"
			" relink with --incremental-full"));

      // The GOT and PLT entries have a 1-1 correspondance, so the GOT offset
      // can be calculated from the PLT index, adjusting for the three
      // reserved entries at the beginning of the GOT.
      plt_index = plt_offset / plt_entry_size - 1;
      got_offset = (plt_index - offset + reserved) * size / 8;
    }

  gsym->set_plt_offset(plt_offset);

  // Every PLT entry needs a reloc.
  this->add_relocation(symtab, layout, gsym, got_offset);

  // Note that we don't need to save the symbol.  The contents of the
  // PLT are independent of which symbols are used.  The symbols only
  // appear in the relocations.
}

// Add an entry to the PLT for a local STT_GNU_IFUNC symbol.  Return
// the PLT offset.

template<int size>
unsigned int
Output_data_plt_s390<size>::add_local_ifunc_entry(
    Symbol_table* symtab,
    Layout* layout,
    Sized_relobj_file<size, true>* relobj,
    unsigned int local_sym_index)
{
  unsigned int plt_offset = this->irelative_count_ * plt_entry_size;
  ++this->irelative_count_;

  section_offset_type got_offset = this->got_irelative_->current_data_size();

  // Every PLT entry needs a GOT entry which points back to the PLT
  // entry.
  this->got_irelative_->set_current_data_size(got_offset + size / 8);

  // Every PLT entry needs a reloc.
  Reloc_section* rela = this->rela_irelative(symtab, layout);
  rela->add_symbolless_local_addend(relobj, local_sym_index,
				    elfcpp::R_390_IRELATIVE,
				    this->got_irelative_, got_offset, 0);

  return plt_offset;
}

// Add the relocation for a PLT entry.

template<int size>
void
Output_data_plt_s390<size>::add_relocation(Symbol_table* symtab,
					     Layout* layout,
					     Symbol* gsym,
					     unsigned int got_offset)
{
  if (gsym->type() == elfcpp::STT_GNU_IFUNC
      && gsym->can_use_relative_reloc(false))
    {
      Reloc_section* rela = this->rela_irelative(symtab, layout);
      rela->add_symbolless_global_addend(gsym, elfcpp::R_390_IRELATIVE,
					 this->got_irelative_, got_offset, 0);
    }
  else
    {
      gsym->set_needs_dynsym_entry();
      this->rel_->add_global(gsym, elfcpp::R_390_JMP_SLOT, this->got_plt_,
			     got_offset, 0);
    }
}

// Return where the IRELATIVE relocations should go in the PLT.  These
// follow the JUMP_SLOT and the TLSDESC relocations.

template<int size>
typename Output_data_plt_s390<size>::Reloc_section*
Output_data_plt_s390<size>::rela_irelative(Symbol_table* symtab,
					     Layout* layout)
{
  if (this->irelative_rel_ == NULL)
    {
      this->irelative_rel_ = new Reloc_section(false);
      layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA,
				      elfcpp::SHF_ALLOC, this->irelative_rel_,
				      ORDER_DYNAMIC_PLT_RELOCS, false);
      gold_assert(this->irelative_rel_->output_section()
		  == this->rel_->output_section());

      if (parameters->doing_static_link())
	{
	  // A statically linked executable will only have a .rela.plt
	  // section to hold R_390_IRELATIVE relocs for
	  // STT_GNU_IFUNC symbols.  The library will use these
	  // symbols to locate the IRELATIVE relocs at program startup
	  // time.
	  symtab->define_in_output_data("__rela_iplt_start", NULL,
					Symbol_table::PREDEFINED,
					this->irelative_rel_, 0, 0,
					elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
					elfcpp::STV_HIDDEN, 0, false, true);
	  symtab->define_in_output_data("__rela_iplt_end", NULL,
					Symbol_table::PREDEFINED,
					this->irelative_rel_, 0, 0,
					elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
					elfcpp::STV_HIDDEN, 0, true, true);
	}
    }
  return this->irelative_rel_;
}

// Return the PLT address to use for a global symbol.

template<int size>
uint64_t
Output_data_plt_s390<size>::address_for_global(const Symbol* gsym)
{
  uint64_t offset = 0;
  if (gsym->type() == elfcpp::STT_GNU_IFUNC
      && gsym->can_use_relative_reloc(false))
    offset = (this->count_ + 1) * plt_entry_size;
  return this->address() + offset + gsym->plt_offset();
}

// Return the PLT address to use for a local symbol.  These are always
// IRELATIVE relocs.

template<int size>
uint64_t
Output_data_plt_s390<size>::address_for_local(const Relobj* object,
						unsigned int r_sym)
{
  return (this->address()
	  + (this->count_ + 1) * plt_entry_size
	  + object->local_plt_offset(r_sym));
}

// Set the final size.
template<int size>
void
Output_data_plt_s390<size>::set_final_data_size()
{
  unsigned int count = this->count_ + this->irelative_count_;
  this->set_data_size((count + 1) * plt_entry_size);
}

template<int size>
const unsigned char
Output_data_plt_s390<size>::first_plt_entry_32_abs[plt_entry_size] =
{
  0x50, 0x10, 0xf0, 0x1c, // st %r1, 28(%r15)
  0x0d, 0x10, // basr %r1, %r0
  0x58, 0x10, 0x10, 0x12, // l %r1, 18(%r1)
  0xd2, 0x03, 0xf0, 0x18, 0x10, 0x04, // mvc 24(4,%r15), 4(%r1)
  0x58, 0x10, 0x10, 0x08, // l %r1, 8(%r1)
  0x07, 0xf1, // br %r1
  0x00, 0x00, // padding
  0x00, 0x00, 0x00, 0x00, // _GLOBAL_OFFSET_TABLE_ (to fill)
  0x00, 0x00, 0x00, 0x00, // padding
};

template<int size>
const unsigned char
Output_data_plt_s390<size>::first_plt_entry_32_pic[plt_entry_size] =
{
  0x50, 0x10, 0xf0, 0x1c, // st %r1, 28(%r15)
  0x58, 0x10, 0xc0, 0x04, // l %r1, 4(%r12)
  0x50, 0x10, 0xf0, 0x18, // st %r1, 24(%r15)
  0x58, 0x10, 0xc0, 0x08, // l %r1, 8(%r12)
  0x07, 0xf1, // br %r1
  0x00, 0x00, // padding
  0x00, 0x00, 0x00, 0x00, // padding
  0x00, 0x00, 0x00, 0x00, // padding
  0x00, 0x00, 0x00, 0x00, // padding
};

template<int size>
const unsigned char
Output_data_plt_s390<size>::first_plt_entry_64[plt_entry_size] =
{
  0xe3, 0x10, 0xf0, 0x38, 0x00, 0x24, // stg %r1, 56(%r15)
  0xc0, 0x10, 0x00, 0x00, 0x00, 0x00, // larl %r1, _GLOBAL_OFFSET_TABLE_ (to fill)
  0xd2, 0x07, 0xf0, 0x30, 0x10, 0x08, // mvc 48(8,%r15), 8(%r1)
  0xe3, 0x10, 0x10, 0x10, 0x00, 0x04, // lg %r1, 16(%r1)
  0x07, 0xf1, // br %r1
  0x07, 0x00, // nopr
  0x07, 0x00, // nopr
  0x07, 0x00, // nopr
};

template<int size>
void
Output_data_plt_s390<size>::fill_first_plt_entry(
    unsigned char* pov,
    typename elfcpp::Elf_types<size>::Elf_Addr got_address,
    typename elfcpp::Elf_types<size>::Elf_Addr plt_address)
{
  if (size == 64)
    {
      memcpy(pov, first_plt_entry_64, plt_entry_size);
      S390_relocate_functions<size>::pcrela32dbl(pov + 8, got_address, (plt_address + 6));
    }
  else if (!parameters->options().output_is_position_independent())
    {
      memcpy(pov, first_plt_entry_32_abs, plt_entry_size);
      elfcpp::Swap<32, true>::writeval(pov + 24, got_address);
    }
  else
    {
      memcpy(pov, first_plt_entry_32_pic, plt_entry_size);
    }
}

template<int size>
const unsigned char
Output_data_plt_s390<size>::plt_entry_32_abs[plt_entry_size] =
{
  // first part
  0x0d, 0x10, // basr %r1, %r0
  0x58, 0x10, 0x10, 0x16, // l %r1, 22(%r1)
  0x58, 0x10, 0x10, 0x00, // l %r1, 0(%r1)
  0x07, 0xf1, // br %r1
  // second part
  0x0d, 0x10, // basr %r1, %r0
  0x58, 0x10, 0x10, 0x0e, // l %r1, 14(%r1)
  0xa7, 0xf4, 0x00, 0x00, // j first_plt_entry (to fill)
  0x00, 0x00, // padding
  0x00, 0x00, 0x00, 0x00, // _GLOBAL_OFFSET_TABLE_+sym@gotplt (to fill)
  0x00, 0x00, 0x00, 0x00, // offset of relocation in .rela.plt (to fill)
};

template<int size>
const unsigned char
Output_data_plt_s390<size>::plt_entry_32_pic12[plt_entry_size] =
{
  // first part
  0x58, 0x10, 0xc0, 0x00, // l %r1, sym@gotplt(%r12) (to fill)
  0x07, 0xf1, // br %r1
  0x00, 0x00, // padding
  0x00, 0x00, 0x00, 0x00, // padding
  // second part
  0x0d, 0x10, // basr %r1, %r0
  0x58, 0x10, 0x10, 0x0e, // l %r1, 14(%r1)
  0xa7, 0xf4, 0x00, 0x00, // j first_plt_entry (to fill)
  0x00, 0x00, // padding
  0x00, 0x00, 0x00, 0x00, // padding
  0x00, 0x00, 0x00, 0x00, // offset of relocation in .rela.plt (to fill)
};

template<int size>
const unsigned char
Output_data_plt_s390<size>::plt_entry_32_pic16[plt_entry_size] =
{
  // first part
  0xa7, 0x18, 0x00, 0x00, // lhi %r1, sym@gotplt (to fill)
  0x58, 0x11, 0xc0, 0x00, // l %r1, 0(%r1, %r12)
  0x07, 0xf1, // br %r1
  0x00, 0x00, // padding
  // second part
  0x0d, 0x10, // basr %r1, %r0
  0x58, 0x10, 0x10, 0x0e, // l %r1, 14(%r1)
  0xa7, 0xf4, 0x00, 0x00, // j first_plt_entry (to fill)
  0x00, 0x00, // padding
  0x00, 0x00, 0x00, 0x00, // padding
  0x00, 0x00, 0x00, 0x00, // offset of relocation in .rela.plt (to fill)
};

template<int size>
const unsigned char
Output_data_plt_s390<size>::plt_entry_32_pic[plt_entry_size] =
{
  // first part
  0x0d, 0x10, // basr %r1, %r0
  0x58, 0x10, 0x10, 0x16, // l %r1, 22(%r1)
  0x58, 0x11, 0xc0, 0x00, // l %r1, 0(%r1, %r12)
  0x07, 0xf1, // br %r1
  // second part
  0x0d, 0x10, // basr %r1, %r0
  0x58, 0x10, 0x10, 0x0e, // l %r1, 14(%r1)
  0xa7, 0xf4, 0x00, 0x00, // j first_plt_entry (to fill)
  0x00, 0x00, // padding
  0x00, 0x00, 0x00, 0x00, // sym@gotplt (to fill)
  0x00, 0x00, 0x00, 0x00, // offset of relocation in .rela.plt (to fill)
};

template<int size>
const unsigned char
Output_data_plt_s390<size>::plt_entry_64[plt_entry_size] =
{
  // first part
  0xc0, 0x10, 0x00, 0x00, 0x00, 0x00, // larl %r1, _GLOBAL_OFFSET_TABLE_+off (to fill)
  0xe3, 0x10, 0x10, 0x00, 0x00, 0x04, // lg %r1, 0(%r1)
  0x07, 0xf1, // br %r1
  // second part
  0x0d, 0x10, // basr %r1, %r0
  0xe3, 0x10, 0x10, 0x0c, 0x00, 0x14, // lgf %r1, 12(%r1)
  0xc0, 0xf4, 0x00, 0x00, 0x00, 0x00, // jg first_plt_entry (to fill)
  0x00, 0x00, 0x00, 0x00, // offset of relocation in .rela.plt (to fill)
};

template<int size>
unsigned int
Output_data_plt_s390<size>::fill_plt_entry(
    unsigned char* pov,
    typename elfcpp::Elf_types<size>::Elf_Addr got_address,
    typename elfcpp::Elf_types<size>::Elf_Addr plt_address,
    unsigned int got_offset,
    unsigned int plt_offset,
    unsigned int plt_rel_offset)
{
  if (size == 64)
  {
    memcpy(pov, plt_entry_64, plt_entry_size);
    S390_relocate_functions<size>::pcrela32dbl(pov + 2, got_address + got_offset, plt_address + plt_offset);
    S390_relocate_functions<size>::pcrela32dbl(pov + 24, plt_address, plt_address + plt_offset + 22);
  }
  else
  {
    if (!parameters->options().output_is_position_independent())
      {
	memcpy(pov, plt_entry_32_abs, plt_entry_size);
	elfcpp::Swap<32, true>::writeval(pov + 24, got_address + got_offset);
      }
    else
      {
	if (got_offset < 0x1000)
	  {
	    memcpy(pov, plt_entry_32_pic12, plt_entry_size);
	    S390_relocate_functions<size>::rela12(pov + 2, got_offset);
	  }
	else if (got_offset < 0x8000)
	  {
	    memcpy(pov, plt_entry_32_pic16, plt_entry_size);
	    S390_relocate_functions<size>::rela16(pov + 2, got_offset);
	  }
	else
	  {
	    memcpy(pov, plt_entry_32_pic, plt_entry_size);
	    elfcpp::Swap<32, true>::writeval(pov + 24, got_offset);
	  }
      }
    typename elfcpp::Elf_types<size>::Elf_Addr target = plt_address;
    if (plt_offset >= 0x10000)
      {
	// Would overflow pcrela16dbl - aim at the farthest previous jump
	// we can reach.
	if (plt_offset > 0x10000)
	  {
	    // Use the full range of pcrel16dbl.
	    target = plt_address + plt_offset - 0x10000 + 18;
	  }
	else
	  {
	    // if plt_offset is exactly 0x10000, the above would aim at 18th byte
	    // of first_plt_entry, which doesn't have the jump back like the others.
	    // Aim at the next entry instead.
	    target = plt_address + plt_offset - 0xffe0 + 18;
	  }
      }
    S390_relocate_functions<size>::pcrela16dbl(pov + 20, target, plt_address + plt_offset + 18);
  }
  elfcpp::Swap<32, true>::writeval(pov + 28, plt_rel_offset);
  if (size == 64)
    return 14;
  else
    return 12;
}

// The .eh_frame unwind information for the PLT.

template<>
const unsigned char
Output_data_plt_s390<32>::plt_eh_frame_cie[plt_eh_frame_cie_size] =
{
  1,				// CIE version.
  'z',				// Augmentation: augmentation size included.
  'R',				// Augmentation: FDE encoding included.
  '\0',				// End of augmentation string.
  1,				// Code alignment factor.
  0x7c,				// Data alignment factor.
  14,				// Return address column.
  1,				// Augmentation size.
  (elfcpp::DW_EH_PE_pcrel	// FDE encoding.
   | elfcpp::DW_EH_PE_sdata4),
  elfcpp::DW_CFA_def_cfa, 15, 0x60,	// DW_CFA_def_cfa: r15 ofs 0x60.
};

template<>
const unsigned char
Output_data_plt_s390<64>::plt_eh_frame_cie[plt_eh_frame_cie_size] =
{
  1,				// CIE version.
  'z',				// Augmentation: augmentation size included.
  'R',				// Augmentation: FDE encoding included.
  '\0',				// End of augmentation string.
  1,				// Code alignment factor.
  0x78,				// Data alignment factor.
  14,				// Return address column.
  1,				// Augmentation size.
  (elfcpp::DW_EH_PE_pcrel	// FDE encoding.
   | elfcpp::DW_EH_PE_sdata4),
  elfcpp::DW_CFA_def_cfa, 15, 0xa0,	// DW_CFA_def_cfa: r15 ofs 0xa0.
};

template<int size>
const unsigned char
Output_data_plt_s390<size>::plt_eh_frame_fde[plt_eh_frame_fde_size] =
{
  0, 0, 0, 0,				// Replaced with offset to .plt.
  0, 0, 0, 0,				// Replaced with size of .plt.
  0,					// Augmentation size.
  elfcpp::DW_CFA_nop,
  elfcpp::DW_CFA_nop,
  elfcpp::DW_CFA_nop
};

// Write out the PLT.  This uses the hand-coded instructions above,
// and adjusts them as needed.

template<int size>
void
Output_data_plt_s390<size>::do_write(Output_file* of)
{
  const off_t offset = this->offset();
  const section_size_type oview_size =
    convert_to_section_size_type(this->data_size());
  unsigned char* const oview = of->get_output_view(offset, oview_size);

  const off_t got_file_offset = this->got_plt_->offset();
  gold_assert(parameters->incremental_update()
	      || (got_file_offset + this->got_plt_->data_size()
		  == this->got_irelative_->offset()));
  const section_size_type got_size =
    convert_to_section_size_type(this->got_plt_->data_size()
				 + this->got_irelative_->data_size());
  unsigned char* const got_view = of->get_output_view(got_file_offset,
						      got_size);

  unsigned char* pov = oview;

  // The base address of the .plt section.
  typename elfcpp::Elf_types<size>::Elf_Addr plt_address = this->address();
  // The base address of the PLT portion of the .got section,
  // which is where the GOT pointer will point, and where the
  // three reserved GOT entries are located.
  typename elfcpp::Elf_types<size>::Elf_Addr got_address
    = this->got_plt_->address();

  this->fill_first_plt_entry(pov, got_address, plt_address);
  pov += this->get_plt_entry_size();

  unsigned char* got_pov = got_view;

  const int rel_size = elfcpp::Elf_sizes<size>::rela_size;

  unsigned int plt_offset = this->get_plt_entry_size();
  unsigned int plt_rel_offset = 0;
  unsigned int got_offset = 3 * size / 8;
  const unsigned int count = this->count_ + this->irelative_count_;
  // The first three entries in the GOT are reserved, and are written
  // by Output_data_got_plt_s390::do_write.
  got_pov += 3 * size / 8;

  for (unsigned int plt_index = 0;
       plt_index < count;
       ++plt_index,
	 pov += plt_entry_size,
	 got_pov += size / 8,
	 plt_offset += plt_entry_size,
	 plt_rel_offset += rel_size,
	 got_offset += size / 8)
    {
      // Set and adjust the PLT entry itself.
      unsigned int lazy_offset = this->fill_plt_entry(pov,
						      got_address, plt_address,
						      got_offset, plt_offset,
						      plt_rel_offset);

      // Set the entry in the GOT.
      elfcpp::Swap<size, true>::writeval(got_pov,
					plt_address + plt_offset + lazy_offset);
    }

  gold_assert(static_cast<section_size_type>(pov - oview) == oview_size);
  gold_assert(static_cast<section_size_type>(got_pov - got_view) == got_size);

  of->write_output_view(offset, oview_size, oview);
  of->write_output_view(got_file_offset, got_size, got_view);
}

// Get the GOT section, creating it if necessary.

template<int size>
Output_data_got<size, true>*
Target_s390<size>::got_section(Symbol_table* symtab, Layout* layout)
{
  if (this->got_ == NULL)
    {
      gold_assert(symtab != NULL && layout != NULL);

      // When using -z now, we can treat .got as a relro section.
      // Without -z now, it is modified after program startup by lazy
      // PLT relocations.
      bool is_got_relro = parameters->options().now();
      Output_section_order got_order = (is_got_relro
					? ORDER_RELRO_LAST
					: ORDER_DATA);

      // The old GNU linker creates a .got.plt section.  We just
      // create another set of data in the .got section.  Note that we
      // always create a PLT if we create a GOT, although the PLT
      // might be empty.
      this->got_plt_ = new Output_data_got_plt_s390<size>(layout);
      layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
				      (elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE),
				      this->got_plt_, got_order, is_got_relro);

      // The first three entries are reserved.
      this->got_plt_->set_current_data_size(3 * size / 8);

      // If there are any IRELATIVE relocations, they get GOT entries
      // in .got.plt after the jump slot entries.
      this->got_irelative_ = new Output_data_space(size / 8, "** GOT IRELATIVE PLT");
      layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
				      (elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE),
				      this->got_irelative_,
				      got_order, is_got_relro);

      // Unlike some targets (.e.g x86), S/390 does not use separate .got and
      // .got.plt sections in output.  The output .got section contains both
      // PLT and non-PLT GOT entries.
      this->got_ = new Output_data_got<size, true>();

      layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
				      (elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE),
				      this->got_, got_order, is_got_relro);

      // Define _GLOBAL_OFFSET_TABLE_ at the start of the GOT.
      this->global_offset_table_ =
        symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
				      Symbol_table::PREDEFINED,
				      this->got_plt_,
				      0, 0, elfcpp::STT_OBJECT,
				      elfcpp::STB_LOCAL,
				      elfcpp::STV_HIDDEN, 0,
				      false, false);

    }
  return this->got_;
}

// Get the dynamic reloc section, creating it if necessary.

template<int size>
typename Target_s390<size>::Reloc_section*
Target_s390<size>::rela_dyn_section(Layout* layout)
{
  if (this->rela_dyn_ == NULL)
    {
      gold_assert(layout != NULL);
      this->rela_dyn_ = new Reloc_section(parameters->options().combreloc());
      layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA,
				      elfcpp::SHF_ALLOC, this->rela_dyn_,
				      ORDER_DYNAMIC_RELOCS, false);
    }
  return this->rela_dyn_;
}

// Get the section to use for IRELATIVE relocs, creating it if
// necessary.  These go in .rela.dyn, but only after all other dynamic
// relocations.  They need to follow the other dynamic relocations so
// that they can refer to global variables initialized by those
// relocs.

template<int size>
typename Target_s390<size>::Reloc_section*
Target_s390<size>::rela_irelative_section(Layout* layout)
{
  if (this->rela_irelative_ == NULL)
    {
      // Make sure we have already created the dynamic reloc section.
      this->rela_dyn_section(layout);
      this->rela_irelative_ = new Reloc_section(false);
      layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA,
				      elfcpp::SHF_ALLOC, this->rela_irelative_,
				      ORDER_DYNAMIC_RELOCS, false);
      gold_assert(this->rela_dyn_->output_section()
		  == this->rela_irelative_->output_section());
    }
  return this->rela_irelative_;
}

// Write the first three reserved words of the .got.plt section.
// The remainder of the section is written while writing the PLT
// in Output_data_plt_s390::do_write.

template<int size>
void
Output_data_got_plt_s390<size>::do_write(Output_file* of)
{
  // The first entry in the GOT is the address of the .dynamic section
  // aka the PT_DYNAMIC segment.  The next two entries are reserved.
  // We saved space for them when we created the section in
  // Target_x86_64::got_section.
  const off_t got_file_offset = this->offset();
  gold_assert(this->data_size() >= 3 * size / 8);
  unsigned char* const got_view =
      of->get_output_view(got_file_offset, 3 * size / 8);
  Output_section* dynamic = this->layout_->dynamic_section();
  uint64_t dynamic_addr = dynamic == NULL ? 0 : dynamic->address();
  elfcpp::Swap<size, true>::writeval(got_view, dynamic_addr);
  memset(got_view + size / 8, 0, 2 * size / 8);
  of->write_output_view(got_file_offset, 3 * size / 8, got_view);
}

// Create the PLT section.

template<int size>
void
Target_s390<size>::make_plt_section(Symbol_table* symtab, Layout* layout)
{
  if (this->plt_ == NULL)
    {
      // Create the GOT sections first.
      this->got_section(symtab, layout);

      // Ensure that .rela.dyn always appears before .rela.plt  This is
      // necessary due to how, on 32-bit S/390 and some other targets,
      // .rela.dyn needs to include .rela.plt in it's range.
      this->rela_dyn_section(layout);

      this->plt_ = new Output_data_plt_s390<size>(layout,
		      this->got_, this->got_plt_, this->got_irelative_);

      // Add unwind information if requested.
      if (parameters->options().ld_generated_unwind_info())
	this->plt_->add_eh_frame(layout);

      layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS,
				      (elfcpp::SHF_ALLOC
				       | elfcpp::SHF_EXECINSTR),
				      this->plt_, ORDER_PLT, false);

      // Make the sh_info field of .rela.plt point to .plt.
      Output_section* rela_plt_os = this->plt_->rela_plt()->output_section();
      rela_plt_os->set_info_section(this->plt_->output_section());
    }
}

// Create a PLT entry for a global symbol.

template<int size>
void
Target_s390<size>::make_plt_entry(Symbol_table* symtab, Layout* layout,
				    Symbol* gsym)
{
  if (gsym->has_plt_offset())
    return;

  if (this->plt_ == NULL)
    this->make_plt_section(symtab, layout);

  this->plt_->add_entry(symtab, layout, gsym);
}

// Make a PLT entry for a local STT_GNU_IFUNC symbol.

template<int size>
void
Target_s390<size>::make_local_ifunc_plt_entry(
    Symbol_table* symtab, Layout* layout,
    Sized_relobj_file<size, true>* relobj,
    unsigned int local_sym_index)
{
  if (relobj->local_has_plt_offset(local_sym_index))
    return;
  if (this->plt_ == NULL)
    this->make_plt_section(symtab, layout);
  unsigned int plt_offset = this->plt_->add_local_ifunc_entry(symtab, layout,
							      relobj,
							      local_sym_index);
  relobj->set_local_plt_offset(local_sym_index, plt_offset);
}

// Return the number of entries in the PLT.

template<int size>
unsigned int
Target_s390<size>::plt_entry_count() const
{
  if (this->plt_ == NULL)
    return 0;
  return this->plt_->entry_count();
}

// Return the offset of the first non-reserved PLT entry.

template<int size>
unsigned int
Target_s390<size>::first_plt_entry_offset() const
{
  return this->plt_->first_plt_entry_offset();
}

// Return the size of each PLT entry.

template<int size>
unsigned int
Target_s390<size>::plt_entry_size() const
{
  return this->plt_->get_plt_entry_size();
}

// Create the GOT and PLT sections for an incremental update.

template<int size>
Output_data_got_base*
Target_s390<size>::init_got_plt_for_update(Symbol_table* symtab,
				       Layout* layout,
				       unsigned int got_count,
				       unsigned int plt_count)
{
  gold_assert(this->got_ == NULL);

  // Add the three reserved entries.
  this->got_plt_ = new Output_data_got_plt_s390<size>(layout, (plt_count + 3) * size / 8);
  layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
				  (elfcpp::SHF_ALLOC
				   | elfcpp::SHF_WRITE),
				  this->got_plt_, ORDER_NON_RELRO_FIRST,
				  false);

  // If there are any IRELATIVE relocations, they get GOT entries in
  // .got.plt after the jump slot entries.
  this->got_irelative_ = new Output_data_space(0, size / 8, "** GOT IRELATIVE PLT");
  layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
				  elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE,
				  this->got_irelative_,
				  ORDER_NON_RELRO_FIRST, false);

  this->got_ = new Output_data_got<size, true>(got_count * size / 8);
  layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
				  (elfcpp::SHF_ALLOC
				   | elfcpp::SHF_WRITE),
				  this->got_, ORDER_RELRO_LAST,
				  true);

  // Define _GLOBAL_OFFSET_TABLE_ at the start of the PLT.
  this->global_offset_table_ =
    symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
				  Symbol_table::PREDEFINED,
				  this->got_plt_,
				  0, 0, elfcpp::STT_OBJECT,
				  elfcpp::STB_LOCAL,
				  elfcpp::STV_HIDDEN, 0,
				  false, false);

  // Create the PLT section.
  this->plt_ = new Output_data_plt_s390<size>(layout,
		  this->got_, this->got_plt_, this->got_irelative_, plt_count);

  // Add unwind information if requested.
  if (parameters->options().ld_generated_unwind_info())
    this->plt_->add_eh_frame(layout);

  layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS,
				  elfcpp::SHF_ALLOC | elfcpp::SHF_EXECINSTR,
				  this->plt_, ORDER_PLT, false);

  // Make the sh_info field of .rela.plt point to .plt.
  Output_section* rela_plt_os = this->plt_->rela_plt()->output_section();
  rela_plt_os->set_info_section(this->plt_->output_section());

  // Create the rela_dyn section.
  this->rela_dyn_section(layout);

  return this->got_;
}

// Reserve a GOT entry for a local symbol, and regenerate any
// necessary dynamic relocations.

template<int size>
void
Target_s390<size>::reserve_local_got_entry(
    unsigned int got_index,
    Sized_relobj<size, true>* obj,
    unsigned int r_sym,
    unsigned int got_type)
{
  unsigned int got_offset = got_index * size / 8;
  Reloc_section* rela_dyn = this->rela_dyn_section(NULL);

  this->got_->reserve_local(got_index, obj, r_sym, got_type);
  switch (got_type)
    {
    case GOT_TYPE_STANDARD:
      if (parameters->options().output_is_position_independent())
	rela_dyn->add_local_relative(obj, r_sym, elfcpp::R_390_RELATIVE,
				     this->got_, got_offset, 0, false);
      break;
    case GOT_TYPE_TLS_OFFSET:
      rela_dyn->add_local(obj, r_sym, elfcpp::R_390_TLS_TPOFF,
			  this->got_, got_offset, 0);
      break;
    case GOT_TYPE_TLS_PAIR:
      this->got_->reserve_slot(got_index + 1);
      rela_dyn->add_local(obj, r_sym, elfcpp::R_390_TLS_DTPMOD,
			  this->got_, got_offset, 0);
      break;
    default:
      gold_unreachable();
    }
}

// Reserve a GOT entry for a global symbol, and regenerate any
// necessary dynamic relocations.

template<int size>
void
Target_s390<size>::reserve_global_got_entry(unsigned int got_index,
					      Symbol* gsym,
					      unsigned int got_type)
{
  unsigned int got_offset = got_index * size / 8;
  Reloc_section* rela_dyn = this->rela_dyn_section(NULL);

  this->got_->reserve_global(got_index, gsym, got_type);
  switch (got_type)
    {
    case GOT_TYPE_STANDARD:
      if (!gsym->final_value_is_known())
	{
	  if (gsym->is_from_dynobj()
	      || gsym->is_undefined()
	      || gsym->is_preemptible()
	      || gsym->type() == elfcpp::STT_GNU_IFUNC)
	    rela_dyn->add_global(gsym, elfcpp::R_390_GLOB_DAT,
				 this->got_, got_offset, 0);
	  else
	    rela_dyn->add_global_relative(gsym, elfcpp::R_390_RELATIVE,
					  this->got_, got_offset, 0, false);
	}
      break;
    case GOT_TYPE_TLS_OFFSET:
      rela_dyn->add_global_relative(gsym, elfcpp::R_390_TLS_TPOFF,
				    this->got_, got_offset, 0, false);
      break;
    case GOT_TYPE_TLS_PAIR:
      this->got_->reserve_slot(got_index + 1);
      rela_dyn->add_global_relative(gsym, elfcpp::R_390_TLS_DTPMOD,
				    this->got_, got_offset, 0, false);
      rela_dyn->add_global_relative(gsym, elfcpp::R_390_TLS_DTPOFF,
				    this->got_, got_offset + size / 8, 0, false);
      break;
    default:
      gold_unreachable();
    }
}

// Register an existing PLT entry for a global symbol.

template<int size>
void
Target_s390<size>::register_global_plt_entry(Symbol_table* symtab,
					       Layout* layout,
					       unsigned int plt_index,
					       Symbol* gsym)
{
  gold_assert(this->plt_ != NULL);
  gold_assert(!gsym->has_plt_offset());

  this->plt_->reserve_slot(plt_index);

  gsym->set_plt_offset((plt_index + 1) * this->plt_entry_size());

  unsigned int got_offset = (plt_index + 3) * size / 8;
  this->plt_->add_relocation(symtab, layout, gsym, got_offset);
}

// Force a COPY relocation for a given symbol.

template<int size>
void
Target_s390<size>::emit_copy_reloc(
    Symbol_table* symtab, Symbol* sym, Output_section* os, off_t offset)
{
  this->copy_relocs_.emit_copy_reloc(symtab,
				     symtab->get_sized_symbol<size>(sym),
				     os,
				     offset,
				     this->rela_dyn_section(NULL));
}

// Create a GOT entry for the TLS module index.

template<int size>
unsigned int
Target_s390<size>::got_mod_index_entry(Symbol_table* symtab, Layout* layout,
					 Sized_relobj_file<size, true>* object)
{
  if (this->got_mod_index_offset_ == -1U)
    {
      gold_assert(symtab != NULL && layout != NULL && object != NULL);
      Reloc_section* rela_dyn = this->rela_dyn_section(layout);
      Output_data_got<size, true>* got = this->got_section(symtab, layout);
      unsigned int got_offset = got->add_constant(0);
      rela_dyn->add_local(object, 0, elfcpp::R_390_TLS_DTPMOD, got,
			  got_offset, 0);
      got->add_constant(0);
      this->got_mod_index_offset_ = got_offset;
    }
  return this->got_mod_index_offset_;
}

// Optimize the TLS relocation type based on what we know about the
// symbol.  IS_FINAL is true if the final address of this symbol is
// known at link time.

template<int size>
tls::Tls_optimization
Target_s390<size>::optimize_tls_reloc(bool is_final, int r_type)
{
  // If we are generating a shared library, then we can't do anything
  // in the linker.
  if (parameters->options().shared())
    return tls::TLSOPT_NONE;

  switch (r_type)
    {
    case elfcpp::R_390_TLS_GD32:
    case elfcpp::R_390_TLS_GD64:
    case elfcpp::R_390_TLS_GDCALL:
      // These are General-Dynamic which permits fully general TLS
      // access.  Since we know that we are generating an executable,
      // we can convert this to Initial-Exec.  If we also know that
      // this is a local symbol, we can further switch to Local-Exec.
      if (is_final)
	return tls::TLSOPT_TO_LE;
      return tls::TLSOPT_TO_IE;

    case elfcpp::R_390_TLS_LDM32:
    case elfcpp::R_390_TLS_LDM64:
    case elfcpp::R_390_TLS_LDO32:
    case elfcpp::R_390_TLS_LDO64:
    case elfcpp::R_390_TLS_LDCALL:
      // This is Local-Dynamic, which refers to a local symbol in the
      // dynamic TLS block.  Since we know that we generating an
      // executable, we can switch to Local-Exec.
      return tls::TLSOPT_TO_LE;

    case elfcpp::R_390_TLS_IE32:
    case elfcpp::R_390_TLS_IE64:
    case elfcpp::R_390_TLS_GOTIE32:
    case elfcpp::R_390_TLS_GOTIE64:
    case elfcpp::R_390_TLS_LOAD:
      // These are Initial-Exec relocs which get the thread offset
      // from the GOT.  If we know that we are linking against the
      // local symbol, we can switch to Local-Exec, which links the
      // thread offset into the instruction.
      if (is_final)
	return tls::TLSOPT_TO_LE;
      return tls::TLSOPT_NONE;

    case elfcpp::R_390_TLS_GOTIE12:
    case elfcpp::R_390_TLS_IEENT:
    case elfcpp::R_390_TLS_GOTIE20:
      // These are Initial-Exec, but cannot be optimized.
      return tls::TLSOPT_NONE;

    case elfcpp::R_390_TLS_LE32:
    case elfcpp::R_390_TLS_LE64:
      // When we already have Local-Exec, there is nothing further we
      // can do.
      return tls::TLSOPT_NONE;

    default:
      gold_unreachable();
    }
}

// Get the Reference_flags for a particular relocation.

template<int size>
int
Target_s390<size>::Scan::get_reference_flags(unsigned int r_type)
{
  switch (r_type)
    {
    case elfcpp::R_390_NONE:
    case elfcpp::R_390_GNU_VTINHERIT:
    case elfcpp::R_390_GNU_VTENTRY:
    case elfcpp::R_390_GOTPC:
    case elfcpp::R_390_GOTPCDBL:
      // No symbol reference.
      return 0;

    case elfcpp::R_390_64:
    case elfcpp::R_390_32:
    case elfcpp::R_390_20:
    case elfcpp::R_390_16:
    case elfcpp::R_390_12:
    case elfcpp::R_390_8:
      return Symbol::ABSOLUTE_REF;

    case elfcpp::R_390_PC12DBL:
    case elfcpp::R_390_PC16:
    case elfcpp::R_390_PC16DBL:
    case elfcpp::R_390_PC24DBL:
    case elfcpp::R_390_PC32:
    case elfcpp::R_390_PC32DBL:
    case elfcpp::R_390_PC64:
    case elfcpp::R_390_GOTOFF16:
    case elfcpp::R_390_GOTOFF32:
    case elfcpp::R_390_GOTOFF64:
      return Symbol::RELATIVE_REF;

    case elfcpp::R_390_PLT12DBL:
    case elfcpp::R_390_PLT16DBL:
    case elfcpp::R_390_PLT24DBL:
    case elfcpp::R_390_PLT32:
    case elfcpp::R_390_PLT32DBL:
    case elfcpp::R_390_PLT64:
    case elfcpp::R_390_PLTOFF16:
    case elfcpp::R_390_PLTOFF32:
    case elfcpp::R_390_PLTOFF64:
      return Symbol::FUNCTION_CALL | Symbol::RELATIVE_REF;

    case elfcpp::R_390_GOT12:
    case elfcpp::R_390_GOT16:
    case elfcpp::R_390_GOT20:
    case elfcpp::R_390_GOT32:
    case elfcpp::R_390_GOT64:
    case elfcpp::R_390_GOTENT:
    case elfcpp::R_390_GOTPLT12:
    case elfcpp::R_390_GOTPLT16:
    case elfcpp::R_390_GOTPLT20:
    case elfcpp::R_390_GOTPLT32:
    case elfcpp::R_390_GOTPLT64:
    case elfcpp::R_390_GOTPLTENT:
      // Absolute in GOT.
      return Symbol::ABSOLUTE_REF;

    case elfcpp::R_390_TLS_GD32:          // Global-dynamic
    case elfcpp::R_390_TLS_GD64:
    case elfcpp::R_390_TLS_GDCALL:
    case elfcpp::R_390_TLS_LDM32:         // Local-dynamic
    case elfcpp::R_390_TLS_LDM64:
    case elfcpp::R_390_TLS_LDO32:
    case elfcpp::R_390_TLS_LDO64:
    case elfcpp::R_390_TLS_LDCALL:
    case elfcpp::R_390_TLS_IE32:          // Initial-exec
    case elfcpp::R_390_TLS_IE64:
    case elfcpp::R_390_TLS_IEENT:
    case elfcpp::R_390_TLS_GOTIE12:
    case elfcpp::R_390_TLS_GOTIE20:
    case elfcpp::R_390_TLS_GOTIE32:
    case elfcpp::R_390_TLS_GOTIE64:
    case elfcpp::R_390_TLS_LOAD:
    case elfcpp::R_390_TLS_LE32:          // Local-exec
    case elfcpp::R_390_TLS_LE64:
      return Symbol::TLS_REF;

    case elfcpp::R_390_COPY:
    case elfcpp::R_390_GLOB_DAT:
    case elfcpp::R_390_JMP_SLOT:
    case elfcpp::R_390_RELATIVE:
    case elfcpp::R_390_IRELATIVE:
    case elfcpp::R_390_TLS_TPOFF:
    case elfcpp::R_390_TLS_DTPOFF:
    case elfcpp::R_390_TLS_DTPMOD:
    default:
      // Not expected.  We will give an error later.
      return 0;
    }
}

// Report an unsupported relocation against a local symbol.

template<int size>
void
Target_s390<size>::Scan::unsupported_reloc_local(
     Sized_relobj_file<size, true>* object,
     unsigned int r_type)
{
  gold_error(_("%s: unsupported reloc %u against local symbol"),
	     object->name().c_str(), r_type);
}

// We are about to emit a dynamic relocation of type R_TYPE.  If the
// dynamic linker does not support it, issue an error.

template<int size>
void
Target_s390<size>::Scan::check_non_pic(Relobj* object, unsigned int r_type)
{
  gold_assert(r_type != elfcpp::R_390_NONE);

  if (size == 64)
    {
      switch (r_type)
	{
	  // These are the relocation types supported by glibc for s390 64-bit.
	case elfcpp::R_390_RELATIVE:
	case elfcpp::R_390_IRELATIVE:
	case elfcpp::R_390_COPY:
	case elfcpp::R_390_GLOB_DAT:
	case elfcpp::R_390_JMP_SLOT:
	case elfcpp::R_390_TLS_DTPMOD:
	case elfcpp::R_390_TLS_DTPOFF:
	case elfcpp::R_390_TLS_TPOFF:
	case elfcpp::R_390_8:
	case elfcpp::R_390_16:
	case elfcpp::R_390_32:
	case elfcpp::R_390_64:
	case elfcpp::R_390_PC16:
	case elfcpp::R_390_PC16DBL:
	case elfcpp::R_390_PC32:
	case elfcpp::R_390_PC32DBL:
	case elfcpp::R_390_PC64:
	  return;

	default:
	  break;
	}
    }
  else
    {
      switch (r_type)
	{
	  // These are the relocation types supported by glibc for s390 32-bit.
	case elfcpp::R_390_RELATIVE:
	case elfcpp::R_390_IRELATIVE:
	case elfcpp::R_390_COPY:
	case elfcpp::R_390_GLOB_DAT:
	case elfcpp::R_390_JMP_SLOT:
	case elfcpp::R_390_TLS_DTPMOD:
	case elfcpp::R_390_TLS_DTPOFF:
	case elfcpp::R_390_TLS_TPOFF:
	case elfcpp::R_390_8:
	case elfcpp::R_390_16:
	case elfcpp::R_390_32:
	case elfcpp::R_390_PC16:
	case elfcpp::R_390_PC16DBL:
	case elfcpp::R_390_PC32:
	case elfcpp::R_390_PC32DBL:
	  return;

	default:
	  break;
	}
    }

  // This prevents us from issuing more than one error per reloc
  // section.  But we can still wind up issuing more than one
  // error per object file.
  if (this->issued_non_pic_error_)
    return;
  gold_assert(parameters->options().output_is_position_independent());
  object->error(_("requires unsupported dynamic reloc; "
		  "recompile with -fPIC"));
  this->issued_non_pic_error_ = true;
  return;
}

// Return whether we need to make a PLT entry for a relocation of the
// given type against a STT_GNU_IFUNC symbol.

template<int size>
bool
Target_s390<size>::Scan::reloc_needs_plt_for_ifunc(
     Sized_relobj_file<size, true>* object,
     unsigned int r_type)
{
  int flags = Scan::get_reference_flags(r_type);
  if (flags & Symbol::TLS_REF)
    gold_error(_("%s: unsupported TLS reloc %u for IFUNC symbol"),
	       object->name().c_str(), r_type);
  return flags != 0;
}

// Scan a relocation for a local symbol.

template<int size>
inline void
Target_s390<size>::Scan::local(Symbol_table* symtab,
				 Layout* layout,
				 Target_s390<size>* target,
				 Sized_relobj_file<size, true>* object,
				 unsigned int data_shndx,
				 Output_section* output_section,
				 const elfcpp::Rela<size, true>& reloc,
				 unsigned int r_type,
				 const elfcpp::Sym<size, true>& lsym,
				 bool is_discarded)
{
  if (is_discarded)
    return;

  // A local STT_GNU_IFUNC symbol may require a PLT entry.
  bool is_ifunc = lsym.get_st_type() == elfcpp::STT_GNU_IFUNC;

  if (is_ifunc && this->reloc_needs_plt_for_ifunc(object, r_type))
    {
      unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
      target->make_local_ifunc_plt_entry(symtab, layout, object, r_sym);
    }

  switch (r_type)
    {
    case elfcpp::R_390_NONE:
    case elfcpp::R_390_GNU_VTINHERIT:
    case elfcpp::R_390_GNU_VTENTRY:
      break;

    case elfcpp::R_390_64:
      // If building a shared library (or a position-independent
      // executable), we need to create a dynamic relocation for this
      // location.  The relocation applied at link time will apply the
      // link-time value, so we flag the location with an
      // R_390_RELATIVE relocation so the dynamic loader can
      // relocate it easily.
      if (parameters->options().output_is_position_independent() && size == 64)
	{
	  unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
	  Reloc_section* rela_dyn = target->rela_dyn_section(layout);
	  rela_dyn->add_local_relative(object, r_sym,
				       elfcpp::R_390_RELATIVE,
				       output_section, data_shndx,
				       reloc.get_r_offset(),
				       reloc.get_r_addend(), is_ifunc);
	}
      break;

    case elfcpp::R_390_32:
    case elfcpp::R_390_20:
    case elfcpp::R_390_16:
    case elfcpp::R_390_12:
    case elfcpp::R_390_8:
      if (parameters->options().output_is_position_independent())
	{
	  if (size == 32 && r_type == elfcpp::R_390_32)
	    {
	      unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
	      Reloc_section* rela_dyn = target->rela_dyn_section(layout);
	      rela_dyn->add_local_relative(object, r_sym,
					   elfcpp::R_390_RELATIVE,
					   output_section, data_shndx,
					   reloc.get_r_offset(),
					   reloc.get_r_addend(), is_ifunc);
	      break;
	    }

	  check_non_pic(object, r_type);

	  Reloc_section* rela_dyn = target->rela_dyn_section(layout);
	  unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
	  if (lsym.get_st_type() != elfcpp::STT_SECTION)
	    rela_dyn->add_local(object, r_sym, r_type, output_section,
				data_shndx, reloc.get_r_offset(),
				reloc.get_r_addend());
	  else
	    {
	      gold_assert(lsym.get_st_value() == 0);
	      unsigned int shndx = lsym.get_st_shndx();
	      bool is_ordinary;
	      shndx = object->adjust_sym_shndx(r_sym, shndx,
					       &is_ordinary);
	      if (!is_ordinary)
		object->error(_("section symbol %u has bad shndx %u"),
			      r_sym, shndx);
	      else
		rela_dyn->add_local_section(object, shndx,
					    r_type, output_section,
					    data_shndx, reloc.get_r_offset(),
					    reloc.get_r_addend());
	    }
	}
      break;

    case elfcpp::R_390_PC12DBL:
    case elfcpp::R_390_PC16:
    case elfcpp::R_390_PC16DBL:
    case elfcpp::R_390_PC24DBL:
    case elfcpp::R_390_PC32:
    case elfcpp::R_390_PC32DBL:
    case elfcpp::R_390_PC64:
      break;

    case elfcpp::R_390_PLT12DBL:
    case elfcpp::R_390_PLT16DBL:
    case elfcpp::R_390_PLT24DBL:
    case elfcpp::R_390_PLT32:
    case elfcpp::R_390_PLT32DBL:
    case elfcpp::R_390_PLT64:
      // Since we know this is a local symbol, we can handle this as a
      // PC32 reloc.
      break;

    case elfcpp::R_390_GOTPC:
    case elfcpp::R_390_GOTPCDBL:
    case elfcpp::R_390_GOTOFF16:
    case elfcpp::R_390_GOTOFF32:
    case elfcpp::R_390_GOTOFF64:
    case elfcpp::R_390_PLTOFF16:
    case elfcpp::R_390_PLTOFF32:
    case elfcpp::R_390_PLTOFF64:
      // We need a GOT section.
      target->got_section(symtab, layout);
      // For PLTOFF*, we'd normally want a PLT section, but since we
      // know this is a local symbol, no PLT is needed.
      break;

    case elfcpp::R_390_GOT12:
    case elfcpp::R_390_GOT16:
    case elfcpp::R_390_GOT20:
    case elfcpp::R_390_GOT32:
    case elfcpp::R_390_GOT64:
    case elfcpp::R_390_GOTENT:
    case elfcpp::R_390_GOTPLT12:
    case elfcpp::R_390_GOTPLT16:
    case elfcpp::R_390_GOTPLT20:
    case elfcpp::R_390_GOTPLT32:
    case elfcpp::R_390_GOTPLT64:
    case elfcpp::R_390_GOTPLTENT:
      {
	// The symbol requires a GOT section.
	Output_data_got<size, true>* got = target->got_section(symtab, layout);

	// The symbol requires a GOT entry.
	unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());

	// For a STT_GNU_IFUNC symbol we want the PLT offset.  That
	// lets function pointers compare correctly with shared
	// libraries.  Otherwise we would need an IRELATIVE reloc.
	bool is_new;
	if (is_ifunc)
	  is_new = got->add_local_plt(object, r_sym, GOT_TYPE_STANDARD);
	else
	  is_new = got->add_local(object, r_sym, GOT_TYPE_STANDARD);
	if (is_new)
	  {
	    // If we are generating a shared object, we need to add a
	    // dynamic relocation for this symbol's GOT entry.
	    if (parameters->options().output_is_position_independent())
	      {
		Reloc_section* rela_dyn = target->rela_dyn_section(layout);
		unsigned int got_offset =
		  object->local_got_offset(r_sym, GOT_TYPE_STANDARD);
		rela_dyn->add_local_relative(object, r_sym,
					     elfcpp::R_390_RELATIVE,
					     got, got_offset, 0, is_ifunc);
	      }
	  }
	// For GOTPLT*, we'd normally want a PLT section, but since
	// we know this is a local symbol, no PLT is needed.
      }
      break;

    case elfcpp::R_390_COPY:
    case elfcpp::R_390_GLOB_DAT:
    case elfcpp::R_390_JMP_SLOT:
    case elfcpp::R_390_RELATIVE:
    case elfcpp::R_390_IRELATIVE:
      // These are outstanding tls relocs, which are unexpected when linking
    case elfcpp::R_390_TLS_TPOFF:
    case elfcpp::R_390_TLS_DTPOFF:
    case elfcpp::R_390_TLS_DTPMOD:
      gold_error(_("%s: unexpected reloc %u in object file"),
		 object->name().c_str(), r_type);
      break;

      // These are initial tls relocs, which are expected when linking
    case elfcpp::R_390_TLS_GD32:          // Global-dynamic
    case elfcpp::R_390_TLS_GD64:
    case elfcpp::R_390_TLS_GDCALL:
    case elfcpp::R_390_TLS_LDM32:         // Local-dynamic
    case elfcpp::R_390_TLS_LDM64:
    case elfcpp::R_390_TLS_LDO32:
    case elfcpp::R_390_TLS_LDO64:
    case elfcpp::R_390_TLS_LDCALL:
    case elfcpp::R_390_TLS_IE32:          // Initial-exec
    case elfcpp::R_390_TLS_IE64:
    case elfcpp::R_390_TLS_IEENT:
    case elfcpp::R_390_TLS_GOTIE12:
    case elfcpp::R_390_TLS_GOTIE20:
    case elfcpp::R_390_TLS_GOTIE32:
    case elfcpp::R_390_TLS_GOTIE64:
    case elfcpp::R_390_TLS_LOAD:
    case elfcpp::R_390_TLS_LE32:          // Local-exec
    case elfcpp::R_390_TLS_LE64:
      {
	bool output_is_shared = parameters->options().shared();
	const tls::Tls_optimization optimized_type
	    = Target_s390<size>::optimize_tls_reloc(!output_is_shared,
						      r_type);
	switch (r_type)
	  {
	  case elfcpp::R_390_TLS_GD32:       // General-dynamic
	  case elfcpp::R_390_TLS_GD64:
	  case elfcpp::R_390_TLS_GDCALL:
	    if (optimized_type == tls::TLSOPT_NONE)
	      {
		// Create a pair of GOT entries for the module index and
		// dtv-relative offset.
		Output_data_got<size, true>* got
		    = target->got_section(symtab, layout);
		unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
		unsigned int shndx = lsym.get_st_shndx();
		bool is_ordinary;
		shndx = object->adjust_sym_shndx(r_sym, shndx, &is_ordinary);
		if (!is_ordinary)
		  object->error(_("local symbol %u has bad shndx %u"),
			      r_sym, shndx);
		else
		  got->add_local_pair_with_rel(object, r_sym,
					       shndx,
					       GOT_TYPE_TLS_PAIR,
					       target->rela_dyn_section(layout),
					       elfcpp::R_390_TLS_DTPMOD);
	      }
	    else if (optimized_type != tls::TLSOPT_TO_LE)
	      unsupported_reloc_local(object, r_type);
	    break;

	  case elfcpp::R_390_TLS_LDM32:       // Local-dynamic
	  case elfcpp::R_390_TLS_LDM64:
	  case elfcpp::R_390_TLS_LDCALL:
	    if (optimized_type == tls::TLSOPT_NONE)
	      {
		// Create a GOT entry for the module index.
		target->got_mod_index_entry(symtab, layout, object);
	      }
	    else if (optimized_type != tls::TLSOPT_TO_LE)
	      unsupported_reloc_local(object, r_type);
	    break;

	  case elfcpp::R_390_TLS_LDO32:
	  case elfcpp::R_390_TLS_LDO64:
	    break;

	  case elfcpp::R_390_TLS_IE32:    // Initial-exec
	  case elfcpp::R_390_TLS_IE64:
	    // These two involve an absolute address
	    if (parameters->options().shared()
		&& optimized_type == tls::TLSOPT_NONE)
	      {
		if ((size == 32 && r_type == elfcpp::R_390_TLS_IE32) ||
		    (size == 64 && r_type == elfcpp::R_390_TLS_IE64))
		  {
		    // We need to create a dynamic relocation.
		    Reloc_section* rela_dyn = target->rela_dyn_section(layout);
		    unsigned int r_sym =
			elfcpp::elf_r_sym<size>(reloc.get_r_info());
		    rela_dyn->add_local_relative(object, r_sym,
						elfcpp::R_390_RELATIVE,
						output_section, data_shndx,
						reloc.get_r_offset(),
						reloc.get_r_addend(), false);
		  }
		else
		  {
		    unsupported_reloc_local(object, r_type);
		  }
	      }
	    // Fall through.
	  case elfcpp::R_390_TLS_IEENT:
	  case elfcpp::R_390_TLS_GOTIE12:
	  case elfcpp::R_390_TLS_GOTIE20:
	  case elfcpp::R_390_TLS_GOTIE32:
	  case elfcpp::R_390_TLS_GOTIE64:
	  case elfcpp::R_390_TLS_LOAD:
	    layout->set_has_static_tls();
	    if (optimized_type == tls::TLSOPT_NONE)
	      {
		if (!output_is_shared)
		  {
		    // We're making an executable, and the symbol is local, but
		    // we cannot optimize to LE.  Make a const GOT entry instead.
		    Output_data_got<size, true>* got
			= target->got_section(symtab, layout);
		    unsigned int r_sym
			= elfcpp::elf_r_sym<size>(reloc.get_r_info());
		    got->add_local_plt(object, r_sym, GOT_TYPE_TLS_OFFSET);
		  }
		else
		{
		  // Create a GOT entry for the tp-relative offset.
		  Output_data_got<size, true>* got
		      = target->got_section(symtab, layout);
		  unsigned int r_sym
		      = elfcpp::elf_r_sym<size>(reloc.get_r_info());
		  got->add_local_with_rel(object, r_sym, GOT_TYPE_TLS_OFFSET,
					  target->rela_dyn_section(layout),
					  elfcpp::R_390_TLS_TPOFF);
		}
	      }
	    else if (optimized_type != tls::TLSOPT_TO_LE)
	      unsupported_reloc_local(object, r_type);
	    break;

	  case elfcpp::R_390_TLS_LE32:     // Local-exec
	  case elfcpp::R_390_TLS_LE64:
	    layout->set_has_static_tls();
	    if (output_is_shared)
	    {
	      // We need to create a dynamic relocation.
	      if ((size == 32 && r_type == elfcpp::R_390_TLS_LE32) ||
	          (size == 64 && r_type == elfcpp::R_390_TLS_LE64))
		{
		  Reloc_section* rela_dyn = target->rela_dyn_section(layout);
		  unsigned int r_sym
		      = elfcpp::elf_r_sym<size>(reloc.get_r_info());
		  gold_assert(lsym.get_st_type() != elfcpp::STT_SECTION);
		  rela_dyn->add_local(object, r_sym, elfcpp::R_390_TLS_TPOFF,
				      output_section, data_shndx,
				      reloc.get_r_offset(),
				      reloc.get_r_addend());
		}
	      else
		{
		  unsupported_reloc_local(object, r_type);
		}
	    }
	    break;

	  default:
	    gold_unreachable();
	  }
      }
      break;

    default:
      gold_error(_("%s: unsupported reloc %u against local symbol"),
		 object->name().c_str(), r_type);
      break;
    }
}

// Scan a relocation for a global symbol.

template<int size>
inline void
Target_s390<size>::Scan::global(Symbol_table* symtab,
			    Layout* layout,
			    Target_s390<size>* target,
			    Sized_relobj_file<size, true>* object,
			    unsigned int data_shndx,
			    Output_section* output_section,
			    const elfcpp::Rela<size, true>& reloc,
			    unsigned int r_type,
			    Symbol* gsym)
{
  // A STT_GNU_IFUNC symbol may require a PLT entry.
  if (gsym->type() == elfcpp::STT_GNU_IFUNC
      && this->reloc_needs_plt_for_ifunc(object, r_type))
    target->make_plt_entry(symtab, layout, gsym);

  switch (r_type)
    {
    case elfcpp::R_390_NONE:
    case elfcpp::R_390_GNU_VTINHERIT:
    case elfcpp::R_390_GNU_VTENTRY:
      break;

    case elfcpp::R_390_64:
    case elfcpp::R_390_32:
    case elfcpp::R_390_20:
    case elfcpp::R_390_16:
    case elfcpp::R_390_12:
    case elfcpp::R_390_8:
      {
	// Make a PLT entry if necessary.
	if (gsym->needs_plt_entry())
	  {
	    target->make_plt_entry(symtab, layout, gsym);
	    // Since this is not a PC-relative relocation, we may be
	    // taking the address of a function. In that case we need to
	    // set the entry in the dynamic symbol table to the address of
	    // the PLT entry.
	    if (gsym->is_from_dynobj() && !parameters->options().shared())
	      gsym->set_needs_dynsym_value();
	  }
	// Make a dynamic relocation if necessary.
	if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type)))
	  {
	    if (!parameters->options().output_is_position_independent()
		&& gsym->may_need_copy_reloc())
	      {
		target->copy_reloc(symtab, layout, object,
				   data_shndx, output_section, gsym, reloc);
	      }
	    else if (((size == 64 && r_type == elfcpp::R_390_64)
		      || (size == 32 && r_type == elfcpp::R_390_32))
		     && gsym->type() == elfcpp::STT_GNU_IFUNC
		     && gsym->can_use_relative_reloc(false)
		     && !gsym->is_from_dynobj()
		     && !gsym->is_undefined()
		     && !gsym->is_preemptible())
	      {
		// Use an IRELATIVE reloc for a locally defined
		// STT_GNU_IFUNC symbol.  This makes a function
		// address in a PIE executable match the address in a
		// shared library that it links against.
		Reloc_section* rela_dyn =
		  target->rela_irelative_section(layout);
		unsigned int r_type = elfcpp::R_390_IRELATIVE;
		rela_dyn->add_symbolless_global_addend(gsym, r_type,
						       output_section, object,
						       data_shndx,
						       reloc.get_r_offset(),
						       reloc.get_r_addend());
	      }
	    else if (((size == 64 && r_type == elfcpp::R_390_64)
		      || (size == 32 && r_type == elfcpp::R_390_32))
		     && gsym->can_use_relative_reloc(false))
	      {
		Reloc_section* rela_dyn = target->rela_dyn_section(layout);
		rela_dyn->add_global_relative(gsym, elfcpp::R_390_RELATIVE,
					      output_section, object,
					      data_shndx,
					      reloc.get_r_offset(),
					      reloc.get_r_addend(), false);
	      }
	    else
	      {
		check_non_pic(object, r_type);
		Reloc_section* rela_dyn = target->rela_dyn_section(layout);
		rela_dyn->add_global(gsym, r_type, output_section, object,
				     data_shndx, reloc.get_r_offset(),
				     reloc.get_r_addend());
	      }
	  }
      }
      break;

    case elfcpp::R_390_PC12DBL:
    case elfcpp::R_390_PC16:
    case elfcpp::R_390_PC16DBL:
    case elfcpp::R_390_PC24DBL:
    case elfcpp::R_390_PC32:
    case elfcpp::R_390_PC32DBL:
    case elfcpp::R_390_PC64:
      {
	// Make a PLT entry if necessary.
	if (gsym->needs_plt_entry())
	  {
	    target->make_plt_entry(symtab, layout, gsym);
	    // larl is often used to take address of a function.  Aim the
	    // symbol at the PLT entry.
	    if (gsym->is_from_dynobj() && !parameters->options().shared())
	      gsym->set_needs_dynsym_value();
	  }
	// Make a dynamic relocation if necessary.
	if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type)))
	  {
	    if (parameters->options().output_is_executable()
		&& gsym->may_need_copy_reloc())
	      {
		target->copy_reloc(symtab, layout, object,
				   data_shndx, output_section, gsym, reloc);
	      }
	    else
	      {
		check_non_pic(object, r_type);
		Reloc_section* rela_dyn = target->rela_dyn_section(layout);
		rela_dyn->add_global(gsym, r_type, output_section, object,
				     data_shndx, reloc.get_r_offset(),
				     reloc.get_r_addend());
	      }
	  }
      }
      break;

    case elfcpp::R_390_PLT12DBL:
    case elfcpp::R_390_PLT16DBL:
    case elfcpp::R_390_PLT24DBL:
    case elfcpp::R_390_PLT32:
    case elfcpp::R_390_PLT32DBL:
    case elfcpp::R_390_PLT64:
      // If the symbol is fully resolved, this is just a PC32 reloc.
      // Otherwise we need a PLT entry.
      if (gsym->final_value_is_known())
	break;
      // If building a shared library, we can also skip the PLT entry
      // if the symbol is defined in the output file and is protected
      // or hidden.
      if (gsym->is_defined()
	  && !gsym->is_from_dynobj()
	  && !gsym->is_preemptible())
	break;
      target->make_plt_entry(symtab, layout, gsym);
      break;

    case elfcpp::R_390_GOTPC:
    case elfcpp::R_390_GOTPCDBL:
    case elfcpp::R_390_GOTOFF16:
    case elfcpp::R_390_GOTOFF32:
    case elfcpp::R_390_GOTOFF64:
    case elfcpp::R_390_PLTOFF16:
    case elfcpp::R_390_PLTOFF32:
    case elfcpp::R_390_PLTOFF64:
      // We need a GOT section.
      target->got_section(symtab, layout);
      // For PLTOFF*, we also need a PLT entry (but only if the
      // symbol is not fully resolved).
      if ((r_type == elfcpp::R_390_PLTOFF16
           || r_type == elfcpp::R_390_PLTOFF32
	   || r_type == elfcpp::R_390_PLTOFF64)
	  && !gsym->final_value_is_known())
	target->make_plt_entry(symtab, layout, gsym);
      break;

    case elfcpp::R_390_GOT12:
    case elfcpp::R_390_GOT16:
    case elfcpp::R_390_GOT20:
    case elfcpp::R_390_GOT32:
    case elfcpp::R_390_GOT64:
    case elfcpp::R_390_GOTENT:
    case elfcpp::R_390_GOTPLT12:
    case elfcpp::R_390_GOTPLT16:
    case elfcpp::R_390_GOTPLT20:
    case elfcpp::R_390_GOTPLT32:
    case elfcpp::R_390_GOTPLT64:
    case elfcpp::R_390_GOTPLTENT:
      {
	// The symbol requires a GOT entry.
	Output_data_got<size, true>* got = target->got_section(symtab, layout);

	if (gsym->final_value_is_known())
	  {
	    // For a STT_GNU_IFUNC symbol we want the PLT address.
	    if (gsym->type() == elfcpp::STT_GNU_IFUNC)
	      got->add_global_plt(gsym, GOT_TYPE_STANDARD);
	    else
	      got->add_global(gsym, GOT_TYPE_STANDARD);
	  }
	else
	  {
	    // If this symbol is not fully resolved, we need to add a
	    // dynamic relocation for it.
	    Reloc_section* rela_dyn = target->rela_dyn_section(layout);

	    // Use a GLOB_DAT rather than a RELATIVE reloc if:
	    //
	    // 1) The symbol may be defined in some other module.
	    //
	    // 2) We are building a shared library and this is a
	    // protected symbol; using GLOB_DAT means that the dynamic
	    // linker can use the address of the PLT in the main
	    // executable when appropriate so that function address
	    // comparisons work.
	    //
	    // 3) This is a STT_GNU_IFUNC symbol in position dependent
	    // code, again so that function address comparisons work.
	    if (gsym->is_from_dynobj()
		|| gsym->is_undefined()
		|| gsym->is_preemptible()
		|| (gsym->visibility() == elfcpp::STV_PROTECTED
		    && parameters->options().shared())
		|| (gsym->type() == elfcpp::STT_GNU_IFUNC
		    && parameters->options().output_is_position_independent()))
	      got->add_global_with_rel(gsym, GOT_TYPE_STANDARD, rela_dyn,
				       elfcpp::R_390_GLOB_DAT);
	    else
	      {
		// For a STT_GNU_IFUNC symbol we want to write the PLT
		// offset into the GOT, so that function pointer
		// comparisons work correctly.
		bool is_new;
		if (gsym->type() != elfcpp::STT_GNU_IFUNC)
		  is_new = got->add_global(gsym, GOT_TYPE_STANDARD);
		else
		  {
		    is_new = got->add_global_plt(gsym, GOT_TYPE_STANDARD);
		    // Tell the dynamic linker to use the PLT address
		    // when resolving relocations.
		    if (gsym->is_from_dynobj()
			&& !parameters->options().shared())
		      gsym->set_needs_dynsym_value();
		  }
		if (is_new)
		  {
		    unsigned int got_off = gsym->got_offset(GOT_TYPE_STANDARD);
		    rela_dyn->add_global_relative(gsym,
						  elfcpp::R_390_RELATIVE,
						  got, got_off, 0, false);
		  }
	      }
	  }
      }
      break;

    case elfcpp::R_390_COPY:
    case elfcpp::R_390_GLOB_DAT:
    case elfcpp::R_390_JMP_SLOT:
    case elfcpp::R_390_RELATIVE:
    case elfcpp::R_390_IRELATIVE:
      // These are outstanding tls relocs, which are unexpected when linking
    case elfcpp::R_390_TLS_TPOFF:
    case elfcpp::R_390_TLS_DTPOFF:
    case elfcpp::R_390_TLS_DTPMOD:
      gold_error(_("%s: unexpected reloc %u in object file"),
		 object->name().c_str(), r_type);
      break;

      // These are initial tls relocs, which are expected for global()
    case elfcpp::R_390_TLS_GD32:          // Global-dynamic
    case elfcpp::R_390_TLS_GD64:
    case elfcpp::R_390_TLS_GDCALL:
    case elfcpp::R_390_TLS_LDM32:         // Local-dynamic
    case elfcpp::R_390_TLS_LDM64:
    case elfcpp::R_390_TLS_LDO32:
    case elfcpp::R_390_TLS_LDO64:
    case elfcpp::R_390_TLS_LDCALL:
    case elfcpp::R_390_TLS_IE32:          // Initial-exec
    case elfcpp::R_390_TLS_IE64:
    case elfcpp::R_390_TLS_IEENT:
    case elfcpp::R_390_TLS_GOTIE12:
    case elfcpp::R_390_TLS_GOTIE20:
    case elfcpp::R_390_TLS_GOTIE32:
    case elfcpp::R_390_TLS_GOTIE64:
    case elfcpp::R_390_TLS_LOAD:
    case elfcpp::R_390_TLS_LE32:          // Local-exec
    case elfcpp::R_390_TLS_LE64:
      {
	// For the optimizable Initial-Exec model, we can treat undef symbols
	// as final when building an executable.
	const bool is_final = (gsym->final_value_is_known() ||
			       ((r_type == elfcpp::R_390_TLS_IE32 ||
			         r_type == elfcpp::R_390_TLS_IE64 ||
			         r_type == elfcpp::R_390_TLS_GOTIE32 ||
			         r_type == elfcpp::R_390_TLS_GOTIE64) &&
			        gsym->is_undefined() &&
				parameters->options().output_is_executable()));
	const tls::Tls_optimization optimized_type
	    = Target_s390<size>::optimize_tls_reloc(is_final, r_type);
	switch (r_type)
	  {
	  case elfcpp::R_390_TLS_GD32:       // General-dynamic
	  case elfcpp::R_390_TLS_GD64:
	  case elfcpp::R_390_TLS_GDCALL:
	    if (optimized_type == tls::TLSOPT_NONE)
	      {
		// Create a pair of GOT entries for the module index and
		// dtv-relative offset.
		Output_data_got<size, true>* got
		    = target->got_section(symtab, layout);
		got->add_global_pair_with_rel(gsym, GOT_TYPE_TLS_PAIR,
					      target->rela_dyn_section(layout),
					      elfcpp::R_390_TLS_DTPMOD,
					      elfcpp::R_390_TLS_DTPOFF);
	      }
	    else if (optimized_type == tls::TLSOPT_TO_IE)
	      {
		// Create a GOT entry for the tp-relative offset.
		Output_data_got<size, true>* got
		    = target->got_section(symtab, layout);
		got->add_global_with_rel(gsym, GOT_TYPE_TLS_OFFSET,
					 target->rela_dyn_section(layout),
					 elfcpp::R_390_TLS_TPOFF);
	      }
	    else if (optimized_type != tls::TLSOPT_TO_LE)
	      unsupported_reloc_global(object, r_type, gsym);
	    break;

	  case elfcpp::R_390_TLS_LDM32:       // Local-dynamic
	  case elfcpp::R_390_TLS_LDM64:
	  case elfcpp::R_390_TLS_LDCALL:
	    if (optimized_type == tls::TLSOPT_NONE)
	      {
		// Create a GOT entry for the module index.
		target->got_mod_index_entry(symtab, layout, object);
	      }
	    else if (optimized_type != tls::TLSOPT_TO_LE)
	      unsupported_reloc_global(object, r_type, gsym);
	    break;

	  case elfcpp::R_390_TLS_LDO32:
	  case elfcpp::R_390_TLS_LDO64:
	    break;

	  case elfcpp::R_390_TLS_IE32:    // Initial-exec
	  case elfcpp::R_390_TLS_IE64:
	    // These two involve an absolute address
	    if (parameters->options().shared())
	      {
		if ((size == 32 && r_type == elfcpp::R_390_TLS_IE32) ||
		    (size == 64 && r_type == elfcpp::R_390_TLS_IE64))
		  {
		    // We need to create a dynamic relocation.
		    Reloc_section* rela_dyn = target->rela_dyn_section(layout);
		    rela_dyn->add_global_relative(gsym, elfcpp::R_390_RELATIVE,
						  output_section, object,
						  data_shndx,
						  reloc.get_r_offset(),
						  reloc.get_r_addend(), false);
		  }
		else
		  {
		    unsupported_reloc_global(object, r_type, gsym);
		  }
	      }
	    // Fall through.
	  case elfcpp::R_390_TLS_IEENT:
	  case elfcpp::R_390_TLS_GOTIE12:
	  case elfcpp::R_390_TLS_GOTIE20:
	  case elfcpp::R_390_TLS_GOTIE32:
	  case elfcpp::R_390_TLS_GOTIE64:
	  case elfcpp::R_390_TLS_LOAD:
	    layout->set_has_static_tls();
	    if (optimized_type == tls::TLSOPT_NONE)
	      {
		if (is_final && !parameters->options().shared())
		  {
		    // We're making an executable, and the symbol is local, but
		    // we cannot optimize to LE.  Make a const GOT entry instead.
		    Output_data_got<size, true>* got
			= target->got_section(symtab, layout);
		    got->add_global_plt(gsym, GOT_TYPE_TLS_OFFSET);
		  }
		else
		  {
		    // Create a GOT entry for the tp-relative offset.
		    Output_data_got<size, true>* got
			= target->got_section(symtab, layout);
		    got->add_global_with_rel(gsym, GOT_TYPE_TLS_OFFSET,
					     target->rela_dyn_section(layout),
					     elfcpp::R_390_TLS_TPOFF);
		  }
	      }
	    else if (optimized_type != tls::TLSOPT_TO_LE)
	      unsupported_reloc_global(object, r_type, gsym);
	    break;

	  case elfcpp::R_390_TLS_LE32:     // Local-exec
	  case elfcpp::R_390_TLS_LE64:
	    layout->set_has_static_tls();
	    if (parameters->options().shared())
	      {
		// We need to create a dynamic relocation.
		if ((size == 32 && r_type == elfcpp::R_390_TLS_LE32) ||
		    (size == 64 && r_type == elfcpp::R_390_TLS_LE64))
		  {
		    Reloc_section* rela_dyn = target->rela_dyn_section(layout);
		    rela_dyn->add_global(gsym, elfcpp::R_390_TLS_TPOFF,
					 output_section, object,
					 data_shndx, reloc.get_r_offset(),
					 reloc.get_r_addend());
		  }
		else
		  {
		    unsupported_reloc_global(object, r_type, gsym);
		  }
	      }
	    break;

	  default:
	    gold_unreachable();
	  }
      }
      break;

    default:
      gold_error(_("%s: unsupported reloc %u against global symbol %s"),
		 object->name().c_str(), r_type,
		 gsym->demangled_name().c_str());
      break;
    }
}


// Report an unsupported relocation against a global symbol.

template<int size>
void
Target_s390<size>::Scan::unsupported_reloc_global(
    Sized_relobj_file<size, true>* object,
    unsigned int r_type,
    Symbol* gsym)
{
  gold_error(_("%s: unsupported reloc %u against global symbol %s"),
	     object->name().c_str(), r_type, gsym->demangled_name().c_str());
}

// Returns true if this relocation type could be that of a function pointer.
template<int size>
inline bool
Target_s390<size>::Scan::possible_function_pointer_reloc(unsigned int r_type)
{
  switch (r_type)
    {
    case elfcpp::R_390_32:
    case elfcpp::R_390_64:
    case elfcpp::R_390_PC32DBL: // could be used by larl insn
    case elfcpp::R_390_GOT12:
    case elfcpp::R_390_GOT16:
    case elfcpp::R_390_GOT20:
    case elfcpp::R_390_GOT32:
    case elfcpp::R_390_GOT64:
    case elfcpp::R_390_GOTENT:
    case elfcpp::R_390_GOTOFF16:
    case elfcpp::R_390_GOTOFF32:
    case elfcpp::R_390_GOTOFF64:
      return true;
    }
  return false;
}

// For safe ICF, scan a relocation for a local symbol to check if it
// corresponds to a function pointer being taken.  In that case mark
// the function whose pointer was taken as not foldable.

template<int size>
inline bool
Target_s390<size>::Scan::local_reloc_may_be_function_pointer(
  Symbol_table* ,
  Layout* ,
  Target_s390<size>* ,
  Sized_relobj_file<size, true>* ,
  unsigned int ,
  Output_section* ,
  const elfcpp::Rela<size, true>& ,
  unsigned int r_type,
  const elfcpp::Sym<size, true>&)
{
  // When building a shared library, do not fold any local symbols.
  return (parameters->options().shared()
	  || possible_function_pointer_reloc(r_type));
}

// For safe ICF, scan a relocation for a global symbol to check if it
// corresponds to a function pointer being taken.  In that case mark
// the function whose pointer was taken as not foldable.

template<int size>
inline bool
Target_s390<size>::Scan::global_reloc_may_be_function_pointer(
  Symbol_table*,
  Layout* ,
  Target_s390<size>* ,
  Sized_relobj_file<size, true>* ,
  unsigned int ,
  Output_section* ,
  const elfcpp::Rela<size, true>& ,
  unsigned int r_type,
  Symbol* gsym)
{
  // When building a shared library, do not fold symbols whose visibility
  // is hidden, internal or protected.
  return ((parameters->options().shared()
	   && (gsym->visibility() == elfcpp::STV_INTERNAL
	       || gsym->visibility() == elfcpp::STV_PROTECTED
	       || gsym->visibility() == elfcpp::STV_HIDDEN))
	  || possible_function_pointer_reloc(r_type));
}

template<int size>
void
Target_s390<size>::gc_process_relocs(Symbol_table* symtab,
				       Layout* layout,
				       Sized_relobj_file<size, true>* object,
				       unsigned int data_shndx,
				       unsigned int sh_type,
				       const unsigned char* prelocs,
				       size_t reloc_count,
				       Output_section* output_section,
				       bool needs_special_offset_handling,
				       size_t local_symbol_count,
				       const unsigned char* plocal_symbols)
{
  typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, true>
      Classify_reloc;

  if (sh_type == elfcpp::SHT_REL)
    return;

  gold::gc_process_relocs<size, true, Target_s390<size>, Scan, Classify_reloc>(
    symtab,
    layout,
    this,
    object,
    data_shndx,
    prelocs,
    reloc_count,
    output_section,
    needs_special_offset_handling,
    local_symbol_count,
    plocal_symbols);
}

// Perform a relocation.

template<int size>
inline bool
Target_s390<size>::Relocate::relocate(
    const Relocate_info<size, true>* relinfo,
    unsigned int,
    Target_s390<size>* target,
    Output_section*,
    size_t relnum,
    const unsigned char* preloc,
    const Sized_symbol<size>* gsym,
    const Symbol_value<size>* psymval,
    unsigned char* view,
    typename elfcpp::Elf_types<size>::Elf_Addr address,
    section_size_type view_size)
{
  if (view == NULL)
    return true;

  const elfcpp::Rela<size, true> rela(preloc);
  unsigned int r_type = elfcpp::elf_r_type<size>(rela.get_r_info());
  const Sized_relobj_file<size, true>* object = relinfo->object;

  // Pick the value to use for symbols defined in the PLT.
  Symbol_value<size> symval;
  if (gsym != NULL
      && gsym->use_plt_offset(Scan::get_reference_flags(r_type)))
    {
      symval.set_output_value(target->plt_address_for_global(gsym));
      psymval = &symval;
    }
  else if (gsym == NULL && psymval->is_ifunc_symbol())
    {
      unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
      if (object->local_has_plt_offset(r_sym))
	{
	  symval.set_output_value(target->plt_address_for_local(object, r_sym));
	  psymval = &symval;
	}
    }

  const elfcpp::Elf_Xword addend = rela.get_r_addend();

  typename elfcpp::Elf_types<size>::Elf_Addr value = 0;

  switch (r_type)
    {
    case elfcpp::R_390_PLT64:
    case elfcpp::R_390_PLT32:
    case elfcpp::R_390_PLT32DBL:
    case elfcpp::R_390_PLT24DBL:
    case elfcpp::R_390_PLT16DBL:
    case elfcpp::R_390_PLT12DBL:
      gold_assert(gsym == NULL
		  || gsym->has_plt_offset()
		  || gsym->final_value_is_known()
		  || (gsym->is_defined()
		      && !gsym->is_from_dynobj()
		      && !gsym->is_preemptible()));
      // Fall through.
    case elfcpp::R_390_8:
    case elfcpp::R_390_12:
    case elfcpp::R_390_16:
    case elfcpp::R_390_20:
    case elfcpp::R_390_32:
    case elfcpp::R_390_64:
    case elfcpp::R_390_PC16:
    case elfcpp::R_390_PC32:
    case elfcpp::R_390_PC64:
    case elfcpp::R_390_PC32DBL:
    case elfcpp::R_390_PC24DBL:
    case elfcpp::R_390_PC16DBL:
    case elfcpp::R_390_PC12DBL:
      value = psymval->value(object, addend);
      break;

    case elfcpp::R_390_GOTPC:
    case elfcpp::R_390_GOTPCDBL:
      gold_assert(gsym != NULL);
      value = target->got_address() + addend;
      break;

    case elfcpp::R_390_PLTOFF64:
    case elfcpp::R_390_PLTOFF32:
    case elfcpp::R_390_PLTOFF16:
      gold_assert(gsym == NULL
		  || gsym->has_plt_offset()
		  || gsym->final_value_is_known());
      // Fall through.
    case elfcpp::R_390_GOTOFF64:
    case elfcpp::R_390_GOTOFF32:
    case elfcpp::R_390_GOTOFF16:
      value = (psymval->value(object, addend)
	       - target->got_address());
      break;

    case elfcpp::R_390_GOT12:
    case elfcpp::R_390_GOT16:
    case elfcpp::R_390_GOT20:
    case elfcpp::R_390_GOT32:
    case elfcpp::R_390_GOT64:
    case elfcpp::R_390_GOTENT:
    case elfcpp::R_390_GOTPLT12:
    case elfcpp::R_390_GOTPLT16:
    case elfcpp::R_390_GOTPLT20:
    case elfcpp::R_390_GOTPLT32:
    case elfcpp::R_390_GOTPLT64:
    case elfcpp::R_390_GOTPLTENT:
      {
        unsigned int got_offset = 0;
        if (gsym != NULL)
	  {
	    gold_assert(gsym->has_got_offset(GOT_TYPE_STANDARD));
	    got_offset = gsym->got_offset(GOT_TYPE_STANDARD);
	  }
        else
	  {
	    unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
	    gold_assert(object->local_has_got_offset(r_sym, GOT_TYPE_STANDARD));
	    got_offset = object->local_got_offset(r_sym, GOT_TYPE_STANDARD);
	  }
        value = got_offset + target->got_main_offset() + addend;
      }
      break;

      // These are initial tls relocs, which are expected when linking
    case elfcpp::R_390_TLS_LOAD:
    case elfcpp::R_390_TLS_GDCALL:          // Global-dynamic
    case elfcpp::R_390_TLS_GD32:
    case elfcpp::R_390_TLS_GD64:
    case elfcpp::R_390_TLS_LDCALL:          // Local-dynamic
    case elfcpp::R_390_TLS_LDM32:
    case elfcpp::R_390_TLS_LDM64:
    case elfcpp::R_390_TLS_LDO32:
    case elfcpp::R_390_TLS_LDO64:
    case elfcpp::R_390_TLS_GOTIE12:         // Initial-exec
    case elfcpp::R_390_TLS_GOTIE20:
    case elfcpp::R_390_TLS_GOTIE32:
    case elfcpp::R_390_TLS_GOTIE64:
    case elfcpp::R_390_TLS_IE32:
    case elfcpp::R_390_TLS_IE64:
    case elfcpp::R_390_TLS_IEENT:
    case elfcpp::R_390_TLS_LE32:            // Local-exec
    case elfcpp::R_390_TLS_LE64:
      value = this->relocate_tls(relinfo, target, relnum, rela, r_type, gsym, psymval,
			 view, view_size);
      break;

    default:
      break;
    }

  typename S390_relocate_functions<size>::Status status
      = S390_relocate_functions<size>::STATUS_OK;

  switch (r_type)
    {
    case elfcpp::R_390_NONE:
    case elfcpp::R_390_GNU_VTINHERIT:
    case elfcpp::R_390_GNU_VTENTRY:
    case elfcpp::R_390_TLS_GDCALL:
    case elfcpp::R_390_TLS_LDCALL:
    case elfcpp::R_390_TLS_LOAD:
      break;

    case elfcpp::R_390_64:
    case elfcpp::R_390_GOT64:
    case elfcpp::R_390_GOTPLT64:
    case elfcpp::R_390_PLTOFF64:
    case elfcpp::R_390_GOTOFF64:
    case elfcpp::R_390_TLS_GD64:
    case elfcpp::R_390_TLS_LDM64:
    case elfcpp::R_390_TLS_LDO64:
    case elfcpp::R_390_TLS_GOTIE64:
    case elfcpp::R_390_TLS_IE64:
    case elfcpp::R_390_TLS_LE64:
      Relocate_functions<size, true>::rela64(view, value, 0);
      break;

    case elfcpp::R_390_32:
    case elfcpp::R_390_GOT32:
    case elfcpp::R_390_GOTPLT32:
    case elfcpp::R_390_PLTOFF32:
    case elfcpp::R_390_GOTOFF32:
    case elfcpp::R_390_TLS_GD32:
    case elfcpp::R_390_TLS_LDM32:
    case elfcpp::R_390_TLS_LDO32:
    case elfcpp::R_390_TLS_GOTIE32:
    case elfcpp::R_390_TLS_IE32:
    case elfcpp::R_390_TLS_LE32:
      Relocate_functions<size, true>::rela32(view, value, 0);
      break;

    case elfcpp::R_390_20:
    case elfcpp::R_390_GOT20:
    case elfcpp::R_390_GOTPLT20:
    case elfcpp::R_390_TLS_GOTIE20:
      status = S390_relocate_functions<size>::rela20(view, value);
      break;

    case elfcpp::R_390_16:
    case elfcpp::R_390_GOT16:
    case elfcpp::R_390_GOTPLT16:
    case elfcpp::R_390_PLTOFF16:
    case elfcpp::R_390_GOTOFF16:
      status = S390_relocate_functions<size>::rela16(view, value);
      break;

    case elfcpp::R_390_12:
    case elfcpp::R_390_GOT12:
    case elfcpp::R_390_GOTPLT12:
    case elfcpp::R_390_TLS_GOTIE12:
      status = S390_relocate_functions<size>::rela12(view, value);
      break;

    case elfcpp::R_390_8:
      Relocate_functions<size, true>::rela8(view, value, 0);
      break;

    case elfcpp::R_390_PC16:
      Relocate_functions<size, true>::pcrela16(view, value, 0,
					       address);
      break;

    case elfcpp::R_390_PLT64:
    case elfcpp::R_390_PC64:
      Relocate_functions<size, true>::pcrela64(view, value, 0, address);
      break;

    case elfcpp::R_390_PLT32:
    case elfcpp::R_390_PC32:
    case elfcpp::R_390_GOTPC:
      Relocate_functions<size, true>::pcrela32(view, value, 0, address);
      break;

    case elfcpp::R_390_PLT32DBL:
    case elfcpp::R_390_PC32DBL:
    case elfcpp::R_390_GOTPCDBL:
      status = S390_relocate_functions<size>::pcrela32dbl(view, value, address);
      break;

    case elfcpp::R_390_PLT24DBL:
    case elfcpp::R_390_PC24DBL:
      status = S390_relocate_functions<size>::pcrela24dbl(view, value, address);
      break;

    case elfcpp::R_390_PLT16DBL:
    case elfcpp::R_390_PC16DBL:
      status = S390_relocate_functions<size>::pcrela16dbl(view, value, address);
      break;

    case elfcpp::R_390_PLT12DBL:
    case elfcpp::R_390_PC12DBL:
      status = S390_relocate_functions<size>::pcrela12dbl(view, value, address);
      break;

    case elfcpp::R_390_GOTENT:
    case elfcpp::R_390_GOTPLTENT:
    case elfcpp::R_390_TLS_IEENT:
      value += target->got_address();
      status = S390_relocate_functions<size>::pcrela32dbl(view, value, address);
      break;

    case elfcpp::R_390_COPY:
    case elfcpp::R_390_GLOB_DAT:
    case elfcpp::R_390_JMP_SLOT:
    case elfcpp::R_390_RELATIVE:
    case elfcpp::R_390_IRELATIVE:
      // These are outstanding tls relocs, which are unexpected when linking
    case elfcpp::R_390_TLS_TPOFF:
    case elfcpp::R_390_TLS_DTPMOD:
    case elfcpp::R_390_TLS_DTPOFF:
      gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
			     _("unexpected reloc %u in object file"),
			     r_type);
      break;

    default:
      gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
			     _("unsupported reloc %u"),
			     r_type);
      break;
    }

  if (status != S390_relocate_functions<size>::STATUS_OK)
    {
      gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
			     _("relocation overflow"));
    }

  return true;
}

// Perform a TLS relocation.

template<int size>
inline typename elfcpp::Elf_types<size>::Elf_Addr
Target_s390<size>::Relocate::relocate_tls(
    const Relocate_info<size, true>* relinfo,
    Target_s390<size>* target,
    size_t relnum,
    const elfcpp::Rela<size, true>& rela,
    unsigned int r_type,
    const Sized_symbol<size>* gsym,
    const Symbol_value<size>* psymval,
    unsigned char* view,
    section_size_type view_size)
{
  Output_segment* tls_segment = relinfo->layout->tls_segment();

  const Sized_relobj_file<size, true>* object = relinfo->object;
  const elfcpp::Elf_Xword addend = rela.get_r_addend();
  elfcpp::Shdr<size, true> data_shdr(relinfo->data_shdr);
  bool is_allocatable = (data_shdr.get_sh_flags() & elfcpp::SHF_ALLOC) != 0;

  typename elfcpp::Elf_types<size>::Elf_Addr value
      = psymval->value(relinfo->object, addend);

  const bool is_final = (gsym == NULL
			 ? !parameters->options().shared()
			 : gsym->final_value_is_known());
  tls::Tls_optimization optimized_type
      = Target_s390<size>::optimize_tls_reloc(is_final, r_type);
  switch (r_type)
    {
    case elfcpp::R_390_TLS_GDCALL:            // Global-dynamic marker
      if (optimized_type == tls::TLSOPT_TO_LE)
	{
	  if (tls_segment == NULL)
	    {
	      gold_assert(parameters->errors()->error_count() > 0
			  || issue_undefined_symbol_error(gsym));
	      return 0;
	    }
	  this->tls_gd_to_le(relinfo, relnum, rela, view, view_size);
	  break;
	}
      else
	{
	  if (optimized_type == tls::TLSOPT_TO_IE)
	    {
	      this->tls_gd_to_ie(relinfo, relnum, rela, view, view_size);
	      break;
	    }
	  else if (optimized_type == tls::TLSOPT_NONE)
	    {
	      break;
	    }
	}
      gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
			     _("unsupported reloc %u"), r_type);
      break;

    case elfcpp::R_390_TLS_GD32:            // Global-dynamic
    case elfcpp::R_390_TLS_GD64:
      if (optimized_type == tls::TLSOPT_TO_LE)
	{
	  if (tls_segment == NULL)
	    {
	      gold_assert(parameters->errors()->error_count() > 0
			  || issue_undefined_symbol_error(gsym));
	      return 0;
	    }
	  return value - tls_segment->memsz();
	}
      else
	{
	  unsigned int got_type = (optimized_type == tls::TLSOPT_TO_IE
				   ? GOT_TYPE_TLS_OFFSET
				   : GOT_TYPE_TLS_PAIR);
	  if (gsym != NULL)
	    {
	      gold_assert(gsym->has_got_offset(got_type));
	      return (gsym->got_offset(got_type)
		      + target->got_main_offset()
		      + addend);
	    }
	  else
	    {
	      unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
	      gold_assert(object->local_has_got_offset(r_sym, got_type));
	      return (object->local_got_offset(r_sym, got_type)
		      + target->got_main_offset()
		      + addend);
	    }
	}
      gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
			     _("unsupported reloc %u"), r_type);
      break;

    case elfcpp::R_390_TLS_LDCALL:            // Local-dynamic marker
      // This is a marker relocation. If the sequence is being turned to LE,
      // we modify the instruction, otherwise the instruction is untouched.
      if (optimized_type == tls::TLSOPT_TO_LE)
	{
	  if (tls_segment == NULL)
	    {
	      gold_assert(parameters->errors()->error_count() > 0
			  || issue_undefined_symbol_error(gsym));
	      return 0;
	    }
	  this->tls_ld_to_le(relinfo, relnum, rela, view, view_size);
	  break;
	}
      else if (optimized_type == tls::TLSOPT_NONE)
	{
	  break;
	}
      gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
			     _("unsupported reloc %u"), r_type);
      break;

    case elfcpp::R_390_TLS_LDM32:            // Local-dynamic module
    case elfcpp::R_390_TLS_LDM64:
      if (optimized_type == tls::TLSOPT_TO_LE)
	{
	  if (tls_segment == NULL)
	    {
	      gold_assert(parameters->errors()->error_count() > 0
			  || issue_undefined_symbol_error(gsym));
	      return 0;
	    }
	  // Doesn't matter what we fill it with - it's going to be unused.
	  return 0;
	}
      else if (optimized_type == tls::TLSOPT_NONE)
	{
	  // Relocate the field with the offset of the GOT entry for
	  // the module index.
	  return (target->got_mod_index_entry(NULL, NULL, NULL)
		  + addend
		  + target->got_main_offset());
	}
      gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
			     _("unsupported reloc %u"), r_type);
      break;

    case elfcpp::R_390_TLS_LDO32:         // Local-dynamic offset
    case elfcpp::R_390_TLS_LDO64:
      // This relocation type is used in debugging information.
      // In that case we need to not optimize the value.  If the
      // section is not allocatable, then we assume we should not
      // optimize this reloc.
      if (optimized_type == tls::TLSOPT_TO_LE && is_allocatable)
	{
	  if (tls_segment == NULL)
	    {
	      gold_assert(parameters->errors()->error_count() > 0
			  || issue_undefined_symbol_error(gsym));
	      return 0;
	    }
	  value -= tls_segment->memsz();
	}
      return value;

    case elfcpp::R_390_TLS_LOAD:         // Initial-exec marker
      // This is a marker relocation. If the sequence is being turned to LE,
      // we modify the instruction, otherwise the instruction is untouched.
      if (gsym != NULL
	  && gsym->is_undefined()
	  && parameters->options().output_is_executable())
	{
	  Target_s390<size>::Relocate::tls_ie_to_le(relinfo, relnum,
						      rela, view,
						      view_size);
	  break;
	}
      else if (optimized_type == tls::TLSOPT_TO_LE)
	{
	  if (tls_segment == NULL)
	    {
	      gold_assert(parameters->errors()->error_count() > 0
			  || issue_undefined_symbol_error(gsym));
	      return 0;
	    }
	  Target_s390<size>::Relocate::tls_ie_to_le(relinfo, relnum,
						      rela, view,
						      view_size);
	  break;
	}
      else if (optimized_type == tls::TLSOPT_NONE)
	{
	  break;
	}
      gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
			     _("unsupported reloc type %u"),
			     r_type);
      break;

    case elfcpp::R_390_TLS_GOTIE12:       // Initial-exec, not optimizable
    case elfcpp::R_390_TLS_GOTIE20:
    case elfcpp::R_390_TLS_IEENT:
    case elfcpp::R_390_TLS_GOTIE32:       // Initial-exec, optimizable
    case elfcpp::R_390_TLS_GOTIE64:
    case elfcpp::R_390_TLS_IE32:
    case elfcpp::R_390_TLS_IE64:
      if (gsym != NULL
	  && gsym->is_undefined()
	  && parameters->options().output_is_executable()
	  // These three cannot be optimized to LE, no matter what
	  && r_type != elfcpp::R_390_TLS_GOTIE12
	  && r_type != elfcpp::R_390_TLS_GOTIE20
	  && r_type != elfcpp::R_390_TLS_IEENT)
	{
          return value;
	}
      else if (optimized_type == tls::TLSOPT_TO_LE)
	{
	  if (tls_segment == NULL)
	    {
	      gold_assert(parameters->errors()->error_count() > 0
			  || issue_undefined_symbol_error(gsym));
	      return 0;
	    }
          return value - tls_segment->memsz();
	}
      else if (optimized_type == tls::TLSOPT_NONE)
	{
	  // Relocate the field with the offset of the GOT entry for
	  // the tp-relative offset of the symbol.
	  unsigned int got_offset;
	  if (gsym != NULL)
	    {
	      gold_assert(gsym->has_got_offset(GOT_TYPE_TLS_OFFSET));
	      got_offset = gsym->got_offset(GOT_TYPE_TLS_OFFSET);
	    }
	  else
	    {
	      unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
	      gold_assert(object->local_has_got_offset(r_sym,
						       GOT_TYPE_TLS_OFFSET));
	      got_offset = object->local_got_offset(r_sym, GOT_TYPE_TLS_OFFSET);
	    }
	  got_offset += target->got_main_offset();
	  if (r_type == elfcpp::R_390_TLS_IE32
	      || r_type == elfcpp::R_390_TLS_IE64)
	    return target->got_address() + got_offset + addend;
	  else
	    return got_offset + addend;
	}
      gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
			     _("unsupported reloc type %u"),
			     r_type);
      break;

    case elfcpp::R_390_TLS_LE32:          // Local-exec
    case elfcpp::R_390_TLS_LE64:
      if (tls_segment == NULL)
	{
	  gold_assert(parameters->errors()->error_count() > 0
		      || issue_undefined_symbol_error(gsym));
	  return 0;
	}
      return value - tls_segment->memsz();
    }
  return 0;
}

// Do a relocation in which we convert a TLS General-Dynamic to an
// Initial-Exec.

template<int size>
inline void
Target_s390<size>::Relocate::tls_gd_to_ie(
    const Relocate_info<size, true>* relinfo,
    size_t relnum,
    const elfcpp::Rela<size, true>& rela,
    unsigned char* view,
    section_size_type view_size)
{
  tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size, 4);
  if (view[0] == 0x4d)
    {
      // bas, don't care about details
      // Change to l %r2, 0(%r2, %r12)
      view[0] = 0x58;
      view[1] = 0x22;
      view[2] = 0xc0;
      view[3] = 0x00;
      return;
    }
  else if (view[0] == 0xc0)
    {
      tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size, 6);
      // brasl %r14, __tls_get_offset@plt
      if (view[1] == 0xe5)
	{
	  // Change to l/lg %r2, 0(%r2, %r12)
	  // There was a PLT32DBL reloc at the last 4 bytes, overwrite its result.
	  if (size == 32)
	    {
	      // l
	      view[0] = 0x58;
	      view[1] = 0x22;
	      view[2] = 0xc0;
	      view[3] = 0x00;
	      // nop
	      view[4] = 0x07;
	      view[5] = 0x07;
	    }
	  else
	    {
	      // lg
	      view[0] = 0xe3;
	      view[1] = 0x22;
	      view[2] = 0xc0;
	      view[3] = 0;
	      view[4] = 0;
	      view[5] = 0x04;
	    }
	  return;
	}
    }
  gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
			 _("unsupported op for GD to IE"));
}

// Do a relocation in which we convert a TLS General-Dynamic to a
// Local-Exec.

template<int size>
inline void
Target_s390<size>::Relocate::tls_gd_to_le(
    const Relocate_info<size, true>* relinfo,
    size_t relnum,
    const elfcpp::Rela<size, true>& rela,
    unsigned char* view,
    section_size_type view_size)
{
  tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size, 2);
  if (view[0] == 0x0d)
    {
      // basr, change to nop
      view[0] = 0x07;
      view[1] = 0x07;
    }
  else if (view[0] == 0x4d)
    {
      tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size, 4);
      // bas, don't care about details, change to nop
      view[0] = 0x47;
      view[1] = 0;
      view[2] = 0;
      view[3] = 0;
      return;
    }
  else if (view[0] == 0xc0)
    {
      tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size, 6);
      // brasl %r14, __tls_get_offset@plt
      if (view[1] == 0xe5)
	{
	  // Change to nop jump. There was a PLT32DBL reloc at the last
	  // 4 bytes, overwrite its result.
	  view[1] = 0x04;
	  view[2] = 0;
	  view[3] = 0;
	  view[4] = 0;
	  view[5] = 0;
	  return;
	}
    }
  gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
			 _("unsupported op for GD to LE"));
}

template<int size>
inline void
Target_s390<size>::Relocate::tls_ld_to_le(
    const Relocate_info<size, true>* relinfo,
    size_t relnum,
    const elfcpp::Rela<size, true>& rela,
    unsigned char* view,
    section_size_type view_size)
{
  tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size, 4);

  if (view[0] == 0x0d)
    {
      // basr, change to nop
      view[0] = 0x07;
      view[1] = 0x07;
    }
  else if (view[0] == 0x4d)
    {
      // bas, don't care about details, change to nop
      view[0] = 0x47;
      view[1] = 0;
      view[2] = 0;
      view[3] = 0;
      return;
    }
  else if (view[0] == 0xc0)
    {
      tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size, 6);
      // brasl %r14, __tls_get_offset@plt
      if (view[1] == 0xe5)
	{
	  // Change to nop jump. There was a PLT32DBL reloc at the last
	  // 4 bytes, overwrite its result.
	  view[1] = 0x04;
	  view[2] = 0;
	  view[3] = 0;
	  view[4] = 0;
	  view[5] = 0;
	  return;
	}
    }
  gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
			 _("unsupported op for LD to LE"));
}

// Do a relocation in which we convert a TLS Initial-Exec to a
// Local-Exec.

template<int size>
inline void
Target_s390<size>::Relocate::tls_ie_to_le(
    const Relocate_info<size, true>* relinfo,
    size_t relnum,
    const elfcpp::Rela<size, true>& rela,
    unsigned char* view,
    section_size_type view_size)
{
  tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size, 4);

  if (view[0] == 0x58)
    {
      // l %rX, 0(%rY) or l %rX, 0(%rY, %r12)
      if ((view[2] & 0x0f) != 0 || view[3] != 0)
	goto err;
      int rx = view[1] >> 4 & 0xf;
      int ry = view[1] & 0xf;
      int rz = view[2] >> 4 & 0xf;
      if (rz == 0)
	{
	}
      else if (ry == 0)
	{
	  ry = rz;
	}
      else if (rz == 12)
	{
	}
      else if (ry == 12)
	{
	  ry = rz;
	}
      else
	goto err;
      // to lr %rX, $rY
      view[0] = 0x18;
      view[1] = rx << 4 | ry;
      // and insert a nop
      view[2] = 0x07;
      view[3] = 0x00;
    }
  else if (view[0] == 0xe3)
    {
      tls::check_range(relinfo, relnum, rela.get_r_offset(), view_size, 6);
      // lg %rX, 0(%rY) or lg %rX, 0(%rY, %r12)
      if ((view[2] & 0x0f) != 0 ||
	  view[3] != 0 ||
	  view[4] != 0 ||
	  view[5] != 0x04)
	goto err;
      int rx = view[1] >> 4 & 0xf;
      int ry = view[1] & 0xf;
      int rz = view[2] >> 4 & 0xf;
      if (rz == 0)
	{
	}
      else if (ry == 0)
	{
	  ry = rz;
	}
      else if (rz == 12)
	{
	}
      else if (ry == 12)
	{
	  ry = rz;
	}
      else
	goto err;
      // to sllg %rX, $rY, 0
      view[0] = 0xeb;
      view[1] = rx << 4 | ry;
      view[2] = 0x00;
      view[3] = 0x00;
      view[4] = 0x00;
      view[5] = 0x0d;
    }
  else
    {
err:
      gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
			     _("unsupported op for IE to LE"));
    }
}

// Scan relocations for a section.

template<int size>
void
Target_s390<size>::scan_relocs(Symbol_table* symtab,
				 Layout* layout,
				 Sized_relobj_file<size, true>* object,
				 unsigned int data_shndx,
				 unsigned int sh_type,
				 const unsigned char* prelocs,
				 size_t reloc_count,
				 Output_section* output_section,
				 bool needs_special_offset_handling,
				 size_t local_symbol_count,
				 const unsigned char* plocal_symbols)
{
  typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, true>
      Classify_reloc;

  if (sh_type == elfcpp::SHT_REL)
    {
      gold_error(_("%s: unsupported REL reloc section"),
		 object->name().c_str());
      return;
    }

  gold::scan_relocs<size, true, Target_s390<size>, Scan, Classify_reloc>(
    symtab,
    layout,
    this,
    object,
    data_shndx,
    prelocs,
    reloc_count,
    output_section,
    needs_special_offset_handling,
    local_symbol_count,
    plocal_symbols);
}

// Finalize the sections.

template<int size>
void
Target_s390<size>::do_finalize_sections(
    Layout* layout,
    const Input_objects*,
    Symbol_table* symtab)
{
  const Reloc_section* rel_plt = (this->plt_ == NULL
				  ? NULL
				  : this->plt_->rela_plt());
  layout->add_target_dynamic_tags(false, this->got_plt_, rel_plt,
				  this->rela_dyn_, true, size == 32);

  this->layout_ = layout;

  // Emit any relocs we saved in an attempt to avoid generating COPY
  // relocs.
  if (this->copy_relocs_.any_saved_relocs())
    this->copy_relocs_.emit(this->rela_dyn_section(layout));

  // Set the size of the _GLOBAL_OFFSET_TABLE_ symbol to the size of
  // the .got section.
  Symbol* sym = this->global_offset_table_;
  if (sym != NULL)
    {
      uint64_t data_size = this->got_->current_data_size();
      symtab->get_sized_symbol<size>(sym)->set_symsize(data_size);
    }

  if (parameters->doing_static_link()
      && (this->plt_ == NULL || !this->plt_->has_irelative_section()))
    {
      // If linking statically, make sure that the __rela_iplt symbols
      // were defined if necessary, even if we didn't create a PLT.
      static const Define_symbol_in_segment syms[] =
	{
	  {
	    "__rela_iplt_start",	// name
	    elfcpp::PT_LOAD,		// segment_type
	    elfcpp::PF_W,		// segment_flags_set
	    elfcpp::PF(0),		// segment_flags_clear
	    0,				// value
	    0,				// size
	    elfcpp::STT_NOTYPE,		// type
	    elfcpp::STB_GLOBAL,		// binding
	    elfcpp::STV_HIDDEN,		// visibility
	    0,				// nonvis
	    Symbol::SEGMENT_START,	// offset_from_base
	    true			// only_if_ref
	  },
	  {
	    "__rela_iplt_end",		// name
	    elfcpp::PT_LOAD,		// segment_type
	    elfcpp::PF_W,		// segment_flags_set
	    elfcpp::PF(0),		// segment_flags_clear
	    0,				// value
	    0,				// size
	    elfcpp::STT_NOTYPE,		// type
	    elfcpp::STB_GLOBAL,		// binding
	    elfcpp::STV_HIDDEN,		// visibility
	    0,				// nonvis
	    Symbol::SEGMENT_START,	// offset_from_base
	    true			// only_if_ref
	  }
	};

      symtab->define_symbols(layout, 2, syms,
			     layout->script_options()->saw_sections_clause());
    }
}

// Scan the relocs during a relocatable link.

template<int size>
void
Target_s390<size>::scan_relocatable_relocs(
    Symbol_table* symtab,
    Layout* layout,
    Sized_relobj_file<size, true>* object,
    unsigned int data_shndx,
    unsigned int sh_type,
    const unsigned char* prelocs,
    size_t reloc_count,
    Output_section* output_section,
    bool needs_special_offset_handling,
    size_t local_symbol_count,
    const unsigned char* plocal_symbols,
    Relocatable_relocs* rr)
{
  typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, true>
      Classify_reloc;
  typedef gold::Default_scan_relocatable_relocs<Classify_reloc>
      Scan_relocatable_relocs;

  gold_assert(sh_type == elfcpp::SHT_RELA);

  gold::scan_relocatable_relocs<size, true, Scan_relocatable_relocs>(
    symtab,
    layout,
    object,
    data_shndx,
    prelocs,
    reloc_count,
    output_section,
    needs_special_offset_handling,
    local_symbol_count,
    plocal_symbols,
    rr);
}

// Scan the relocs for --emit-relocs.

template<int size>
void
Target_s390<size>::emit_relocs_scan(
    Symbol_table* symtab,
    Layout* layout,
    Sized_relobj_file<size, true>* object,
    unsigned int data_shndx,
    unsigned int sh_type,
    const unsigned char* prelocs,
    size_t reloc_count,
    Output_section* output_section,
    bool needs_special_offset_handling,
    size_t local_symbol_count,
    const unsigned char* plocal_syms,
    Relocatable_relocs* rr)
{
  typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, true>
      Classify_reloc;
  typedef gold::Default_emit_relocs_strategy<Classify_reloc>
      Emit_relocs_strategy;

  gold_assert(sh_type == elfcpp::SHT_RELA);

  gold::scan_relocatable_relocs<size, true, Emit_relocs_strategy>(
    symtab,
    layout,
    object,
    data_shndx,
    prelocs,
    reloc_count,
    output_section,
    needs_special_offset_handling,
    local_symbol_count,
    plocal_syms,
    rr);
}

// Relocate a section during a relocatable link.

template<int size>
void
Target_s390<size>::relocate_relocs(
    const Relocate_info<size, true>* relinfo,
    unsigned int sh_type,
    const unsigned char* prelocs,
    size_t reloc_count,
    Output_section* output_section,
    typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
    unsigned char* view,
    typename elfcpp::Elf_types<size>::Elf_Addr view_address,
    section_size_type view_size,
    unsigned char* reloc_view,
    section_size_type reloc_view_size)
{
  typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, true>
      Classify_reloc;

  gold_assert(sh_type == elfcpp::SHT_RELA);

  gold::relocate_relocs<size, true, Classify_reloc>(
    relinfo,
    prelocs,
    reloc_count,
    output_section,
    offset_in_output_section,
    view,
    view_address,
    view_size,
    reloc_view,
    reloc_view_size);
}

// Return the offset to use for the GOT_INDX'th got entry which is
// for a local tls symbol specified by OBJECT, SYMNDX.
template<int size>
int64_t
Target_s390<size>::do_tls_offset_for_local(
    const Relobj*,
    unsigned int,
    unsigned int) const
{
  // The only way we can get called is when IEENT/GOTIE12/GOTIE20
  // couldn't be optimised to LE.
  Output_segment* tls_segment = layout_->tls_segment();
  return -tls_segment->memsz();
}

// Return the offset to use for the GOT_INDX'th got entry which is
// for global tls symbol GSYM.
template<int size>
int64_t
Target_s390<size>::do_tls_offset_for_global(
    Symbol*,
    unsigned int) const
{
  Output_segment* tls_segment = layout_->tls_segment();
  return -tls_segment->memsz();
}

// Return the value to use for a dynamic which requires special
// treatment.  This is how we support equality comparisons of function
// pointers across shared library boundaries, as described in the
// processor specific ABI supplement.

template<int size>
uint64_t
Target_s390<size>::do_dynsym_value(const Symbol* gsym) const
{
  gold_assert(gsym->is_from_dynobj() && gsym->has_plt_offset());
  return this->plt_address_for_global(gsym);
}

// Return a string used to fill a code section with nops to take up
// the specified length.

template<int size>
std::string
Target_s390<size>::do_code_fill(section_size_type length) const
{
  if (length & 1)
    gold_warning(_("S/390 code fill of odd length requested"));
  return std::string(length, static_cast<char>(0x07));
}

// Return whether SYM should be treated as a call to a non-split
// function.  We don't want that to be true of a larl instruction
// that merely loads its address.

template<int size>
bool
Target_s390<size>::do_is_call_to_non_split(const Symbol* sym,
					   const unsigned char* preloc,
					   const unsigned char* view,
					   section_size_type view_size) const
{
  if (sym->type() != elfcpp::STT_FUNC)
    return false;
  typename Reloc_types<elfcpp::SHT_RELA, size, true>::Reloc reloc(preloc);
  typename elfcpp::Elf_types<size>::Elf_WXword r_info
    = reloc.get_r_info();
  unsigned int r_type = elfcpp::elf_r_type<size>(r_info);
  section_offset_type offset = reloc.get_r_offset();
  switch (r_type)
    {
    // PLT refs always involve calling the function.
    case elfcpp::R_390_PLT12DBL:
    case elfcpp::R_390_PLT16DBL:
    case elfcpp::R_390_PLT24DBL:
    case elfcpp::R_390_PLT32:
    case elfcpp::R_390_PLT32DBL:
    case elfcpp::R_390_PLT64:
    case elfcpp::R_390_PLTOFF16:
    case elfcpp::R_390_PLTOFF32:
    case elfcpp::R_390_PLTOFF64:
    // Could be used for calls for -msmall-exec.
    case elfcpp::R_390_PC16DBL:
      return true;

    // Tricky case.  When used in a brasl, jg, and other branch instructions,
    // it's a call or a sibcall.  However, when used in larl, it only loads
    // the function's address - not a call.
    case elfcpp::R_390_PC32DBL:
      {
	if (offset < 2
	    || offset + 4 > static_cast<section_offset_type>(view_size))
	  {
	    // Should not happen.
	    gold_error(_("instruction with PC32DBL not wholly within section"));
	    return false;
	  }

	uint8_t op0 = view[offset-2];
	uint8_t op1 = view[offset-1] & 0xf;

	// LARL
	if (op0 == 0xc0 && op1 == 0)
	  return false;

	// Otherwise, it's either a call instruction, a branch instruction
	// (used as a sibcall), or a data manipulation instruction (which
	// has no business being used on a function, and can be ignored).
        return true;
      }

    // Otherwise, it's probably not a call.
    default:
      return false;
    }
}

// Code sequences to match below.

template<int size>
const unsigned char
Target_s390<size>::ss_code_bras_8[] = {
  0xa7, 0x15, 0x00, 0x06,		// bras %r1, .+0xc
};

template<int size>
const unsigned char
Target_s390<size>::ss_code_l_basr[] = {
  0x58, 0xe0, 0x10, 0x00,		// l %r14, 0(%r1)
  0x58, 0x10, 0x10, 0x04,		// l %r1, 4(%r1)
  0x0d, 0xee,				// basr %r14, %r14
};

template<int size>
const unsigned char
Target_s390<size>::ss_code_a_basr[] = {
  0x18, 0xe1,				// lr %r14, %r1
  0x5a, 0xe0, 0x10, 0x00,		// a %r14, 0(%r1)
  0x5a, 0x10, 0x10, 0x04,		// a %r1, 4(%r1)
  0x0d, 0xee,				// basr %r14, %r14
};

template<int size>
const unsigned char
Target_s390<size>::ss_code_larl[] = {
  0xc0, 0x10,				// larl %r1, ...
};

template<int size>
const unsigned char
Target_s390<size>::ss_code_brasl[] = {
  0xc0, 0xe5,				// brasl %r14, ...
};

template<int size>
const unsigned char
Target_s390<size>::ss_code_jg[] = {
  0xc0, 0xf4,				// jg ...
};

template<int size>
const unsigned char
Target_s390<size>::ss_code_jgl[] = {
  0xc0, 0x44,				// jgl ...
};

template<>
bool
Target_s390<32>::ss_match_st_r14(unsigned char* view,
				 section_size_type view_size,
				 section_offset_type *offset) const
{
  static const unsigned char ss_code_st_r14[] = {
    0x50, 0xe0, 0xf0, 0x04,		// st %r14, 4(%r15)
  };
  if (!this->match_view_u(view, view_size, *offset, ss_code_st_r14,
			  sizeof ss_code_st_r14))
    return false;
  *offset += sizeof ss_code_st_r14;
  return true;
}

template<>
bool
Target_s390<64>::ss_match_st_r14(unsigned char* view,
				 section_size_type view_size,
				 section_offset_type *offset) const
{
  static const unsigned char ss_code_st_r14[] = {
    0xe3, 0xe0, 0xf0, 0x08, 0x00, 0x24	// stg %r14, 8(%r15)
  };
  if (!this->match_view_u(view, view_size, *offset, ss_code_st_r14,
			  sizeof ss_code_st_r14))
    return false;
  *offset += sizeof ss_code_st_r14;
  return true;
}

template<>
bool
Target_s390<32>::ss_match_l_r14(unsigned char* view,
				section_size_type view_size,
				section_offset_type *offset) const
{
  static const unsigned char ss_code_l_r14[] = {
    0x58, 0xe0, 0xf0, 0x04,		// l %r14, 4(%r15)
  };
  if (!this->match_view_u(view, view_size, *offset, ss_code_l_r14,
			  sizeof ss_code_l_r14))
    return false;
  *offset += sizeof ss_code_l_r14;
  return true;
}

template<>
bool
Target_s390<64>::ss_match_l_r14(unsigned char* view,
				section_size_type view_size,
				section_offset_type *offset) const
{
  static const unsigned char ss_code_l_r14[] = {
    0xe3, 0xe0, 0xf0, 0x08, 0x00, 0x04	// lg %r14, 8(%r15)
  };
  if (!this->match_view_u(view, view_size, *offset, ss_code_l_r14,
			  sizeof ss_code_l_r14))
    return false;
  *offset += sizeof ss_code_l_r14;
  return true;
}

template<int size>
bool
Target_s390<size>::ss_match_mcount(unsigned char* view,
				   section_size_type view_size,
				   section_offset_type *offset) const
{
  // Match the mcount call sequence.
  section_offset_type myoff = *offset;

  // First, look for the store instruction saving %r14.
  if (!this->ss_match_st_r14(view, view_size, &myoff))
    return false;

  // Now, param load and the actual call.
  if (this->match_view_u(view, view_size, myoff, ss_code_larl,
			 sizeof ss_code_larl))
    {
      myoff += sizeof ss_code_larl + 4;

      // After larl, expect a brasl.
      if (!this->match_view_u(view, view_size, myoff, ss_code_brasl,
			      sizeof ss_code_brasl))
	return false;
      myoff += sizeof ss_code_brasl + 4;
    }
  else if (size == 32 &&
	   this->match_view_u(view, view_size, myoff, ss_code_bras_8,
			      sizeof ss_code_bras_8))
    {
      // The bras skips over a block of 8 bytes, loading its address
      // to %r1.
      myoff += sizeof ss_code_bras_8 + 8;

      // Now, there are two sequences used for actual load and call,
      // absolute and PIC.
      if (this->match_view_u(view, view_size, myoff, ss_code_l_basr,
			     sizeof ss_code_l_basr))
        myoff += sizeof ss_code_l_basr;
      else if (this->match_view_u(view, view_size, myoff, ss_code_a_basr,
				  sizeof ss_code_a_basr))
        myoff += sizeof ss_code_a_basr;
      else
	return false;
    }
  else
    return false;

  // Finally, a load bringing %r14 back.
  if (!this->ss_match_l_r14(view, view_size, &myoff))
    return false;

  // Found it.
  *offset = myoff;
  return true;
}

template<>
bool
Target_s390<32>::ss_match_ear(unsigned char* view,
				section_size_type view_size,
				section_offset_type *offset) const
{
  static const unsigned char ss_code_ear[] = {
    0xb2, 0x4f, 0x00, 0x10,		// ear %r1, %a0
  };
  if (!this->match_view_u(view, view_size, *offset, ss_code_ear,
			  sizeof ss_code_ear))
    return false;
  *offset += sizeof ss_code_ear;
  return true;
}

template<>
bool
Target_s390<64>::ss_match_ear(unsigned char* view,
				section_size_type view_size,
				section_offset_type *offset) const
{
  static const unsigned char ss_code_ear[] = {
    0xb2, 0x4f, 0x00, 0x10,		// ear %r1, %a0
    0xeb, 0x11, 0x00, 0x20, 0x00, 0x0d,	// sllg %r1,%r1,32
    0xb2, 0x4f, 0x00, 0x11,		// ear %r1, %a1
  };
  if (!this->match_view_u(view, view_size, *offset, ss_code_ear,
			  sizeof ss_code_ear))
    return false;
  *offset += sizeof ss_code_ear;
  return true;
}

template<>
bool
Target_s390<32>::ss_match_c(unsigned char* view,
				section_size_type view_size,
				section_offset_type *offset) const
{
  static const unsigned char ss_code_c[] = {
    0x59, 0xf0, 0x10, 0x20,		// c %r15, 0x20(%r1)
  };
  if (!this->match_view_u(view, view_size, *offset, ss_code_c,
			  sizeof ss_code_c))
    return false;
  *offset += sizeof ss_code_c;
  return true;
}

template<>
bool
Target_s390<64>::ss_match_c(unsigned char* view,
				section_size_type view_size,
				section_offset_type *offset) const
{
  static const unsigned char ss_code_c[] = {
    0xe3, 0xf0, 0x10, 0x38, 0x00, 0x20,	// cg %r15, 0x38(%r1)
  };
  if (!this->match_view_u(view, view_size, *offset, ss_code_c,
			  sizeof ss_code_c))
    return false;
  *offset += sizeof ss_code_c;
  return true;
}

template<>
bool
Target_s390<32>::ss_match_l(unsigned char* view,
			    section_size_type view_size,
			    section_offset_type *offset,
			    int *guard_reg) const
{
  // l %guard_reg, 0x20(%r1)
  if (convert_to_section_size_type(*offset + 4) > view_size
      || view[*offset] != 0x58
      || (view[*offset + 1] & 0xf) != 0x0
      || view[*offset + 2] != 0x10
      || view[*offset + 3] != 0x20)
    return false;
  *offset += 4;
  *guard_reg = view[*offset + 1] >> 4 & 0xf;
  return true;
}

template<>
bool
Target_s390<64>::ss_match_l(unsigned char* view,
			    section_size_type view_size,
			    section_offset_type *offset,
			    int *guard_reg) const
{
  // lg %guard_reg, 0x38(%r1)
  if (convert_to_section_size_type(*offset + 6) > view_size
      || view[*offset] != 0xe3
      || (view[*offset + 1] & 0xf) != 0x0
      || view[*offset + 2] != 0x10
      || view[*offset + 3] != 0x38
      || view[*offset + 4] != 0x00
      || view[*offset + 5] != 0x04)
    return false;
  *offset += 6;
  *guard_reg = view[*offset + 1] >> 4 & 0xf;
  return true;
}

template<int size>
bool
Target_s390<size>::ss_match_ahi(unsigned char* view,
				section_size_type view_size,
				section_offset_type *offset,
				int guard_reg,
				uint32_t *arg) const
{
  int op = size == 32 ? 0xa : 0xb;
  // a[g]hi %guard_reg, <arg>
  if (convert_to_section_size_type(*offset + 4) > view_size
      || view[*offset] != 0xa7
      || view[*offset + 1] != (guard_reg << 4 | op)
      // Disallow negative size.
      || view[*offset + 2] & 0x80)
    return false;
  *arg = elfcpp::Swap<16, true>::readval(view + *offset + 2);
  *offset += 4;
  return true;
}

template<int size>
bool
Target_s390<size>::ss_match_alfi(unsigned char* view,
				 section_size_type view_size,
				 section_offset_type *offset,
				 int guard_reg,
				 uint32_t *arg) const
{
  int op = size == 32 ? 0xb : 0xa;
  // al[g]fi %guard_reg, <arg>
  if (convert_to_section_size_type(*offset + 6) > view_size
      || view[*offset] != 0xc2
      || view[*offset + 1] != (guard_reg << 4 | op))
    return false;
  *arg = elfcpp::Swap<32, true>::readval(view + *offset + 2);
  *offset += 6;
  return true;
}

template<>
bool
Target_s390<32>::ss_match_cr(unsigned char* view,
			     section_size_type view_size,
			     section_offset_type *offset,
			     int guard_reg) const
{
  // cr %r15, %guard_reg
  if (convert_to_section_size_type(*offset + 2) > view_size
      || view[*offset] != 0x19
      || view[*offset + 1] != (0xf0 | guard_reg))
    return false;
  *offset += 2;
  return true;
}

template<>
bool
Target_s390<64>::ss_match_cr(unsigned char* view,
			     section_size_type view_size,
			     section_offset_type *offset,
			     int guard_reg) const
{
  // cgr %r15, %guard_reg
  if (convert_to_section_size_type(*offset + 4) > view_size
      || view[*offset] != 0xb9
      || view[*offset + 1] != 0x20
      || view[*offset + 2] != 0x00
      || view[*offset + 3] != (0xf0 | guard_reg))
    return false;
  *offset += 4;
  return true;
}


// FNOFFSET in section SHNDX in OBJECT is the start of a function
// compiled with -fsplit-stack.  The function calls non-split-stack
// code.  We have to change the function so that it always ensures
// that it has enough stack space to run some random function.

template<int size>
void
Target_s390<size>::do_calls_non_split(Relobj* object, unsigned int shndx,
				      section_offset_type fnoffset,
				      section_size_type,
				      const unsigned char *prelocs,
				      size_t reloc_count,
				      unsigned char* view,
				      section_size_type view_size,
				      std::string*,
				      std::string*) const
{
  // true if there's a conditional call to __morestack in the function,
  // false if there's an unconditional one.
  bool conditional = false;
  // Offset of the byte after the compare insn, if conditional.
  section_offset_type cmpend = 0;
  // Type and immediate offset of the add instruction that adds frame size
  // to guard.
  enum {
    SS_ADD_NONE,
    SS_ADD_AHI,
    SS_ADD_ALFI,
  } fsadd_type = SS_ADD_NONE;
  section_offset_type fsadd_offset = 0;
  uint32_t fsadd_frame_size = 0;
  // Register used for loading guard.  Usually r1, but can also be r0 or r2-r5.
  int guard_reg;
  // Offset of the conditional jump.
  section_offset_type jump_offset = 0;
  // Section view and offset of param block.
  section_offset_type param_offset = 0;
  unsigned char *param_view = 0;
  section_size_type param_view_size = 0;
  // Current position in function.
  section_offset_type curoffset = fnoffset;
  // And the position of split-stack prologue.
  section_offset_type ssoffset;
  // Frame size.
  typename elfcpp::Elf_types<size>::Elf_Addr frame_size;
  // Relocation parsing.
  typedef typename Reloc_types<elfcpp::SHT_RELA, size, true>::Reloc Reltype;
  const int reloc_size = Reloc_types<elfcpp::SHT_RELA, size, true>::reloc_size;
  const unsigned char *pr = prelocs;

  // If the function was compiled with -pg, the profiling code may come before
  // the split-stack prologue.  Skip it.

  this->ss_match_mcount(view, view_size, &curoffset);
  ssoffset = curoffset;

  // First, figure out if there's a conditional call by looking for the
  // extract-tp, add, cmp sequence.

  if (this->ss_match_ear(view, view_size, &curoffset))
    {
      // Found extract-tp, now look for an add and compare.
      conditional = true;
      if (this->ss_match_c(view, view_size, &curoffset))
	{
	  // Found a direct compare of stack pointer with the guard,
	  // we're done here.
	}
      else if (this->ss_match_l(view, view_size, &curoffset, &guard_reg))
	{
	  // Found a load of guard to register, look for an add and compare.
          if (this->ss_match_ahi(view, view_size, &curoffset, guard_reg,
				 &fsadd_frame_size))
	    {
	      fsadd_type = SS_ADD_AHI;
	      fsadd_offset = curoffset - 2;
	    }
	  else if (this->ss_match_alfi(view, view_size, &curoffset, guard_reg,
				       &fsadd_frame_size))
	    {
	      fsadd_type = SS_ADD_ALFI;
	      fsadd_offset = curoffset - 4;
	    }
	  else
            {
	      goto bad;
            }
	  // Now, there has to be a compare.
          if (!this->ss_match_cr(view, view_size, &curoffset, guard_reg))
	    goto bad;
	}
      else
        {
	  goto bad;
        }
      cmpend = curoffset;
    }

  // Second, look for the call.
  if (!this->match_view_u(view, view_size, curoffset, ss_code_larl,
			  sizeof ss_code_larl))
    goto bad;
  curoffset += sizeof ss_code_larl;

  // Find out larl's operand.  It should be a local symbol in .rodata
  // section.
  for (size_t i = 0; i < reloc_count; ++i, pr += reloc_size)
    {
      Reltype reloc(pr);
      if (static_cast<section_offset_type>(reloc.get_r_offset())
          == curoffset)
        {
          typename elfcpp::Elf_types<size>::Elf_WXword r_info
            = reloc.get_r_info();
          unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
          unsigned int r_type = elfcpp::elf_r_type<size>(r_info);
          if (r_type != elfcpp::R_390_PC32DBL)
            goto bad;
          if (r_sym >= object->local_symbol_count())
            goto bad;
          Sized_relobj_file<size, true> *object_sized =
            static_cast<Sized_relobj_file<size, true> *>(object);
          const Symbol_value<size>* sym = object_sized->local_symbol(r_sym);
          bool param_shndx_ordinary;
          const unsigned int param_shndx =
            sym->input_shndx(&param_shndx_ordinary);
          if (!param_shndx_ordinary)
            goto bad;
          param_offset = sym->input_value() + reloc.get_r_addend() - 2
                         - object->output_section(param_shndx)->address()
                         - object->output_section_offset(param_shndx);
          param_view = object->get_output_view(param_shndx,
                                                  &param_view_size);
          break;
        }
    }

  if (!param_view)
    goto bad;

  curoffset += 4;

  // Now, there has to be a jump to __morestack.
  jump_offset = curoffset;

  if (this->match_view_u(view, view_size, curoffset,
                       conditional ? ss_code_jgl : ss_code_jg,
                       sizeof ss_code_jg))
    curoffset += sizeof ss_code_jg;
  else
    goto bad;

  curoffset += 4;

  // Read the frame size.
  if (convert_to_section_size_type(param_offset + size / 8) > param_view_size)
    goto bad;
  frame_size = elfcpp::Swap<size, true>::readval(param_view + param_offset);

  // Sanity check.
  if (fsadd_type != SS_ADD_NONE && fsadd_frame_size != frame_size)
    goto bad;

  // Bump the frame size.
  frame_size += parameters->options().split_stack_adjust_size();

  // Store it to the param block.
  elfcpp::Swap<size, true>::writeval(param_view + param_offset, frame_size);

  if (!conditional)
    {
      // If the call was already unconditional, we're done.
    }
  else if (frame_size <= 0xffffffff && fsadd_type == SS_ADD_ALFI)
    {
      // Using alfi to add the frame size, and it still fits.  Adjust it.
      elfcpp::Swap_unaligned<32, true>::writeval(view + fsadd_offset,
						 frame_size);
    }
  else
    {
      // We were either relying on the backoff area, or used ahi to load
      // frame size.  This won't fly, as our new frame size is too large.
      // Convert the sequence to unconditional by nopping out the comparison,
      // and rewiring the jump.
      this->set_view_to_nop(view, view_size, ssoffset, cmpend - ssoffset);

      // The jump is jgl, we'll mutate it to jg.
      view[jump_offset+1] = 0xf4;
    }

  return;

bad:
  if (!object->has_no_split_stack())
      object->error(_("failed to match split-stack sequence at "
		      "section %u offset %0zx"),
		    shndx, static_cast<size_t>(fnoffset));
}

// Relocate section data.

template<int size>
void
Target_s390<size>::relocate_section(
    const Relocate_info<size, true>* relinfo,
    unsigned int sh_type,
    const unsigned char* prelocs,
    size_t reloc_count,
    Output_section* output_section,
    bool needs_special_offset_handling,
    unsigned char* view,
    typename elfcpp::Elf_types<size>::Elf_Addr address,
    section_size_type view_size,
    const Reloc_symbol_changes* reloc_symbol_changes)
{
  typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, true>
      Classify_reloc;

  gold_assert(sh_type == elfcpp::SHT_RELA);

  gold::relocate_section<size, true, Target_s390<size>, Relocate,
			 gold::Default_comdat_behavior, Classify_reloc>(
    relinfo,
    this,
    prelocs,
    reloc_count,
    output_section,
    needs_special_offset_handling,
    view,
    address,
    view_size,
    reloc_symbol_changes);
}

// Apply an incremental relocation.  Incremental relocations always refer
// to global symbols.

template<int size>
void
Target_s390<size>::apply_relocation(
    const Relocate_info<size, true>* relinfo,
    typename elfcpp::Elf_types<size>::Elf_Addr r_offset,
    unsigned int r_type,
    typename elfcpp::Elf_types<size>::Elf_Swxword r_addend,
    const Symbol* gsym,
    unsigned char* view,
    typename elfcpp::Elf_types<size>::Elf_Addr address,
    section_size_type view_size)
{
  gold::apply_relocation<size, true, Target_s390<size>,
			 typename Target_s390<size>::Relocate>(
    relinfo,
    this,
    r_offset,
    r_type,
    r_addend,
    gsym,
    view,
    address,
    view_size);
}

// The selector for s390 object files.

template<int size>
class Target_selector_s390 : public Target_selector
{
public:
  Target_selector_s390()
    : Target_selector(elfcpp::EM_S390, size, true,
		      (size == 64 ? "elf64-s390" : "elf32-s390"),
		      (size == 64 ? "elf64_s390" : "elf32_s390"))
  { }

  virtual Target*
  do_instantiate_target()
  { return new Target_s390<size>(); }
};

Target_selector_s390<32> target_selector_s390;
Target_selector_s390<64> target_selector_s390x;

} // End anonymous namespace.
