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

// Copyright (C) 2015-2024 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,
			  Output_data_got_base* got,
			  unsigned int got_indx,
			  uint64_t addend) 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,
			   Output_data_got_base* got,
			   unsigned int got_indx,
			   uint64_t addend) 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
  elfcpp::SHT_PROGBITS,	// unwind_section_type
};

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
  elfcpp::SHT_PROGBITS,	// unwind_section_type
};

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

  enum Status
  {
    STATUS_OK,
    STATUS_OVERFLOW
  };

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

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

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

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

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

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

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

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

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

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

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

};

// Initialize the PLT section.

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

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

// Add an entry to the PLT.

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

  unsigned int plt_index;
  off_t plt_offset;
  section_offset_type got_offset;

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

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

      ++*pcount;

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

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

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

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

  gsym->set_plt_offset(plt_offset);

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

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

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

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

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

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

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

  return plt_offset;
}

// Add the relocation for a PLT entry.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// The .eh_frame unwind information for the PLT.

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

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

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

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

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

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

  unsigned char* pov = oview;

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

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

  unsigned char* got_pov = got_view;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    }
  return this->got_;
}

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

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

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

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

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

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

// Create the PLT section.

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

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

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

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

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

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

// Create a PLT entry for a global symbol.

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

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

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

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

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

// Return the number of entries in the PLT.

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

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

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

// Return the size of each PLT entry.

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

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

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

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

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

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

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

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

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

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

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

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

  return this->got_;
}

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

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

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

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

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

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

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

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

  this->plt_->reserve_slot(plt_index);

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

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

// Force a COPY relocation for a given symbol.

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

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

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

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

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

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

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

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

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

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

    default:
      gold_unreachable();
    }
}

// Get the Reference_flags for a particular relocation.

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

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

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

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

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

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

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

// Report an unsupported relocation against a local symbol.

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

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

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

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

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

	default:
	  break;
	}
    }

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

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

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

// Scan a relocation for a local symbol.

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

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

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

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

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

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

	  check_non_pic(object, r_type);

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

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

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

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

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

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

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

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

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

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

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

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

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

	  default:
	    gold_unreachable();
	  }
      }
      break;

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

// Scan a relocation for a global symbol.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	  default:
	    gold_unreachable();
	  }
      }
      break;

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


// Report an unsupported relocation against a global symbol.

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

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

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

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

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

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

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

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

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

// Perform a relocation.

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

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

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

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

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

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

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

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

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

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

    default:
      break;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  return true;
}

// Perform a TLS relocation.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// Scan relocations for a section.

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

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

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

// Finalize the sections.

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

  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,
    Output_data_got_base*,
    unsigned int,
    uint64_t) 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*,
    Output_data_got_base*,
    unsigned int,
    uint64_t) 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.
