gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gold / symtab.h
index 1a1f1c78633b76d05224f5d6ec6878b931a8d8a7..913ccdebca1c64d19bdd36cd53e68c3b3140632f 100644 (file)
@@ -1,6 +1,6 @@
 // symtab.h -- the gold symbol table   -*- C++ -*-
 
-// Copyright (C) 2006-2015 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.
@@ -159,7 +159,7 @@ class Symbol
   object() const
   {
     gold_assert(this->source_ == FROM_OBJECT);
-    return this->u_.from_object.object;
+    return this->u1_.object;
   }
 
   // Return the index of the section in the input relocatable or
@@ -169,7 +169,7 @@ class Symbol
   {
     gold_assert(this->source_ == FROM_OBJECT);
     *is_ordinary = this->is_ordinary_shndx_;
-    return this->u_.from_object.shndx;
+    return this->u2_.shndx;
   }
 
   // Return the output data section with which this symbol is
@@ -179,7 +179,7 @@ class Symbol
   output_data() const
   {
     gold_assert(this->source_ == IN_OUTPUT_DATA);
-    return this->u_.in_output_data.output_data;
+    return this->u1_.output_data;
   }
 
   // If this symbol was defined with respect to an output data
@@ -188,7 +188,7 @@ class Symbol
   offset_is_from_end() const
   {
     gold_assert(this->source_ == IN_OUTPUT_DATA);
-    return this->u_.in_output_data.offset_is_from_end;
+    return this->u2_.offset_is_from_end;
   }
 
   // Return the output segment with which this symbol is associated,
@@ -198,7 +198,7 @@ class Symbol
   output_segment() const
   {
     gold_assert(this->source_ == IN_OUTPUT_SEGMENT);
-    return this->u_.in_output_segment.output_segment;
+    return this->u1_.output_segment;
   }
 
   // If this symbol was defined with respect to an output segment,
@@ -207,7 +207,7 @@ class Symbol
   offset_base() const
   {
     gold_assert(this->source_ == IN_OUTPUT_SEGMENT);
-    return this->u_.in_output_segment.offset_base;
+    return this->u2_.offset_base;
   }
 
   // Return the symbol binding.
@@ -329,6 +329,11 @@ class Symbol
   set_in_reg()
   { this->in_reg_ = true; }
 
+  // Forget this symbol was seen in a regular object.
+  void
+  clear_in_reg()
+  { this->in_reg_ = false; }
+
   // Return whether this symbol has been seen in a dynamic object.
   bool
   in_dyn() const
@@ -339,6 +344,11 @@ class Symbol
   set_in_dyn()
   { this->in_dyn_ = true; }
 
+  // Return whether this symbol is defined in a dynamic object.
+  bool
+  from_dyn() const
+  { return this->source_ == FROM_OBJECT && this->object()->is_dynamic(); }
+
   // Return whether this symbol has been seen in a real ELF object.
   // (IN_REG will return TRUE if the symbol has been seen in either
   // a real ELF object or an object claimed by a plugin.)
@@ -870,11 +880,41 @@ class Symbol
   is_cxx_vtable() const
   { return is_prefix_of("_ZTV", this->name_); }
 
+  // Return true if this symbol is protected in a shared object.
+  // This is not the same as checking if visibility() == elfcpp::STV_PROTECTED,
+  // because the visibility_ field reflects the symbol's visibility from
+  // outside the shared object.
+  bool
+  is_protected() const
+  { return this->is_protected_; }
+
+  // Mark this symbol as protected in a shared object.
+  void
+  set_is_protected()
+  { this->is_protected_ = true; }
+
+  // Return state of PowerPC64 ELFv2 specific flag.
+  bool
+  non_zero_localentry() const
+  { return this->non_zero_localentry_; }
+
+  // Set PowerPC64 ELFv2 specific flag.
+  void
+  set_non_zero_localentry()
+  { this->non_zero_localentry_ = true; }
+
+  // Completely override existing symbol.  Everything bar name_,
+  // version_, and is_forced_local_ flag are copied.  version_ is
+  // cleared if from->version_ is clear.  Returns true if this symbol
+  // should be forced local.
+  bool
+  clone(const Symbol* from);
+
  protected:
   // Instances of this class should always be created at a specific
   // size.
   Symbol()
