X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gold%2Fsymtab.h;h=9299ea8abe9bb36ab4ab24b3e60fcb43342e6c97;hb=7903e5309890633911c91539e23a407e1f74b959;hp=6542edbe5e8b324bf9801615b634388126b9a143;hpb=a9bfd952d1747c18a39f1125d2d56b2b61f45378;p=deliverable%2Fbinutils-gdb.git diff --git a/gold/symtab.h b/gold/symtab.h index 6542edbe5e..9299ea8abe 100644 --- a/gold/symtab.h +++ b/gold/symtab.h @@ -1,6 +1,6 @@ // symtab.h -- the gold symbol table -*- C++ -*- -// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -42,12 +42,14 @@ class Mapfile; class Object; class Relobj; template -class Sized_relobj; +class Sized_relobj_file; template class Sized_pluginobj; class Dynobj; template class Sized_dynobj; +template +class Sized_incrobj; class Versions; class Version_script_info; class Input_objects; @@ -60,7 +62,7 @@ class Garbage_collection; class Icf; // The base class of an entry in the symbol table. The symbol table -// can have a lot of entries, so we don't want this class to big. +// can have a lot of entries, so we don't want this class too big. // Size dependent fields can be found in the template class // Sized_symbol. Targets may support their own derived classes. @@ -119,6 +121,10 @@ class Symbol 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. @@ -134,6 +140,10 @@ class Symbol set_is_default() { this->is_def_ = true; } + // Return the symbol's name as name@version (or name@@version). + std::string + versioned_name() const; + // Return the symbol source. Source source() const @@ -532,8 +542,9 @@ class Symbol bool is_externally_visible() const { - return (this->visibility_ == elfcpp::STV_DEFAULT - || this->visibility_ == elfcpp::STV_PROTECTED); + return ((this->visibility_ == elfcpp::STV_DEFAULT + || this->visibility_ == elfcpp::STV_PROTECTED) + && !this->is_forced_local_); } // Return true if this symbol can be preempted by a definition in @@ -614,15 +625,20 @@ class Symbol // When determining whether a reference to a symbol needs a dynamic // relocation, we need to know several things about the reference. - // These flags may be or'ed together. + // These flags may be or'ed together. 0 means that the symbol + // isn't referenced at all. enum Reference_flags { - // Reference to the symbol's absolute address. + // A reference to the symbol's absolute address. This includes + // references that cause an absolute address to be stored in the GOT. ABSOLUTE_REF = 1, - // A non-PIC reference. - NON_PIC_REF = 2, - // A function call. - FUNCTION_CALL = 4 + // A reference that calculates the offset of the symbol from some + // anchor point, such as the PC or GOT. + RELATIVE_REF = 2, + // A TLS-related reference. + TLS_REF = 4, + // A reference that can always be treated as a function call. + FUNCTION_CALL = 8 }; // Given a direct absolute or pc-relative static relocation against @@ -653,12 +669,8 @@ class Symbol return true; // A function call that can branch to a local PLT entry does not need - // a dynamic relocation. A non-pic pc-relative function call in a - // shared library cannot use a PLT entry. - if ((flags & FUNCTION_CALL) - && this->has_plt_offset() - && !((flags & NON_PIC_REF) - && parameters->options().output_is_position_independent())) + // a dynamic relocation. + if ((flags & FUNCTION_CALL) && this->has_plt_offset()) return false; // A reference to any PLT entry in a non-position-independent executable @@ -679,12 +691,10 @@ class Symbol } // Whether we should use the PLT offset associated with a symbol for - // a relocation. IS_NON_PIC_REFERENCE is true if this is a non-PIC - // reloc--the same set of relocs for which we would pass NON_PIC_REF - // to the needs_dynamic_reloc function. + // a relocation. FLAGS is a set of Reference_flags. bool - use_plt_offset(bool is_non_pic_reference) const + use_plt_offset(int flags) const { // If the symbol doesn't have a PLT offset, then naturally we // don't want to use it. @@ -697,10 +707,7 @@ class Symbol // If we are going to generate a dynamic relocation, then we will // wind up using that, so no need to use the PLT entry. - if (this->needs_dynamic_reloc(FUNCTION_CALL - | (is_non_pic_reference - ? NON_PIC_REF - : 0))) + if (this->needs_dynamic_reloc(flags)) return false; // If the symbol is from a dynamic object, we need to use the PLT @@ -714,10 +721,10 @@ class Symbol && (this->is_undefined() || this->is_preemptible())) return true; - // If this is a weak undefined symbol, we need to use the PLT - // entry; the symbol may be defined by a library loaded at - // runtime. - if (this->is_weak_undefined()) + // If this is a call to a weak undefined symbol, we need to use + // the PLT entry; the symbol may be defined by a library loaded + // at runtime. + if ((flags & FUNCTION_CALL) && this->is_weak_undefined()) return true; // Otherwise we can use the regular definition. @@ -739,7 +746,7 @@ class Symbol return true; // A reference to a symbol defined in a dynamic object or to a - // symbol that is preemptible can not use a RELATIVE relocaiton. + // symbol that is preemptible can not use a RELATIVE relocation. if (this->is_from_dynobj() || this->is_undefined() || this->is_preemptible()) @@ -805,6 +812,16 @@ class Symbol && !this->is_func()); } + // Return true if this symbol was predefined by the linker. + bool + 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_); } + protected: // Instances of this class should always be created at a specific // size. @@ -830,7 +847,8 @@ class Symbol void init_base_output_data(const char* name, const char* version, Output_data*, elfcpp::STT, elfcpp::STB, elfcpp::STV, - unsigned char nonvis, bool offset_is_from_end); + unsigned char nonvis, bool offset_is_from_end, + bool is_predefined); // Initialize fields for an Output_segment. void @@ -838,13 +856,14 @@ class Symbol Output_segment* os, elfcpp::STT type, elfcpp::STB binding, elfcpp::STV visibility, unsigned char nonvis, - Segment_offset_base offset_base); + Segment_offset_base offset_base, + bool is_predefined); // Initialize fields for a constant. void init_base_constant(const char* name, const char* version, elfcpp::STT type, elfcpp::STB binding, elfcpp::STV visibility, - unsigned char nonvis); + unsigned char nonvis, bool is_predefined); // Initialize fields for an undefined symbol. void @@ -983,7 +1002,12 @@ class Symbol // index, not one of the special codes from SHN_LORESERVE to // SHN_HIRESERVE (bit 29). bool is_ordinary_shndx_ : 1; - // True if we've seen this symbol in a real ELF object (bit 30). + // True if we've seen this symbol in a "real" ELF object (bit 30). + // If the symbol has been seen in a relocatable, non-IR, object file, + // it's known to be referenced from outside the IR. A reference from + // a dynamic object doesn't count as a "real" ELF, and we'll simply + // mark the symbol as "visible" from outside the IR. The compiler + // can use this distinction to guide its handling of COMDAT symbols. bool in_real_elf_ : 1; // True if this symbol is defined in a section which was discarded // (bit 31). @@ -993,6 +1017,8 @@ class Symbol // True if this symbol was a weak undef resolved by a dynamic def // (bit 33). bool undef_binding_weak_ : 1; + // True if this symbol is a predefined linker symbol (bit 34). + bool is_predefined_ : 1; }; // The parts of a symbol which are size specific. Using a template @@ -1022,20 +1048,20 @@ class Sized_symbol : public Symbol init_output_data(const char* name, const char* version, Output_data*, Value_type value, Size_type symsize, elfcpp::STT, elfcpp::STB, elfcpp::STV, unsigned char nonvis, - bool offset_is_from_end); + bool offset_is_from_end, bool is_predefined); // Initialize fields for an Output_segment. void init_output_segment(const char* name, const char* version, Output_segment*, Value_type value, Size_type symsize, elfcpp::STT, elfcpp::STB, elfcpp::STV, unsigned char nonvis, - Segment_offset_base offset_base); + Segment_offset_base offset_base, bool is_predefined); // Initialize fields for a constant. void init_constant(const char* name, const char* version, Value_type value, Size_type symsize, elfcpp::STT, elfcpp::STB, elfcpp::STV, - unsigned char nonvis); + unsigned char nonvis, bool is_predefined); // Initialize fields for an undefined symbol. void @@ -1163,6 +1189,25 @@ struct Define_symbol_in_segment 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 @@ -1252,6 +1297,9 @@ class Symbol_table SCRIPT, // Predefined by the linker. PREDEFINED, + // Defined by the linker during an incremental base link, but not + // a predefined symbol (e.g., common, defined in script). + INCREMENTAL_BASE, }; // The order in which we sort common symbols. @@ -1262,7 +1310,7 @@ class Symbol_table SORT_COMMONS_BY_ALIGNMENT_ASCENDING }; - // COUNT is an estimate of how many symbosl will be inserted in the + // COUNT is an estimate of how many symbols will be inserted in the // symbol table. It's ok to put 0 if you don't know; a correct // guess will just save some CPU by reducing hashtable resizes. Symbol_table(unsigned int count, const Version_script_info& version_script); @@ -1293,10 +1341,9 @@ class Symbol_table void gc_mark_undef_symbols(Layout*); - // During garbage collection, this ensures externally visible symbols - // are not treated as garbage while building shared objects. + // This tells garbage collection that this symbol is referenced. void - gc_mark_symbol_for_shlib(Symbol* sym); + gc_mark_symbol(Symbol* sym); // During garbage collection, this keeps sections that correspond to // symbols seen in dynamic objects. @@ -1311,11 +1358,11 @@ class Symbol_table // *DEFINED to the number of defined symbols. template void - add_from_relobj(Sized_relobj* relobj, + add_from_relobj(Sized_relobj_file* relobj, const unsigned char* syms, size_t count, size_t symndx_offset, const char* sym_names, size_t sym_name_size, - typename Sized_relobj::Symbols*, + typename Sized_relobj_file::Symbols*, size_t* defined); // Add one external symbol from the plugin object OBJ to the symbol table. @@ -1337,9 +1384,16 @@ class Symbol_table const char* sym_names, size_t sym_name_size, const unsigned char* versym, size_t versym_size, const std::vector*, - typename Sized_relobj::Symbols*, + typename Sized_relobj_file::Symbols*, size_t* defined); + // Add one external symbol from the incremental object OBJ to the symbol + // table. Returns a pointer to the resolved symbol in the symbol table. + template + Sized_symbol* + add_from_incrobj(Object* obj, const char* name, + const char* ver, elfcpp::Sym* sym); + // Define a special symbol based on an Output_data. It is a // multiple definition error if this symbol is already defined. Symbol* @@ -1470,12 +1524,17 @@ class Symbol_table finalize(off_t off, off_t dynoff, size_t dyn_global_index, size_t dyncount, Stringpool* pool, unsigned int* plocal_symcount); + // Set the final file offset of the symbol table. + void + set_file_offset(off_t off) + { this->offset_ = off; } + // Status code of Symbol_table::compute_final_value. enum Compute_final_value_status { // No error. CFVS_OK, - // Unspported symbol section. + // Unsupported symbol section. CFVS_UNSUPPORTED_SYMBOL_SECTION, // No output section. CFVS_NO_OUTPUT_SECTION @@ -1564,6 +1623,20 @@ class Symbol_table typedef Unordered_map 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(loc.object) ^ loc.offset ^ loc.shndx; } + }; + + typedef Unordered_map > + Odr_map; + // Make FROM a forwarder symbol to TO. void make_forwarder(Symbol* from, Symbol* to); @@ -1608,7 +1681,8 @@ class Symbol_table // Whether we should override a symbol, based on flags in // resolve.cc. static bool - should_override(const Symbol*, unsigned int, Defined, Object*, bool*, bool*); + should_override(const Symbol*, unsigned int, elfcpp::STT, Defined, + Object*, bool*, bool*); // Report a problem in symbol resolution. static void @@ -1626,7 +1700,7 @@ class Symbol_table // Whether we should override a symbol with a special symbol which // is automatically defined by the linker. static bool - should_override_with_special(const Symbol*, Defined); + should_override_with_special(const Symbol*, elfcpp::STT, Defined); // Override a symbol with a special symbol. template @@ -1711,6 +1785,12 @@ class Symbol_table do_allocate_commons_list(Layout*, Commons_section_type, Commons_type*, Mapfile*, Sort_commons_order); + // Returns all of the lines attached to LOC, not just the one the + // instruction actually came from. This helps the ODR checker avoid + // false positives. + static std::vector + linenos_from_loc(const Task* task, const Symbol_location& loc); + // Implement detect_odr_violations. template void @@ -1764,33 +1844,6 @@ class Symbol_table // they are defined. typedef Unordered_map Copied_symbol_dynobjs; - // 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 - { - 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 - { return reinterpret_cast(loc.object) ^ loc.offset ^ loc.shndx; } - }; - - typedef Unordered_map > - Odr_map; - // We increment this every time we see a new undefined symbol, for // use in archive groups. size_t saw_undefined_;