gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gold / target.h
index c2ccc638c94bfc38c916155830555034bde0e3d9..089d7b377c3b38132253286cf793ed7d6e457168 100644 (file)
@@ -1,6 +1,6 @@
 // target.h -- target support for gold   -*- C++ -*-
 
-// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+// Copyright (C) 2006-2020 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -36,6 +36,7 @@
 #include "elfcpp.h"
 #include "options.h"
 #include "parameters.h"
+#include "stringpool.h"
 #include "debug.h"
 
 namespace gold
@@ -49,18 +50,19 @@ template<int size, bool big_endian>
 class Sized_relobj_file;
 class Relocatable_relocs;
 template<int size, bool big_endian>
-class Relocate_info;
+struct Relocate_info;
 class Reloc_symbol_changes;
 class Symbol;
 template<int size>
 class Sized_symbol;
 class Symbol_table;
 class Output_data;
-template<int size, bool big_endian>
-class Output_data_got;
+class Output_data_got_base;
 class Output_section;
 class Input_objects;
 class Task;
+struct Symbol_location;
+class Versions;
 
 // The abstract class for target specific handling.
 
@@ -117,9 +119,19 @@ class Target
   { return this->pti_->dynamic_linker; }
 
   // Return the default address to use for the text segment.
+  // If a -z max-page-size argument has set the ABI page size
+  // to a value larger than the default starting address,
+  // bump the starting address up to the page size, to avoid
+  // misaligning the text segment in the file.
   uint64_t
   default_text_segment_address() const
-  { return this->pti_->default_text_segment_address; }
+  {
+    uint64_t addr = this->pti_->default_text_segment_address;
+    uint64_t pagesize = this->abi_pagesize();
+    if (addr < pagesize)
+      addr = pagesize;
+    return addr;
+  }
 
   // Return the ABI specified page size.
   uint64_t
@@ -143,6 +155,16 @@ class Target
                      this->abi_pagesize());
   }
 
+  // Return whether PF_X segments must contain nothing but the contents of
+  // SHF_EXECINSTR sections (no non-executable data, no headers).
+  bool
+  isolate_execinstr() const
+  { return this->pti_->isolate_execinstr; }
+
+  uint64_t
+  rosegment_gap() const
+  { return this->pti_->rosegment_gap; }
+
   // If we see some object files with .note.GNU-stack sections, and
   // some objects files without them, this returns whether we should
   // consider the object files without them to imply that the stack
@@ -227,9 +249,15 @@ class Target
   // Adjust the output file header before it is written out.  VIEW
   // points to the header in external form.  LEN is the length.
   void
-  adjust_elf_header(unsigned char* view, int len) const
+  adjust_elf_header(unsigned char* view, int len)
   { return this->do_adjust_elf_header(view, len); }
 
+  // Return address and size to plug into eh_frame FDEs associated with a PLT.
+  void
+  plt_fde_location(const Output_data* plt, unsigned char* oview,
+                  uint64_t* address, off_t* len) const
+  { return this->do_plt_fde_location(plt, oview, address, len); }
+
   // Return whether NAME is a local label name.  This is used to implement the
   // --discard-locals options.
   bool
@@ -246,17 +274,35 @@ class Target
   reloc_addend(void* arg, unsigned int type, uint64_t addend) const
   { return this->do_reloc_addend(arg, type, addend); }
 
-  // Return the PLT section to use for a global symbol.  This is used
-  // for STT_GNU_IFUNC symbols.
-  Output_data*
-  plt_section_for_global(const Symbol* sym) const
-  { return this->do_plt_section_for_global(sym); }
+  // Return the PLT address to use for a global symbol.
+  uint64_t
+  plt_address_for_global(const Symbol* sym) const
+  { return this->do_plt_address_for_global(sym); }
 