-  { memset(this, 0, sizeof *this); }
+  { memset(static_cast<void*>(this), 0, sizeof *this); }
 
   // Initialize the general fields.
   void
@@ -950,38 +990,38 @@ class Symbol
 
   union
   {
-    // This struct is used if SOURCE_ == FROM_OBJECT.
-    struct
-    {
-      // Object in which symbol is defined, or in which it was first
-      // seen.
-      Object* object;
-      // Section number in object_ in which symbol is defined.
-      unsigned int shndx;
-    } from_object;
-
-    // This struct is used if SOURCE_ == IN_OUTPUT_DATA.
-    struct
-    {
-      // Output_data in which symbol is defined.  Before
-      // Layout::finalize the symbol's value is an offset within the
-      // Output_data.
-      Output_data* output_data;
-      // True if the offset is from the end, false if the offset is
-      // from the beginning.
-      bool offset_is_from_end;
-    } in_output_data;
-
-    // This struct is used if SOURCE_ == IN_OUTPUT_SEGMENT.
-    struct
-    {
-      // Output_segment in which the symbol is defined.  Before
-      // Layout::finalize the symbol's value is an offset.
-      Output_segment* output_segment;
-      // The base to use for the offset before Layout::finalize.
-      Segment_offset_base offset_base;
-    } in_output_segment;
-  } u_;
+    // This is used if SOURCE_ == FROM_OBJECT.
+    // Object in which symbol is defined, or in which it was first
+    // seen.
+    Object* object;
+
+    // This is used if SOURCE_ == IN_OUTPUT_DATA.
+    // Output_data in which symbol is defined.  Before
+    // Layout::finalize the symbol's value is an offset within the
+    // Output_data.
+    Output_data* output_data;
+
+    // This is used if SOURCE_ == IN_OUTPUT_SEGMENT.
+    // Output_segment in which the symbol is defined.  Before
+    // Layout::finalize the symbol's value is an offset.
+    Output_segment* output_segment;
+  } u1_;
+
+  union
+  {
+    // This is used if SOURCE_ == FROM_OBJECT.
+    // Section number in object in which symbol is defined.
+    unsigned int shndx;
+
+    // This is used if SOURCE_ == IN_OUTPUT_DATA.
+    // True if the offset is from the end, false if the offset is
+    // from the beginning.
+    bool offset_is_from_end;
+
+    // This is used if SOURCE_ == IN_OUTPUT_SEGMENT.
+    // The base to use for the offset before Layout::finalize.
+    Segment_offset_base offset_base;
+  } u2_;
 
   // The index of this symbol in the output file.  If the symbol is
   // not going into the output file, this value is -1U.  This field
@@ -995,16 +1035,16 @@ class Symbol
   // non-zero value during Layout::finalize.
   unsigned int dynsym_index_;
 
-  // The GOT section entries for this symbol.  A symbol may have more
-  // than one GOT offset (e.g., when mixing modules compiled with two
-  // different TLS models), but will usually have at most one.
-  Got_offset_list got_offsets_;
-
   // If this symbol has an entry in the PLT section, then this is the
   // offset from the start of the PLT section.  This is -1U if there
   // is no PLT entry.
   unsigned int plt_offset_;
 
+  // The GOT section entries for this symbol.  A symbol may have more
+  // than one GOT offset (e.g., when mixing modules compiled with two
+  // different TLS models), but will usually have at most one.
+  Got_offset_list got_offsets_;
+
   // Symbol type (bits 0 to 3).
   elfcpp::STT type_ : 4;
   // Symbol binding (bits 4 to 7).
