// common.cc -- handle common symbols for gold
-// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold.
// Allocate_commons_task methods.
-// This task allocates the common symbols. We need a lock on the
-// symbol table.
+// This task allocates the common symbols. We arrange to run it
+// before anything else which needs to access the symbol table.
Task_token*
Allocate_commons_task::is_runnable()
{
- if (!this->symtab_lock_->is_writable())
- return this->symtab_lock_;
return NULL;
}
-// Return the locks we hold: one on the symbol table, and one blocker.
+// Release a blocker.
void
Allocate_commons_task::locks(Task_locker* tl)
{
tl->add(this, this->blocker_);
- tl->add(this, this->symtab_lock_);
}
// Allocate the common symbols.
gold_unreachable();
}
- Output_data_space *poc = new Output_data_space(addralign, ds_name);
- Output_section *os = layout->add_output_section_data(name,
+ Output_data_space* poc = new Output_data_space(addralign, ds_name);
+ Output_section* os = layout->add_output_section_data(name,
elfcpp::SHT_NOBITS,
- flags, poc, false,
- false, false, false);
+ flags, poc,
+ ORDER_INVALID,
+ false);
if (os != NULL)
{
if (commons_section_type == COMMONS_SMALL)
Symbol* sym = *p;
if (sym == NULL)
break;
+
+ // Because we followed forwarding symbols above, but we didn't
+ // do it reliably before adding symbols to the list, it is
+ // possible for us to have the same symbol on the list twice.
+ // This can happen in the horrible case where a program defines
+ // a common symbol with the same name as a versioned libc
+ // symbol. That will show up here as a symbol which has already
+ // been allocated and is therefore no longer a common symbol.
+ if (!sym->is_common())
+ continue;
+
Sized_symbol<size>* ssym = this->get_sized_symbol<size>(sym);
// Record the symbol in the map file now, before we change its