-  // Return the PLT section to use for a local symbol.  This is used
-  // for STT_GNU_IFUNC symbols.
-  Output_data*
-  plt_section_for_local(const Relobj* object, unsigned int symndx) const
-  { return this->do_plt_section_for_local(object, symndx); }
+  // Return the PLT address to use for a local symbol.
+  uint64_t
+  plt_address_for_local(const Relobj* object, unsigned int symndx) const
+  { return this->do_plt_address_for_local(object, 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
+  tls_offset_for_local(const Relobj* object,
+                      unsigned int symndx,
+                      unsigned int got_indx) const
+  { return do_tls_offset_for_local(object, symndx, got_indx); }
+
+  // Return the offset to use for the GOT_INDX'th got entry which is
+  // for global tls symbol GSYM.
+  int64_t
+  tls_offset_for_global(Symbol* gsym, unsigned int got_indx) const
+  { return do_tls_offset_for_global(gsym, got_indx); }
+
+  // For targets that use function descriptors, if LOC is the location
+  // of a function, modify it to point at the function entry location.
+  void
+  function_location(Symbol_location* loc) const
+  { return do_function_location(loc); }
 
   // Return whether this target can use relocation types to determine
   // if a function's address is taken.
@@ -285,13 +331,15 @@ class Target
   ehframe_datarel_base() const
   { return this->do_ehframe_datarel_base(); }
 
-  // Return true if a reference to SYM from a reloc of type R_TYPE
+  // Return true if a reference to SYM from a reloc at *PRELOC
   // means that the current function may call an object compiled
   // without -fsplit-stack.  SYM is known to be defined in an object
   // compiled without -fsplit-stack.
   bool
-  is_call_to_non_split(const Symbol* sym, unsigned int r_type) const
-  { return this->do_is_call_to_non_split(sym, r_type); }
+  is_call_to_non_split(const Symbol* sym, const unsigned char* preloc,
+                      const unsigned char* view,
+                      section_size_type view_size) const
+  { return this->do_is_call_to_non_split(sym, preloc, view, view_size); }
 
   // A function starts at OFFSET in section SHNDX in OBJECT.  That
   // function was compiled with -fsplit-stack, but it refers to a
@@ -302,10 +350,12 @@ class Target
   void
   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
   {
-    this->do_calls_non_split(object, shndx, fnoffset, fnsize, view, view_size,
+    this->do_calls_non_split(object, shndx, fnoffset, fnsize,
+                            prelocs, reloc_count, view, view_size,
                             from, to);
   }
 
@@ -343,7 +393,7 @@ class Target
       return pass < 2;
 
     return this->do_relax(pass, input_objects, symtab, layout, task);
-  } 
+  }
 
   // Return the target-specific name of attributes section.  This is
   // NULL if a target does not use attributes section or if it uses
@@ -363,7 +413,7 @@ class Target
   {
     return ((this->pti_->attributes_section != NULL
             && strcmp(name, this->pti_->attributes_section) == 0)
-           || strcmp(name, ".gnu.attributes") == 0); 
+           || strcmp(name, ".gnu.attributes") == 0);
   }
 
   // Return a bit mask of argument types for attribute with TAG.
@@ -382,7 +432,7 @@ class Target
   // which may be used for expensive, target-specific initialization.
   void
   select_as_default_target()
-  { this->do_select_as_default_target(); } 
+  { this->do_select_as_default_target(); }
 
   // Return the value to store in the EI_OSABI field in the ELF
   // header.
@@ -395,6 +445,75 @@ class Target
   set_osabi(elfcpp::ELFOSABI osabi)
   { this->osabi_ = osabi; }
 
+  // Define target-specific standard symbols.
+  void
+  define_standard_symbols(Symbol_table* symtab, Layout* layout)
+  { this->do_define_standard_symbols(symtab, layout); }
+
+  // Return the output section name to use given an input section
+  // name, or NULL if no target specific name mapping is required.
+  // Set *PLEN to the length of the name if returning non-NULL.
+  const char*
+  output_section_name(const Relobj* relobj,
+                     const char* name,
+                     size_t* plen) const
+  { return this->do_output_section_name(relobj, name, plen); }
+
+  // Add any special sections for this symbol to the gc work list.
+  void
+  gc_mark_symbol(Symbol_table* symtab, Symbol* sym) const
+  { this->do_gc_mark_symbol(symtab, sym); }
+
+  // Return the name of the entry point symbol.
+  const char*
+  entry_symbol_name() const
+  { return this->pti_->entry_symbol_name; }
+
+  // Return the size in bits of SHT_HASH entry.
+  int
+  hash_entry_size() const
+  { return this->pti_->hash_entry_size; }
+
+  // Return the section type to use for unwind sections.
+  unsigned int
+  unwind_section_type() const
+  { return this->pti_->unwind_section_type; }
+
+  // Whether the target has a custom set_dynsym_indexes method.
+  bool
+  has_custom_set_dynsym_indexes() const
+  { return this->do_has_custom_set_dynsym_indexes(); }
+
+  // Custom set_dynsym_indexes method for a target.
+  unsigned int
+  set_dynsym_indexes(std::vector<Symbol*>* dyn_symbols, unsigned int index,
+                     std::vector<Symbol*>* syms, Stringpool* dynpool,
+                     Versions* versions, Symbol_table* symtab) const
+  {
+    return this->do_set_dynsym_indexes(dyn_symbols, index, syms, dynpool,
+                                       versions, symtab);
+  }
+
+  // Get the custom dynamic tag value.
+  unsigned int
+  dynamic_tag_custom_value(elfcpp::DT tag) const
+  { return this->do_dynamic_tag_custom_value(tag); }
+
+  // Adjust the value written to the dynamic symbol table.
+  void
+  adjust_dyn_symbol(const Symbol* sym, unsigned char* view) const
+  { this->do_adjust_dyn_symbol(sym, view); }
+
+  // Return whether to include the section in the link.
+  bool
+  should_include_section(elfcpp::Elf_Word sh_type) const
+  { return this->do_should_include_section(sh_type); }
+
+  // Finalize the target-specific properties in the .note.gnu.property section.
+  void
+  finalize_gnu_properties(Layout* layout) const
+  { this->do_finalize_gnu_properties(layout); }
+
  protected:
   // This struct holds the constant information for a child class.  We
   // use a struct to avoid the overhead of virtual function calls for