@@ -1046,7 +1086,7 @@ class Symbol
   // True if this symbol was forced to local visibility by a version
   // script (bit 28).
   bool is_forced_local_ : 1;
-  // True if the field u_.from_object.shndx is an ordinary section
+  // True if the field u2_.shndx is an ordinary section
   // index, not one of the special codes from SHN_LORESERVE to
   // SHN_HIRESERVE (bit 29).
   bool is_ordinary_shndx_ : 1;
@@ -1067,6 +1107,12 @@ class Symbol
   bool undef_binding_weak_ : 1;
   // True if this symbol is a predefined linker symbol (bit 34).
   bool is_predefined_ : 1;
+  // True if this symbol has protected visibility in a shared object (bit 35).
+  // The visibility_ field will be STV_DEFAULT in this case because we
+  // must treat it as such from outside the shared object.
+  bool is_protected_  : 1;
+  // Used by PowerPC64 ELFv2 to track st_other localentry (bit 36).
+  bool non_zero_localentry_ : 1;
 };
 
 // The parts of a symbol which are size specific.  Using a template
@@ -1113,8 +1159,8 @@ class Sized_symbol : public Symbol
 
   // Initialize fields for an undefined symbol.
   void
-  init_undefined(const char* name, const char* version, elfcpp::STT,
-                elfcpp::STB, elfcpp::STV, unsigned char nonvis);
+  init_undefined(const char* name, const char* version, Value_type value,
+                elfcpp::STT, elfcpp::STB, elfcpp::STV, unsigned char nonvis);
 
   // Override existing symbol.
   template<bool big_endian>
@@ -1153,6 +1199,13 @@ class Sized_symbol : public Symbol
   void
   allocate_common(Output_data*, Value_type value);
 
+  // Completely override existing symbol.  Everything bar name_,
+  // version_, and is_forced_local_ flag are copied.  version_ is
+  // cleared if from->version_ is clear.  Returns true if this symbol
+  // should be forced local.
+  bool
+  clone(const Sized_symbol<size>* from);
+
  private:
   Sized_symbol(const Sized_symbol&);
   Sized_symbol& operator=(const Sized_symbol&);
@@ -1256,6 +1309,16 @@ struct Symbol_location
   }
 };
 
+// A map from symbol name (as a pointer into the namepool) to all
+// the locations the symbols is (weakly) defined (and certain other
+// conditions are met).  This map will be used later to detect
+// possible One Definition Rule (ODR) violations.
+struct Symbol_location_hash
+{
+  size_t operator()(const Symbol_location& loc) const
+  { return reinterpret_cast<uintptr_t>(loc.object) ^ loc.offset ^ loc.shndx; }
+};
+
 // This class manages warnings.  Warnings are a GNU extension.  When
 // we see a section named .gnu.warning.SYM in an object file, and if
 // we wind using the definition of SYM from that object file, then we
@@ -1481,6 +1544,12 @@ class Symbol_table
   define_symbols(const Layout*, int count, const Define_symbol_in_segment*,
                 bool only_if_ref);
 
+  // Add a target-specific global symbol.
+  // (Used by SPARC backend to add STT_SPARC_REGISTER symbols.)
+  void
+  add_target_global_symbol(Symbol* sym)
+  { this->target_symbols_.push_back(sym); }
+
   // Define SYM using a COPY reloc.  POSD is the Output_data where the
   // symbol should be defined--typically a .dyn.bss section.  VALUE is
   // the offset within POSD.
@@ -1511,6 +1580,10 @@ class Symbol_table
   saw_undefined() const
   { return this->saw_undefined_; }
 
+  void
+  set_has_gnu_output()
+  { this->has_gnu_output_ = true; }
+
   // Allocate the common symbols
   void
   allocate_commons(Layout*, Mapfile*);
