namespace gold
{
+class Mapfile;
class Object;
class Relobj;
template<int size, bool big_endian>
// section.
IN_OUTPUT_SEGMENT,
// Symbol value is constant.
- CONSTANT
+ IS_CONSTANT,
+ // Symbol is undefined.
+ IS_UNDEFINED
};
// When the source is IN_OUTPUT_SEGMENT, we need to describe what
{
bool is_ordinary;
if (this->source_ != FROM_OBJECT)
- return true;
+ return this->source_ != IS_UNDEFINED;
unsigned int shndx = this->shndx(&is_ordinary);
return (is_ordinary
? shndx != elfcpp::SHN_UNDEF
is_undefined() const
{
bool is_ordinary;
- return (this->source_ == FROM_OBJECT
- && this->shndx(&is_ordinary) == elfcpp::SHN_UNDEF
- && is_ordinary);
+ return ((this->source_ == FROM_OBJECT
+ && this->shndx(&is_ordinary) == elfcpp::SHN_UNDEF
+ && is_ordinary)
+ || this->source_ == IS_UNDEFINED);
}
// Return whether this is a weak undefined symbol.
bool
is_weak_undefined() const
- {
- bool is_ordinary;
- return (this->source_ == FROM_OBJECT
- && this->binding() == elfcpp::STB_WEAK
- && this->shndx(&is_ordinary) == elfcpp::SHN_UNDEF
- && is_ordinary);
- }
+ { return this->is_undefined() && this->binding() == elfcpp::STB_WEAK; }
// Return whether this is an absolute symbol.
bool
is_absolute() const
{
bool is_ordinary;
- return (this->source_ == FROM_OBJECT
- && this->shndx(&is_ordinary) == elfcpp::SHN_ABS
- && !is_ordinary);
+ return ((this->source_ == FROM_OBJECT
+ && this->shndx(&is_ordinary) == elfcpp::SHN_ABS
+ && !is_ordinary)
+ || this->source_ == IS_CONSTANT);
}
// Return whether this is a common symbol.
// index rather than a special code.
template<int size, bool big_endian>
void
- init_base(const char *name, const char* version, Object* object,
- const elfcpp::Sym<size, big_endian>&, unsigned int st_shndx,
- bool is_ordinary);
+ init_base_object(const char *name, const char* version, Object* object,
+ const elfcpp::Sym<size, big_endian>&, unsigned int st_shndx,
+ bool is_ordinary);
// Initialize fields for an Output_data.
void
- init_base(const char* name, Output_data*, elfcpp::STT, elfcpp::STB,
- elfcpp::STV, unsigned char nonvis, bool offset_is_from_end);
+ 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);
// Initialize fields for an Output_segment.
void
- init_base(const char* name, Output_segment* os, elfcpp::STT type,
- elfcpp::STB binding, elfcpp::STV visibility,
- unsigned char nonvis, Segment_offset_base offset_base);
+ init_base_output_segment(const char* name, const char* version,
+ Output_segment* os, elfcpp::STT type,
+ elfcpp::STB binding, elfcpp::STV visibility,
+ unsigned char nonvis,
+ Segment_offset_base offset_base);
// Initialize fields for a constant.
void
- init_base(const char* name, elfcpp::STT type, elfcpp::STB binding,
- elfcpp::STV visibility, unsigned char nonvis);
+ init_base_constant(const char* name, const char* version, elfcpp::STT type,
+ elfcpp::STB binding, elfcpp::STV visibility,
+ unsigned char nonvis);
+
+ // Initialize fields for an undefined symbol.
+ void
+ init_base_undefined(const char* name, const char* version, elfcpp::STT type,
+ elfcpp::STB binding, elfcpp::STV visibility,
+ unsigned char nonvis);
// Override existing symbol.
template<int size, bool big_endian>
void
override_base_with_special(const Symbol* from);
+ // Override symbol version.
+ void
+ override_version(const char* version);
+
// Allocate a common symbol by giving it a location in the output
// file.
void
// index rather than a special code.
template<bool big_endian>
void
- init(const char *name, const char* version, Object* object,
- const elfcpp::Sym<size, big_endian>&, unsigned int st_shndx,
- bool is_ordinary);
+ init_object(const char *name, const char* version, Object* object,
+ const elfcpp::Sym<size, big_endian>&, unsigned int st_shndx,
+ bool is_ordinary);
// Initialize fields for an Output_data.
void
- init(const char* name, Output_data*, Value_type value, Size_type symsize,
- elfcpp::STT, elfcpp::STB, elfcpp::STV, unsigned char nonvis,
- bool offset_is_from_end);
+ 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);
// Initialize fields for an Output_segment.
void
- init(const char* name, Output_segment*, Value_type value, Size_type symsize,
- elfcpp::STT, elfcpp::STB, elfcpp::STV, unsigned char nonvis,
- Segment_offset_base offset_base);
+ 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);
// Initialize fields for a constant.
void
- init(const char* name, Value_type value, Size_type symsize,
- elfcpp::STT, elfcpp::STB, elfcpp::STV, unsigned char nonvis);
+ init_constant(const char* name, const char* version, Value_type value,
+ Size_type symsize, elfcpp::STT, elfcpp::STB, elfcpp::STV,
+ unsigned char nonvis);
+
+ // Initialize fields for an undefined symbol.
+ void
+ init_undefined(const char* name, const char* version, elfcpp::STT,
+ elfcpp::STB, elfcpp::STV, unsigned char nonvis);
// Override existing symbol.
template<bool big_endian>
// the symbol table. SYMS is the symbols, SYMNDX_OFFSET is the
// offset in the symbol table of the first symbol, SYM_NAMES is
// their names, SYM_NAME_SIZE is the size of SYM_NAMES. This sets
- // SYMPOINTERS to point to the symbols in the symbol table.
+ // SYMPOINTERS to point to the symbols in the symbol table. It sets
+ // *DEFINED to the number of defined symbols.
template<int size, bool big_endian>
void
add_from_relobj(Sized_relobj<size, big_endian>* relobj,
const unsigned char* syms, size_t count,
size_t symndx_offset, const char* sym_names,
size_t sym_name_size,
- typename Sized_relobj<size, big_endian>::Symbols*);
+ typename Sized_relobj<size, big_endian>::Symbols*,
+ size_t* defined);
// Add COUNT dynamic symbols from the dynamic object DYNOBJ to the
// symbol table. SYMS is the symbols. SYM_NAMES is their names.
const unsigned char* syms, size_t count,
const char* sym_names, size_t sym_name_size,
const unsigned char* versym, size_t versym_size,
- const std::vector<const char*>*);
+ const std::vector<const char*>*,
+ typename Sized_relobj<size, big_endian>::Symbols*,
+ size_t* defined);
// Define a special symbol based on an Output_data. It is a
// multiple definition error if this symbol is already defined.
// Allocate the common symbols
void
- allocate_commons(Layout*);
+ allocate_commons(Layout*, Mapfile*);
// Add a warning for symbol NAME in object OBJ. WARNING is the text
// of the warning.
void
detect_odr_violations(const Task*, const char* output_file_name) const;
+ // Add any undefined symbols named on the command line to the symbol
+ // table.
+ void
+ add_undefined_symbols_from_command_line();
+
// SYM is defined using a COPY reloc. Return the dynamic object
// where the original definition was found.
Dynobj*
template<int size, bool big_endian>
void
- resolve(Sized_symbol<size>* to, const Sized_symbol<size>* from,
- const char* version);
+ resolve(Sized_symbol<size>* to, const Sized_symbol<size>* from);
// Record that a symbol is forced to be local by a version script.
void
elfcpp::STV visibility, unsigned char nonvis,
bool only_if_ref, bool force_override);
+ // Add any undefined symbols named on the command line to the symbol
+ // table, sized version.
+ template<int size>
+ void
+ do_add_undefined_symbols_from_command_line();
+
// Allocate the common symbols, sized version.
template<int size>
void
- do_allocate_commons(Layout*);
+ do_allocate_commons(Layout*, Mapfile*);
// Allocate the common symbols from one list.
template<int size>
void
- do_allocate_commons_list(Layout*, bool is_tls, Commons_type*);
+ do_allocate_commons_list(Layout*, bool is_tls, Commons_type*, Mapfile*);
// Implement detect_odr_violations.
template<int size, bool big_endian>