@@ -429,6 +548,11 @@ class Target
     uint64_t abi_pagesize;
     // The common page size used by actual implementations.
     uint64_t common_pagesize;
+    // Whether PF_X segments must contain nothing but the contents of
+    // SHF_EXECINSTR sections (no non-executable data, no headers).
+    bool isolate_execinstr;
+    // If nonzero, distance from the text segment to the read-only segment.
+    uint64_t rosegment_gap;
     // The special section index for small common symbols; SHN_UNDEF
     // if none.
     elfcpp::Elf_Half small_common_shndx;
@@ -443,6 +567,14 @@ class Target
     const char* attributes_section;
     // Vendor name of vendor attributes.
     const char* attributes_vendor;
+    // Name of the main entry point to the program.
+    const char* entry_symbol_name;
+    // Size (in bits) of SHT_HASH entry. Always equal to 32, except for
+    // 64-bit S/390.
+    const int hash_entry_size;
+    // Processor-specific section type for ".eh_frame" (unwind) sections.
+    // SHT_PROGBITS if there is no special section type.
+    const unsigned int unwind_section_type;
   };
 
   Target(const Target_info* pti)
@@ -482,7 +614,12 @@ class Target
   // By default, we set the EI_OSABI field if requested (in
   // Sized_target).
   virtual void
-  do_adjust_elf_header(unsigned char*, int) const = 0;
+  do_adjust_elf_header(unsigned char*, int) = 0;
+
+  // Return address and size to plug into eh_frame FDEs associated with a PLT.
+  virtual void
+  do_plt_fde_location(const Output_data* plt, unsigned char* oview,
+                     uint64_t* address, off_t* len) const;
 
   // Virtual function which may be overridden by the child class.
   virtual bool
@@ -502,14 +639,25 @@ class Target
 
   // Virtual functions that must be overridden by a target that uses
   // STT_GNU_IFUNC symbols.
-  virtual Output_data*
-  do_plt_section_for_global(const Symbol*) const
+  virtual uint64_t
+  do_plt_address_for_global(const Symbol*) const
+  { gold_unreachable(); }
+
+  virtual uint64_t
+  do_plt_address_for_local(const Relobj*, unsigned int) const
   { gold_unreachable(); }
 
-  virtual Output_data*
-  do_plt_section_for_local(const Relobj*, unsigned int) const
+  virtual int64_t
+  do_tls_offset_for_local(const Relobj*, unsigned int, unsigned int) const
   { gold_unreachable(); }
 
+  virtual int64_t
+  do_tls_offset_for_global(Symbol*, unsigned int) const
+  { gold_unreachable(); }
+
+  virtual void
+  do_function_location(Symbol_location*) const = 0;
+
   // Virtual function which may be overriden by the child class.
   virtual bool
   do_can_check_for_function_pointers() const
@@ -538,12 +686,14 @@ class Target
   // default implementation is that any function not defined by the
   // ABI is a call to a non-split function.
   virtual bool
