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

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

// This file is part of gold.

// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.

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

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

#include "gold.h"

#include <cstring>

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

namespace
{

using namespace gold;

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

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

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

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

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

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

// A class to handle the PLT data.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  void
  do_adjust_output_section(Output_section* os);

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

 private:

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

    static inline int
    get_reference_flags(unsigned int r_type);

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

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

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

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

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

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

    void
    check_non_pic(Relobj*, unsigned int r_type);

    inline bool
    possible_function_pointer_reloc(unsigned int r_type);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  this->layout_ = layout;

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

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

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

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

// Scan the relocs during a relocatable link.

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

  gold_assert(sh_type == elfcpp::SHT_RELA);

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

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

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

  gold_assert(sh_type == elfcpp::SHT_RELA);

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

// Relocate a section during a relocatable link.

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

  gold_assert(sh_type == elfcpp::SHT_RELA);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// Code sequences to match below.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

  if (!param_view)
    goto bad;

  curoffset += 4;

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

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

  curoffset += 4;

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

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

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

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

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

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

  return;

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

// Relocate section data.

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

  gold_assert(sh_type == elfcpp::SHT_RELA);

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

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

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

// The selector for s390 object files.

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

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

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

} // End anonymous namespace.