@@ -1551,12 +1624,13 @@ class Symbol_table
   get_copy_source(const Symbol* sym) const;
 
   // Set the dynamic symbol indexes.  INDEX is the index of the first
-  // global dynamic symbol.  Pointers to the symbols are stored into
+  // global dynamic symbol.  Return the count of forced-local symbols in
+  // *PFORCED_LOCAL_COUNT.  Pointers to the symbols are stored into
   // the vector.  The names are stored into the Stringpool.  This
   // returns an updated dynamic symbol index.
   unsigned int
-  set_dynsym_indexes(unsigned int index, std::vector<Symbol*>*,
-                    Stringpool*, Versions*);
+  set_dynsym_indexes(unsigned int index, unsigned int* pforced_local_count,
+                    std::vector<Symbol*>*, Stringpool*, Versions*);
 
   // Finalize the symbol table after we have set the final addresses
   // of all the input sections.  This sets the final symbol indexes,
@@ -1641,6 +1715,15 @@ class Symbol_table
   version_script() const
   { return version_script_; }
 
+  // Completely override existing symbol.
+  template<int size>
+  void
+  clone(Sized_symbol<size>* to, const Sized_symbol<size>* from)
+  {
+    if (to->clone(from))
+      this->force_local(to);
+  }
+
  private:
   Symbol_table(const Symbol_table&);
   Symbol_table& operator=(const Symbol_table&);
@@ -1671,16 +1754,6 @@ class Symbol_table
   typedef Unordered_map<Symbol_table_key, Symbol*, Symbol_table_hash,
                        Symbol_table_eq> Symbol_table_type;
 
-  // A map from symbol name (as a pointer into the namepool) to all
-  // the locations the symbols is (weakly) defined (and certain other
-  // conditions are met).  This map will be used later to detect
-  // possible One Definition Rule (ODR) violations.
-  struct Symbol_location_hash
-  {
-    size_t operator()(const Symbol_location& loc) const
-    { return reinterpret_cast<uintptr_t>(loc.object) ^ loc.offset ^ loc.shndx; }
-  };
-
   typedef Unordered_map<const char*,
                         Unordered_set<Symbol_location, Symbol_location_hash> >
   Odr_map;
@@ -1766,8 +1839,9 @@ class Symbol_table
   template<int size, bool big_endian>
   Sized_symbol<size>*
   define_special_symbol(const char** pname, const char** pversion,
-                       bool only_if_ref, Sized_symbol<size>** poldsym,
-                       bool* resolve_oldsym);
+                       bool only_if_ref, elfcpp::STV visibility,
+                       Sized_symbol<size>** poldsym,
+                       bool* resolve_oldsym, bool is_forced_local);
 
   // Define a symbol in an Output_data, sized version.
   template<int size>
@@ -1905,10 +1979,14 @@ class Symbol_table
   unsigned int output_count_;
   // The file offset of the global dynamic symbols, or 0 if none.
   off_t dynamic_offset_;
-  // The index of the first global dynamic symbol.
+  // The index of the first global dynamic symbol (including
+  // forced-local symbols).
   unsigned int first_dynamic_global_index_;
-  // The number of global dynamic symbols, or 0 if none.
+  // The number of global dynamic symbols (including forced-local symbols),
+  // or 0 if none.
   unsigned int dynamic_count_;
+  // Set if a STT_GNU_IFUNC or STB_GNU_UNIQUE symbol will be output.
+  bool has_gnu_output_;
   // The symbol hash table.
   Symbol_table_type table_;
   // A pool of symbol names.  This is used for all global symbols.
@@ -1951,6 +2029,8 @@ class Symbol_table
   const Version_script_info& version_script_;
   Garbage_collection* gc_;
   Icf* icf_;
+  // Target-specific symbols, if any.
+  std::vector<Symbol*> target_symbols_;
 };
 
 // We inline get_sized_symbol for efficiency.
This page took 0.028967 seconds and 4 git commands to generate.