static std::string
demangle(const char* name)
{
- if (!parameters->demangle())
+ if (!parameters->options().demangle())
return name;
// cplus_demangle allocates memory for the result it returns,
// If exporting all symbols or building a shared library,
// and the symbol is defined in a regular object and is
// externally visible, we need to add it.
- if ((parameters->export_dynamic() || parameters->output_is_shared())
+ if ((parameters->options().export_dynamic() || parameters->options().shared())
&& !this->is_from_dynobj()
&& this->is_externally_visible())
return true;
{
// If we are not generating an executable, then no final values are
// known, since they will change at runtime.
- if (!parameters->output_is_executable())
+ if (parameters->options().shared() || parameters->options().relocatable())
return false;
// If the symbol is not from an object file, then it is defined, and
return parameters->doing_static_link();
}
-// Return whether the symbol has an absolute value.
+// Return the output section where this symbol is defined.
-bool
-Symbol::value_is_absolute() const
+Output_section*
+Symbol::output_section() const
{
switch (this->source_)
{
case FROM_OBJECT:
- return this->u_.from_object.shndx == elfcpp::SHN_ABS;
+ {
+ unsigned int shndx = this->u_.from_object.shndx;
+ if (shndx != elfcpp::SHN_UNDEF && shndx < elfcpp::SHN_LORESERVE)
+ {
+ gold_assert(!this->u_.from_object.object->is_dynamic());
+ Relobj* relobj = static_cast<Relobj*>(this->u_.from_object.object);
+ section_offset_type dummy;
+ return relobj->output_section(shndx, &dummy);
+ }
+ return NULL;
+ }
+
case IN_OUTPUT_DATA:
+ return this->u_.in_output_data.output_data->output_section();
+
case IN_OUTPUT_SEGMENT:
- return false;
case CONSTANT:
- return true;
+ return NULL;
+
+ default:
+ gold_unreachable();
+ }
+}
+
+// Set the symbol's output section. This is used for symbols defined
+// in scripts. This should only be called after the symbol table has
+// been finalized.
+
+void
+Symbol::set_output_section(Output_section* os)
+{
+ switch (this->source_)
+ {
+ case FROM_OBJECT:
+ case IN_OUTPUT_DATA:
+ gold_assert(this->output_section() == os);
+ break;
+ case CONSTANT:
+ this->source_ = IN_OUTPUT_DATA;
+ this->u_.in_output_data.output_data = os;
+ this->u_.in_output_data.offset_is_from_end = false;
+ break;
+ case IN_OUTPUT_SEGMENT:
default:
gold_unreachable();
}
typename Sized_relobj<size, big_endian>::Symbols* sympointers)
{
gold_assert(size == relobj->target()->get_size());
- gold_assert(size == parameters->get_size());
+ gold_assert(size == parameters->target().get_size());
const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
const std::vector<const char*>* version_map)
{
gold_assert(size == dynobj->target()->get_size());
- gold_assert(size == parameters->get_size());
+ gold_assert(size == parameters->target().get_size());
if (dynobj->just_symbols())
{
}
}
- const Target* target = parameters->target();
- if (!target->has_make_symbol())
+ const Target& target = parameters->target();
+ if (!target.has_make_symbol())
sym = new Sized_symbol<size>();
else
{
- gold_assert(target->get_size() == size);
- gold_assert(target->is_big_endian() ? big_endian : !big_endian);
+ gold_assert(target.get_size() == size);
+ gold_assert(target.is_big_endian() ? big_endian : !big_endian);
typedef Sized_target<size, big_endian> My_target;
const My_target* sized_target =
- static_cast<const My_target*>(target);
+ static_cast<const My_target*>(&target);
sym = sized_target->make_symbol();
if (sym == NULL)
return NULL;
bool offset_is_from_end,
bool only_if_ref)
{
- if (parameters->get_size() == 32)
+ if (parameters->target().get_size() == 32)
{
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG)
return this->do_define_in_output_data<32>(name, version, od,
gold_unreachable();
#endif
}
- else if (parameters->get_size() == 64)
+ else if (parameters->target().get_size() == 64)
{
#if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG)
return this->do_define_in_output_data<64>(name, version, od,
Sized_symbol<size>* sym;
Sized_symbol<size>* oldsym;
- if (parameters->is_big_endian())
+ if (parameters->target().is_big_endian())
{
#if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG)
sym = this->define_special_symbol SELECT_SIZE_ENDIAN_NAME(size, true) (
Symbol::Segment_offset_base offset_base,
bool only_if_ref)
{
- if (parameters->get_size() == 32)
+ if (parameters->target().get_size() == 32)
{
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG)
return this->do_define_in_output_segment<32>(name, version, os,
gold_unreachable();
#endif
}
- else if (parameters->get_size() == 64)
+ else if (parameters->target().get_size() == 64)
{
#if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG)
return this->do_define_in_output_segment<64>(name, version, os,
Sized_symbol<size>* sym;
Sized_symbol<size>* oldsym;
- if (parameters->is_big_endian())
+ if (parameters->target().is_big_endian())
{
#if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG)
sym = this->define_special_symbol SELECT_SIZE_ENDIAN_NAME(size, true) (
elfcpp::STB binding,
elfcpp::STV visibility,
unsigned char nonvis,
- bool only_if_ref)
+ bool only_if_ref,
+ bool force_override)
{
- if (parameters->get_size() == 32)
+ if (parameters->target().get_size() == 32)
{
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG)
return this->do_define_as_constant<32>(name, version, value,
symsize, type, binding,
- visibility, nonvis, only_if_ref);
+ visibility, nonvis, only_if_ref,
+ force_override);
#else
gold_unreachable();
#endif
}
- else if (parameters->get_size() == 64)
+ else if (parameters->target().get_size() == 64)
{
#if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG)
return this->do_define_as_constant<64>(name, version, value,
symsize, type, binding,
- visibility, nonvis, only_if_ref);
+ visibility, nonvis, only_if_ref,
+ force_override);
#else
gold_unreachable();
#endif
elfcpp::STB binding,
elfcpp::STV visibility,
unsigned char nonvis,
- bool only_if_ref)
+ bool only_if_ref,
+ bool force_override)
{
Sized_symbol<size>* sym;
Sized_symbol<size>* oldsym;
- if (parameters->is_big_endian())
+ if (parameters->target().is_big_endian())
{
#if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG)
sym = this->define_special_symbol SELECT_SIZE_ENDIAN_NAME(size, true) (
return sym;
}
- if (Symbol_table::should_override_with_special(oldsym))
+ if (force_override || Symbol_table::should_override_with_special(oldsym))
this->override_with_special(oldsym, sym);
delete sym;
return oldsym;
else
this->define_as_constant(p->name, NULL, 0, p->size, p->type,
p->binding, p->visibility, p->nonvis,
- only_if_ref || p->only_if_ref);
+ only_if_ref || p->only_if_ref,
+ false);
}
}
else
this->define_as_constant(p->name, NULL, 0, p->size, p->type,
p->binding, p->visibility, p->nonvis,
- only_if_ref || p->only_if_ref);
+ only_if_ref || p->only_if_ref,
+ false);
}
}
this->first_dynamic_global_index_ = dyn_global_index;
this->dynamic_count_ = dyncount;
- if (parameters->get_size() == 32)
+ if (parameters->target().get_size() == 32)
{
#if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_32_LITTLE)
ret = this->sized_finalize<32>(off, pool, plocal_symcount);
gold_unreachable();
#endif
}
- else if (parameters->get_size() == 64)
+ else if (parameters->target().get_size() == 64)
{
#if defined(HAVE_TARGET_64_BIG) || defined(HAVE_TARGET_64_LITTLE)
ret = this->sized_finalize<64>(off, pool, plocal_symcount);
// FIXME: We need some target specific support here.
if (shndx >= elfcpp::SHN_LORESERVE
- && shndx != elfcpp::SHN_ABS)
+ && shndx != elfcpp::SHN_ABS
+ && shndx != elfcpp::SHN_COMMON)
{
gold_error(_("%s: unsupported symbol section 0x%x"),
sym->demangled_name().c_str(), shndx);
}
else if (shndx == elfcpp::SHN_UNDEF)
value = 0;
- else if (shndx == elfcpp::SHN_ABS)
+ else if (shndx == elfcpp::SHN_ABS || shndx == elfcpp::SHN_COMMON)
value = sym->value();
else
{
sym->set_value(value);
- if (parameters->strip_all())
+ if (parameters->options().strip_all())
{
sym->set_symtab_index(-1U);
return false;
const Stringpool* sympool,
const Stringpool* dynpool, Output_file* of) const
{
- if (parameters->get_size() == 32)
+ switch (parameters->size_and_endianness())
{
- if (parameters->is_big_endian())
- {
-#ifdef HAVE_TARGET_32_BIG
- this->sized_write_globals<32, true>(input_objects, sympool,
- dynpool, of);
-#else
- gold_unreachable();
-#endif
- }
- else
- {
#ifdef HAVE_TARGET_32_LITTLE
- this->sized_write_globals<32, false>(input_objects, sympool,
- dynpool, of);
-#else
- gold_unreachable();
+ case Parameters::TARGET_32_LITTLE:
+ this->sized_write_globals<32, false>(input_objects, sympool,
+ dynpool, of);
+ break;
#endif
- }
- }
- else if (parameters->get_size() == 64)
- {
- if (parameters->is_big_endian())
- {
-#ifdef HAVE_TARGET_64_BIG
- this->sized_write_globals<64, true>(input_objects, sympool,
- dynpool, of);
-#else
- gold_unreachable();
+#ifdef HAVE_TARGET_32_BIG
+ case Parameters::TARGET_32_BIG:
+ this->sized_write_globals<32, true>(input_objects, sympool,
+ dynpool, of);
+ break;
#endif
- }
- else
- {
#ifdef HAVE_TARGET_64_LITTLE
- this->sized_write_globals<64, false>(input_objects, sympool,
- dynpool, of);
-#else
- gold_unreachable();
+ case Parameters::TARGET_64_LITTLE:
+ this->sized_write_globals<64, false>(input_objects, sympool,
+ dynpool, of);
+ break;
#endif
- }
+#ifdef HAVE_TARGET_64_BIG
+ case Parameters::TARGET_64_BIG:
+ this->sized_write_globals<64, true>(input_objects, sympool,
+ dynpool, of);
+ break;
+#endif
+ default:
+ gold_unreachable();
}
- else
- gold_unreachable();
}
// Write out the global symbols.
const Stringpool* dynpool,
Output_file* of) const
{
- const Target* const target = parameters->target();
+ const Target& target = parameters->target();
const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
const unsigned int output_count = this->output_count_;
const section_size_type oview_size = output_count * sym_size;
const unsigned int first_global_index = this->first_global_index_;
- unsigned char* const psyms = of->get_output_view(this->offset_, oview_size);
+ unsigned char* psyms;
+ if (this->offset_ == 0 || output_count == 0)
+ psyms = NULL;
+ else
+ psyms = of->get_output_view(this->offset_, oview_size);
const unsigned int dynamic_count = this->dynamic_count_;
const section_size_type dynamic_size = dynamic_count * sym_size;
const unsigned int first_dynamic_global_index =
this->first_dynamic_global_index_;
unsigned char* dynamic_view;
- if (this->dynamic_offset_ == 0)
+ if (this->dynamic_offset_ == 0 || dynamic_count == 0)
dynamic_view = NULL;
else
dynamic_view = of->get_output_view(this->dynamic_offset_, dynamic_size);
// FIXME: We need some target specific support here.
if (in_shndx >= elfcpp::SHN_LORESERVE
- && in_shndx != elfcpp::SHN_ABS)
+ && in_shndx != elfcpp::SHN_ABS
+ && in_shndx != elfcpp::SHN_COMMON)
{
gold_error(_("%s: unsupported symbol section 0x%x"),
sym->demangled_name().c_str(), in_shndx);
if (symobj->is_dynamic())
{
if (sym->needs_dynsym_value())
- dynsym_value = target->dynsym_value(sym);
+ dynsym_value = target.dynsym_value(sym);
shndx = elfcpp::SHN_UNDEF;
}
else if (in_shndx == elfcpp::SHN_UNDEF
- || in_shndx == elfcpp::SHN_ABS)
+ || in_shndx == elfcpp::SHN_ABS
+ || in_shndx == elfcpp::SHN_COMMON)
shndx = in_shndx;
else
{
// In object files symbol values are section
// relative.
- if (parameters->output_is_object())
+ if (parameters->options().relocatable())
sym_value -= os->address();
}
}
&& sym->object()->is_dynamic()
&& sym->shndx() == elfcpp::SHN_UNDEF
&& sym->binding() != elfcpp::STB_WEAK
- && !parameters->allow_shlib_undefined()
- && !parameters->target()->is_defined_by_abi(sym)
+ && !parameters->options().allow_shlib_undefined()
+ && !parameters->target().is_defined_by_abi(sym)
&& !input_objects->found_in_system_library_directory(sym->object()))
{
// A very ugly cast.
Output_file* of,
off_t offset) const
{
- if (parameters->get_size() == 32)
+ switch (parameters->size_and_endianness())
{
- if (parameters->is_big_endian())
- {
-#ifdef HAVE_TARGET_32_BIG
- this->sized_write_section_symbol<32, true>(os, of, offset);
-#else
- gold_unreachable();
-#endif
- }
- else
- {
#ifdef HAVE_TARGET_32_LITTLE
- this->sized_write_section_symbol<32, false>(os, of, offset);
-#else
- gold_unreachable();
+ case Parameters::TARGET_32_LITTLE:
+ this->sized_write_section_symbol<32, false>(os, of, offset);
+ break;
#endif
- }
- }
- else if (parameters->get_size() == 64)
- {
- if (parameters->is_big_endian())
- {
-#ifdef HAVE_TARGET_64_BIG
- this->sized_write_section_symbol<64, true>(os, of, offset);
-#else
- gold_unreachable();
+#ifdef HAVE_TARGET_32_BIG
+ case Parameters::TARGET_32_BIG:
+ this->sized_write_section_symbol<32, true>(os, of, offset);
+ break;
#endif
- }
- else
- {
#ifdef HAVE_TARGET_64_LITTLE
- this->sized_write_section_symbol<64, false>(os, of, offset);
-#else
- gold_unreachable();
+ case Parameters::TARGET_64_LITTLE:
+ this->sized_write_section_symbol<64, false>(os, of, offset);
+ break;
#endif
- }
+#ifdef HAVE_TARGET_64_BIG
+ case Parameters::TARGET_64_BIG:
+ this->sized_write_section_symbol<64, true>(os, of, offset);
+ break;
+#endif
+ default:
+ gold_unreachable();
}
- else
- gold_unreachable();
}
// Write out a section symbol, specialized for size and endianness.