-  do_is_call_to_non_split(const Symbol* sym, unsigned int) const;
+  do_is_call_to_non_split(const Symbol* sym, const unsigned char*,
+                         const unsigned char*, section_size_type) const;
 
   // Virtual function which may be overridden by the child class.
   virtual void
   do_calls_non_split(Relobj* object, unsigned int, section_offset_type,
-                    section_size_type, unsigned char*, section_size_type,
+                    section_size_type, const unsigned char*, size_t,
+                    unsigned char*, section_size_type,
                     std::string*, std::string*) const;
 
   // make_elf_object hooks.  There are four versions of these for
@@ -556,7 +706,7 @@ class Target
     this->processor_specific_flags_ = flags;
     this->are_processor_specific_flags_set_ = true;
   }
-  
+
 #ifdef HAVE_TARGET_32_LITTLE
   // Virtual functions which may be overridden by the child class.
   virtual Object*
@@ -613,7 +763,7 @@ class Target
                  section_offset_type offset, size_t len) const;
 
   // This must be overridden by the child class if it has target-specific
-  // attributes subsection in the attribute section. 
+  // attributes subsection in the attribute section.
   virtual int
   do_attribute_arg_type(int) const
   { gold_unreachable(); }
@@ -628,6 +778,53 @@ class Target
   do_select_as_default_target()
   { }
 
+  // This may be overridden by the child class.
+  virtual void
+  do_define_standard_symbols(Symbol_table*, Layout*)
+  { }
+
+  // This may be overridden by the child class.
+  virtual const char*
+  do_output_section_name(const Relobj*, const char*, size_t*) const
+  { return NULL; }
+
+  // This may be overridden by the child class.
+  virtual void
+  do_gc_mark_symbol(Symbol_table*, Symbol*) const
+  { }
+
+  // This may be overridden by the child class.
+  virtual bool
+  do_has_custom_set_dynsym_indexes() const
+  { return false; }
+
+  // This may be overridden by the child class.
+  virtual unsigned int
+  do_set_dynsym_indexes(std::vector<Symbol*>*, unsigned int,
+                        std::vector<Symbol*>*, Stringpool*, Versions*,
+                        Symbol_table*) const
+  { gold_unreachable(); }
+
+  // This may be overridden by the child class.
+  virtual unsigned int
+  do_dynamic_tag_custom_value(elfcpp::DT) const
+  { gold_unreachable(); }
+
+  // This may be overridden by the child class.
+  virtual void
+  do_adjust_dyn_symbol(const Symbol*, unsigned char*) const
+  { }
+
+  // This may be overridden by the child class.
+  virtual bool
+  do_should_include_section(elfcpp::Elf_Word) const
+  { return true; }
+
+  // Finalize the target-specific properties in the .note.gnu.property section.
+  virtual void
+  do_finalize_gnu_properties(Layout*) const
+  { }
+
  private:
   // The implementations of the four do_make_elf_object virtual functions are
   // almost identical except for their sizes and endianness.  We use a template.
@@ -665,7 +862,7 @@ class Sized_target : public Target
   // symbol table.  This will only be called if has_make_symbol()
   // returns true.
   virtual Sized_symbol<size>*
-  make_symbol() const
+  make_symbol(const char*, elfcpp::STT, Object*, unsigned int, uint64_t)
   { gold_unreachable(); }
 
   // Resolve a symbol for the target.  This should be overridden by a
@@ -673,7 +870,7 @@ class Sized_target : public Target
   // pre-existing symbol.  SYM is the new symbol, seen in OBJECT.
   // VERSION is the version of SYM.  This will only be called if
   // has_resolve() returns true.
-  virtual void
+  virtual bool
   resolve(Symbol*, const elfcpp::Sym<size, big_endian>&, Object*,
          const char*)
   { gold_unreachable(); }
@@ -760,24 +957,39 @@ class Sized_target : public Target
                          const unsigned char* plocal_symbols,
                          Relocatable_relocs*) = 0;
 
-  // Relocate a section during a relocatable link.  The parameters are
-  // like relocate_section, with additional parameters for the view of
-  // the output reloc section.
+  // Scan the relocs for --emit-relocs.  The parameters are
+  // like scan_relocatable_relocs.
+  virtual void
+  emit_relocs_scan(Symbol_table* symtab,
+                  Layout* layout,
+                  Sized_relobj_file<size, big_endian>* 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) = 0;
+
+  // Emit relocations for a section during a relocatable link, and for
+  // --emit-relocs.  The parameters are like relocate_section, with
+  // additional parameters for the view of the output reloc section.
   virtual void
