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

// Copyright (C) 2015-2016 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()));
      // fallthru
    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());
      // fallthru
    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.
