// Allocate common symbols. This requires write access to the
// symbol table, but is independent of the relocation processing.
- // FIXME: We should have an option to do this even for a relocatable
- // link.
- if (!parameters->options().relocatable())
+ if (parameters->options().define_common())
{
blocker->add_blocker();
workqueue->queue(new Allocate_commons_task(options, symtab, layout,
if (shndx >= elfcpp::SHN_LORESERVE)
{
- if (shndx == elfcpp::SHN_ABS)
+ if (shndx == elfcpp::SHN_ABS || shndx == elfcpp::SHN_COMMON)
lv.set_output_value(lv.input_value());
else
{
N_("--compress-debug-sections=[none" ZLIB_STR "]"),
TWO_DASHES,
&General_options::set_compress_debug_sections),
+ GENERAL_NOARG('d', "define-common", N_("Define common symbols"),
+ NULL, TWO_DASHES, &General_options::set_define_common),
+ GENERAL_NOARG('\0', "dc", NULL, NULL, ONE_DASH,
+ &General_options::set_define_common),
+ GENERAL_NOARG('\0', "dp", NULL, NULL, ONE_DASH,
+ &General_options::set_define_common),
+ GENERAL_NOARG('\0', "no-define-common", N_("Do not define common symbols"),
+ NULL, TWO_DASHES, &General_options::set_no_define_common),
SPECIAL('\0', "defsym", N_("Define a symbol"),
N_("--defsym SYMBOL=EXPRESSION"), TWO_DASHES,
&add_to_defsym),
// The default values for the general options.
General_options::General_options()
- : entry_(NULL),
+ : define_common_(false),
+ user_set_define_common_(false),
+ entry_(NULL),
export_dynamic_(false),
soname_(NULL),
dynamic_linker_(NULL),
this->options_.set_strip_debug(true);
}
+ // Set default value for define_common.
+ if (!this->options_.user_set_define_common())
+ this->options_.set_define_common(!this->options_.relocatable());
+
// FIXME: we can/should be doing a lot more sanity checking here.
}
General_options();
+ // -d: define common symbols.
+ bool
+ define_common() const
+ { return this->define_common_; }
+
// -e: set entry address.
const char*
entry() const
ZLIB_COMPRESSION,
};
+ void
+ set_define_common(bool value)
+ {
+ this->define_common_ = value;
+ this->user_set_define_common_ = true;
+ }
+
+ void
+ set_no_define_common(bool value)
+ { this->set_define_common(!value); }
+
+ bool
+ user_set_define_common() const
+ { return this->user_set_define_common_; }
+
void
set_entry(const char* arg)
{ this->entry_ = arg; }
void
add_sysroot();
+ bool define_common_;
+ bool user_set_define_common_;
const char* entry_;
bool export_dynamic_;
const char* soname_;
extern void
script_set_entry(void* closure, const char*, size_t);
+/* Called by the bison parser to set whether to define common symbols. */
+
+extern void
+script_set_common_allocation(void* closure, int);
+
/* Called by the bison parser to parse an OPTION. */
extern void
script_parse_option(closurev, arg.c_str(), arg.size());
}
+// Called by the bison parser to set whether to define common symbols.
+
+extern "C" void
+script_set_common_allocation(void* closurev, int set)
+{
+ const char* arg = set != 0 ? "--define-common" : "--no-define-common";
+ script_parse_option(closurev, arg, strlen(arg));
+}
+
// Called by the bison parser to define a symbol.
extern "C" void
// 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
{
// 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);
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
{
/* A command which may appear at top level of a linker script. */
file_cmd:
- GROUP
+ FORCE_COMMON_ALLOCATION
+ { script_set_common_allocation(closure, 1); }
+ | GROUP
{ script_start_group(closure); }
'(' input_list ')'
{ script_end_group(closure); }
+ | INHIBIT_COMMON_ALLOCATION
+ { script_set_common_allocation(closure, 0); }
| OPTION '(' string ')'
{ script_parse_option(closure, $3.value, $3.length); }
| PHDRS '{' phdrs_defs '}'