-  relocate_for_relocatable(const Relocate_info<size, big_endian>*,
-                          unsigned int sh_type,
-                          const unsigned char* prelocs,
-                          size_t reloc_count,
-                          Output_section* output_section,
-                          off_t offset_in_output_section,
-                          const Relocatable_relocs*,
-                          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) = 0;
+  relocate_relocs(const Relocate_info<size, big_endian>*,
+                 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) = 0;
+
   // Perform target-specific processing in a relocatable link.  This is
   // only used if we use the relocation strategy RELOC_SPECIAL.
   // RELINFO points to a Relocation_info structure. SH_TYPE is the relocation
@@ -800,14 +1012,15 @@ class Sized_target : public Target
                               const unsigned char* /* preloc_in */,
                               size_t /* relnum */,
                               Output_section* /* output_section */,
-                              off_t /* offset_in_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* /* preloc_out*/)
   { gold_unreachable(); }
+
   // Return the number of entries in the GOT.  This is only used for
   // laying out the incremental link info sections.  A target needs
   // to implement this to support incremental linking.
@@ -840,10 +1053,18 @@ class Sized_target : public Target
   plt_entry_size() const
   { gold_unreachable(); }
 
+  // Return the size of each GOT entry.  This is only used for
+  // laying out the incremental link info sections.  A target needs
+  // to implement this if its GOT size is different.
+
+  virtual unsigned int
+  got_entry_size() const
+  { return size / 8; }
+
   // Create the GOT and PLT sections for an incremental update.
   // A target needs to implement this to support incremental linking.
 
-  virtual Output_data_got<size, big_endian>*
+  virtual Output_data_got_base*
   init_got_plt_for_update(Symbol_table*,
                          Layout*,
                          unsigned int /* got_count */,
@@ -870,7 +1091,8 @@ class Sized_target : public Target
   // A target needs to implement this to support incremental linking.
 
   virtual void
-  register_global_plt_entry(unsigned int /* plt_index */,
+  register_global_plt_entry(Symbol_table*, Layout*,
+                           unsigned int /* plt_index */,
                            Symbol*)
   { gold_unreachable(); }
 
@@ -894,6 +1116,46 @@ class Sized_target : public Target
                   section_size_type /* view_size */)
   { gold_unreachable(); }
 
+  // Handle target specific gc actions when adding a gc reference from
+  // SRC_OBJ, SRC_SHNDX to a location specified by DST_OBJ, DST_SHNDX
+  // and DST_OFF.
+  void
+  gc_add_reference(Symbol_table* symtab,
+                  Relobj* src_obj,
+                  unsigned int src_shndx,
+                  Relobj* dst_obj,
+                  unsigned int dst_shndx,
+                  typename elfcpp::Elf_types<size>::Elf_Addr dst_off) const
+  {
+    this->do_gc_add_reference(symtab, src_obj, src_shndx,
+                             dst_obj, dst_shndx, dst_off);
+  }
+
+  // Return the r_sym field from a relocation.
+  // Most targets can use the default version of this routine,
+  // but some targets have a non-standard r_info field, and will
+  // need to provide a target-specific version.
+  virtual unsigned int
+  get_r_sym(const unsigned char* preloc) const
+  {
+    // Since REL and RELA relocs share the same structure through
+    // the r_info field, we can just use REL here.
+    elfcpp::Rel<size, big_endian> rel(preloc);
+    return elfcpp::elf_r_sym<size>(rel.get_r_info());
+  }
+
+  // Record a target-specific program property in the .note.gnu.property
+  // section.
+  virtual void
+  record_gnu_property(unsigned int, unsigned int, size_t,
+                     const unsigned char*, const Object*)
+  { }
+
+  // Merge the target-specific program properties from the current object.
+  virtual void
+  merge_gnu_properties(const Object*)
+  { }
+
  protected:
   Sized_target(const Target::Target_info* pti)
     : Target(pti)
@@ -904,7 +1166,18 @@ class Sized_target : public Target
 
   // Set the EI_OSABI field if requested.
   virtual void
-  do_adjust_elf_header(unsigned char*, int) const;
+  do_adjust_elf_header(unsigned char*, int);
+
+  // Handle target specific gc actions when adding a gc reference.
+  virtual void
+  do_gc_add_reference(Symbol_table*, Relobj*, unsigned int,
+                     Relobj*, unsigned int,
+                     typename elfcpp::Elf_types<size>::Elf_Addr) const
+  { }
+
+  virtual void
+  do_function_location(Symbol_location*) const
+  { }
 };
 
 } // End namespace gold.
This page took 0.030157 seconds and 4 git commands to generate.