// symtab.h -- the gold symbol table -*- C++ -*-
-// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+// Copyright (C) 2006-2016 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold.
version() const
{ return this->version_; }
+ void
+ clear_version()
+ { this->version_ = NULL; }
+
// Return whether this version is the default for this symbol name
// (eg, "foo@@V2" is a default version; "foo@V1" is not). Only
// meaningful for versioned symbols.
set_is_default()
{ this->is_def_ = true; }
+ // Set that this version is not the default for this symbol name.
+ void
+ set_is_not_default()
+ { this->is_def_ = false; }
+
// Return the symbol's name as name@version (or name@@version).
std::string
versioned_name() const;
type() const
{ return this->type_; }
+ // Set the symbol type.
+ void
+ set_type(elfcpp::STT type)
+ { this->type_ = type; }
+
// Return true for function symbol.
bool
is_func() const
override_visibility(elfcpp::STV);
// Set whether the symbol was originally a weak undef or a regular undef
- // when resolved by a dynamic def.
+ // when resolved by a dynamic def or by a special symbol.
inline void
set_undef_binding(elfcpp::STB bind)
{
}
}
- // Return TRUE if a weak undef was resolved by a dynamic def.
+ // Return TRUE if a weak undef was resolved by a dynamic def or
+ // by a special symbol.
inline bool
is_undef_binding_weak() const
{ return this->undef_binding_weak_; }
nonvis() const
{ return this->nonvis_; }
+ // Set the non-visibility part of the st_other field.
+ void
+ set_nonvis(unsigned int nonvis)
+ { this->nonvis_ = nonvis; }
+
// Return whether this symbol is a forwarder. This will never be
// true of a symbol found in the hash table, but may be true of
// symbol pointers attached to object files.
// Return whether this is a weak undefined symbol.
bool
is_weak_undefined() const
- { return this->is_undefined() && this->binding() == elfcpp::STB_WEAK; }
+ {
+ return (this->is_undefined()
+ && (this->binding() == elfcpp::STB_WEAK
+ || this->is_undef_binding_weak()
+ || parameters->options().weak_unresolved_symbols()));
+ }
+
+ // Return whether this is a strong undefined symbol.
+ bool
+ is_strong_undefined() const
+ {
+ return (this->is_undefined()
+ && this->binding() != elfcpp::STB_WEAK
+ && !this->is_undef_binding_weak()
+ && !parameters->options().weak_unresolved_symbols());
+ }
// Return whether this is an absolute symbol.
bool
{
if (this->source_ != FROM_OBJECT)
return false;
- if (this->type_ == elfcpp::STT_COMMON)
- return true;
bool is_ordinary;
unsigned int shndx = this->shndx(&is_ordinary);
return !is_ordinary && Symbol::is_common_shndx(shndx);
if (!parameters->options().shared())
return false;
- // If the user used -Bsymbolic, then nothing is preemptible.
+ // If the symbol was named in a --dynamic-list script, it is preemptible.
+ if (parameters->options().in_dynamic_list(this->name()))
+ return true;
+
+ // If the user used -Bsymbolic, then nothing (else) is preemptible.
if (parameters->options().Bsymbolic())
return false;
// A TLS-related reference.
TLS_REF = 4,
// A reference that can always be treated as a function call.
- FUNCTION_CALL = 8
+ FUNCTION_CALL = 8,
+ // When set, says that dynamic relocations are needed even if a
+ // symbol has a plt entry.
+ FUNC_DESC_ABI = 16,
};
// Given a direct absolute or pc-relative static relocation against
// A reference to any PLT entry in a non-position-independent executable
// does not need a dynamic relocation.
- if (!parameters->options().output_is_position_independent()
+ if (!(flags & FUNC_DESC_ABI)
+ && !parameters->options().output_is_position_independent()
&& this->has_plt_offset())
return false;
void
set_output_section(Output_section*);
+ // Set the symbol's output segment. This is used for pre-defined
+ // symbols whose segments aren't known until after layout is done
+ // (e.g., __ehdr_start).
+ void
+ set_output_segment(Output_segment*, Segment_offset_base);
+
+ // Set the symbol to undefined. This is used for pre-defined
+ // symbols whose segments aren't known until after layout is done
+ // (e.g., __ehdr_start).
+ void
+ set_undefined();
+
// Return whether there should be a warning for references to this
// symbol.
bool
bool
may_need_copy_reloc() const
{
- return (!parameters->options().output_is_position_independent()
- && parameters->options().copyreloc()
+ return (parameters->options().copyreloc()
&& this->is_from_dynobj()
&& !this->is_func());
}
is_predefined() const
{ return this->is_predefined_; }
+ // Return true if this is a C++ vtable symbol.
+ bool
+ 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; }
+
protected:
// Instances of this class should always be created at a specific
// size.
// True if UNDEF_BINDING_WEAK_ has been set (bit 32).
bool undef_binding_set_ : 1;
// True if this symbol was a weak undef resolved by a dynamic def
- // (bit 33).
+ // or by a special symbol (bit 33).
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;
};
// The parts of a symbol which are size specific. Using a template
// 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>
bool only_if_ref;
};
+// Specify an object/section/offset location. Used by ODR code.
+
+struct Symbol_location
+{
+ // Object where the symbol is defined.
+ Object* object;
+ // Section-in-object where the symbol is defined.
+ unsigned int shndx;
+ // For relocatable objects, offset-in-section where the symbol is defined.
+ // For dynamic objects, address where the symbol is defined.
+ off_t offset;
+ bool operator==(const Symbol_location& that) const
+ {
+ return (this->object == that.object
+ && this->shndx == that.shndx
+ && this->offset == that.offset);
+ }
+};
+
// 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
// Returns true if ICF determined that this is a duplicate section.
bool
- is_section_folded(Object* obj, unsigned int shndx) const;
+ is_section_folded(Relobj* obj, unsigned int shndx) const;
void
set_gc(Garbage_collection* gc)
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.
// 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
- {
- Object* object; // Object where the symbol is defined.
- unsigned int shndx; // Section-in-object where the symbol is defined.
- off_t offset; // Offset-in-section where the symbol is defined.
- bool operator==(const Symbol_location& that) const
- {
- return (this->object == that.object
- && this->shndx == that.shndx
- && this->offset == that.offset);
- }
- };
-
struct Symbol_location_hash
{
size_t operator()(const Symbol_location& loc) const
const elfcpp::Sym<size, big_endian>& sym,
unsigned int st_shndx, bool is_ordinary,
unsigned int orig_st_shndx,
- Object*, const char* version);
+ Object*, const char* version,
+ bool is_default_version);
template<int size, bool big_endian>
void
// resolve.cc.
static bool
should_override(const Symbol*, unsigned int, elfcpp::STT, Defined,
- Object*, bool*, bool*);
+ Object*, bool*, bool*, bool);
// Report a problem in symbol resolution.
static void
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.