summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2011-07-27 15:15:12 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2011-07-29 16:40:37 -0500
commit3293260511403dc21a42e949c8c248f61da92073 (patch)
tree9878e0bd03d8355e04a91ba1b3888191cd0fd1df /src
parentd91c2d0f5db929926584e0f47f27299eff9386e1 (diff)
downloadtalos-hostboot-3293260511403dc21a42e949c8c248f61da92073.tar.gz
talos-hostboot-3293260511403dc21a42e949c8c248f61da92073.zip
Linker checks for multiple weak symbols.
Cause the linker to stop the build if the image has multiple instances of the same weak symbol. This is to prevent, for instance, two different instances of the same Singleton<Foo> from being created in two different modules. Change-Id: I0204e69f191d63451a53b1f99dd226c9996bbccb Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/217 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/build/linker/linker.C60
-rw-r--r--src/include/usr/trace/interface.H21
-rw-r--r--src/usr/trace/trace.C38
3 files changed, 71 insertions, 48 deletions
diff --git a/src/build/linker/linker.C b/src/build/linker/linker.C
index 1b414608f..8e7b2f71c 100644
--- a/src/build/linker/linker.C
+++ b/src/build/linker/linker.C
@@ -109,7 +109,7 @@ struct Object
bool write_object();
/**
- * Read relocations
+ * Read relocations
* @return true if no errors
* @post sets symbols, relocs
*/
@@ -228,6 +228,7 @@ vector<Object> objects;
ofstream modinfo;
vector<uint64_t> all_relocations;
vector<ModuleTable> module_tables;
+map<string,size_t> weak_symbols;
//-----------------------------------------------------------------------------
// MAIN
@@ -276,7 +277,7 @@ int main(int argc, char** argv)
else // extended module
{
// allocate space for the module table in the extended image
- uint64_t table_size =
+ uint64_t table_size =
page_align(112*VFS_EXTENDED_MODULE_MAX);
fseek(output, table_size, SEEK_SET);
}
@@ -311,11 +312,11 @@ int main(int argc, char** argv)
}
// Write objects to their output file
- for_each(objects.begin(), objects.end(),
+ for_each(objects.begin(), objects.end(),
mem_fun_ref(&Object::write_object));
//bind2nd(mem_fun_ref(&Object::write_object), output));
- // used to find start of unallocated memory
+ // used to find start of unallocated memory
// goes in base binary only
uint64_t last_address = ftell(objects[0].iv_output);
@@ -334,7 +335,7 @@ int main(int argc, char** argv)
//
// Create module tables
- //
+ //
for(vector<ModuleTable>::iterator i = module_tables.begin();
i != module_tables.end(); ++i)
{
@@ -404,7 +405,7 @@ bool Object::read_object(const char* i_file)
}
else
{
- cout << "NON ELF format on file: " << i_file
+ cout << "NON ELF format on file: " << i_file
<< ". The file will be added as a binary blob." << endl;
image = NULL;
}
@@ -436,7 +437,7 @@ bool Object::read_object(const char* i_file)
cout << "Section " << s->name << endl;
cout << "\tSize " << std::dec << s->size << endl;
cout << "\tVMA " << std::hex << s->vma_offset << endl;
- cout << "\tData " << std::hex << bfd_getb64(s->data)
+ cout << "\tData " << std::hex << bfd_getb64(s->data)
<< "..." << endl;
}
@@ -457,7 +458,7 @@ bool Object::write_object()
offset = ftell(iv_output);
if(isELF())
- {
+ {
// Output TEXT section.
fseek(iv_output, text.vma_offset, SEEK_CUR);
if (text.size != fwrite(text.data, 1, text.size, iv_output))
@@ -484,7 +485,7 @@ bool Object::write_object()
fwrite(&zero, 0, 8 - (eof % 8), iv_output);
}
- modinfo << &name[(name.find_last_of("/")+1)] << ",0x"
+ modinfo << &name[(name.find_last_of("/")+1)] << ",0x"
<< std::hex << offset + base_addr << endl;
}
else // binary blob
@@ -557,6 +558,17 @@ bool Object::read_relocation()
}
else if (syms[i]->flags & (BSF_LOCAL | BSF_WEAK))
{
+ // Check weak symbol list for duplicate weak symbols.
+ if (syms[i]->flags & (BSF_WEAK))
+ {
+ if (weak_symbols[syms[i]->name]++)
+ {
+ throw std::runtime_error(
+ string("Duplicate weak symbol detected: ") +
+ s.name);
+ }
+ }
+
s.type |= Symbol::LOCAL;
cout << "\t\tLOCAL" << endl;
}
@@ -665,14 +677,14 @@ bool Object::perform_local_relocations()
if (address != i->addend)
{
ostringstream oss;
- oss << "Expected " << i->addend << " found " << address
+ oss << "Expected " << i->addend << " found " << address
<< " at " << (offset + i->address);
cout << oss.str() << endl;
throw range_error(oss.str());
}
// If it is a non-ABS relocation, also need to add the symbol addr.
- if (i->name != BFD_ABS_SECTION_NAME)
+ if (i->name != BFD_ABS_SECTION_NAME)
{
Symbol& s = this->symbols[i->name];
uint64_t symbol_addr = s.base + s.address;
@@ -687,7 +699,7 @@ bool Object::perform_local_relocations()
fseek(iv_output, offset + i->address, SEEK_SET);
fwrite(data, sizeof(uint64_t), 1, iv_output);
- cout << "\tRelocated " << i->addend << " at " << i->address << " to "
+ cout << "\tRelocated " << i->addend << " at " << i->address << " to "
<< relocation << endl;
}
}
@@ -711,8 +723,8 @@ bool Object::perform_global_relocations()
char data[sizeof(uint64_t)*3];
- for(int allow_local = 0;
- ((allow_local < 2) && (!found_symbol));
+ for(int allow_local = 0;
+ ((allow_local < 2) && (!found_symbol));
allow_local++)
{
for(vector<Object>::iterator j = objects.begin();
@@ -722,8 +734,8 @@ bool Object::perform_global_relocations()
if (j->symbols.find(i->name) != j->symbols.end())
{
Symbol s = j->symbols[i->name];
- uint64_t symbol_addr =
- j->offset + s.address + s.base;
+ uint64_t symbol_addr =
+ j->offset + s.address + s.base;
if (s.type & Symbol::UNRESOLVED)
continue;
@@ -734,7 +746,7 @@ bool Object::perform_global_relocations()
found_symbol = true;
- if ((s.type & Symbol::FUNCTION) &&
+ if ((s.type & Symbol::FUNCTION) &&
(i->type & Symbol::FUNCTION))
{
if (i->addend != 0)
@@ -758,8 +770,8 @@ bool Object::perform_global_relocations()
all_relocations.push_back(offset + i->address + 16);
}
- cout << "\tCopied relocation from " << std::hex
- << j->base_addr << ':' << symbol_addr << " to "
+ cout << "\tCopied relocation from " << std::hex
+ << j->base_addr << ':' << symbol_addr << " to "
<< base_addr << ':' << offset + i->address << "."
<< endl;
}
@@ -782,7 +794,7 @@ bool Object::perform_global_relocations()
if(!base_addr) all_relocations.push_back(offset + i->address);
cout << "\tRelocated from " << std::hex
- << j->base_addr << ':'
+ << j->base_addr << ':'
<< symbol_addr - j->base_addr << " to "
<< base_addr << ':' << offset + i->address << "."
<< endl;
@@ -809,7 +821,7 @@ uint64_t Object::find_init_symbol()
if (symbols.find(VFS_TOSTRING(VFS_SYMBOL_INIT)) == symbols.end())
return 0;
- return symbols[VFS_TOSTRING(VFS_SYMBOL_INIT)].address +
+ return symbols[VFS_TOSTRING(VFS_SYMBOL_INIT)].address +
offset + base_addr + data.vma_offset;
}
@@ -820,7 +832,7 @@ uint64_t Object::find_start_symbol()
if (symbols.find(VFS_TOSTRING(VFS_SYMBOL_START)) == symbols.end())
return 0;
- return symbols[VFS_TOSTRING(VFS_SYMBOL_START)].address +
+ return symbols[VFS_TOSTRING(VFS_SYMBOL_START)].address +
offset + base_addr + data.vma_offset;
}
@@ -831,7 +843,7 @@ uint64_t Object::find_fini_symbol()
if (symbols.find(VFS_TOSTRING(VFS_SYMBOL_FINI)) == symbols.end())
return 0;
- return symbols[VFS_TOSTRING(VFS_SYMBOL_FINI)].address +
+ return symbols[VFS_TOSTRING(VFS_SYMBOL_FINI)].address +
offset + base_addr + data.vma_offset;
}
@@ -946,7 +958,7 @@ void ModuleTable::write_table(vector<Object> & i_objects)
fwrite(data, sizeof(uint64_t), 1, iv_output);
cout << std::hex << std::setfill('0');
- cout << "\tAdded module " << object_name
+ cout << "\tAdded module " << object_name
<< " page size 0x" << module_size << endl;
cout << "\t\twith .text at 0x" << setw(16) << text_offset << endl;
cout << "\t\twith .data at 0x" << setw(16) << data_offset << endl;
diff --git a/src/include/usr/trace/interface.H b/src/include/usr/trace/interface.H
index 432b69648..5679f7420 100644
--- a/src/include/usr/trace/interface.H
+++ b/src/include/usr/trace/interface.H
@@ -1,14 +1,14 @@
/****************************************************************************
* $IBMCopyrightBlock:
- *
+ *
* IBM Confidential
- *
+ *
* Licensed Internal Code Source Materials
- *
+ *
* IBM HostBoot Licensed Internal Code
- *
- * (C) Copyright IBM Corp. 2004 - 2011
- *
+ *
+ * (C) Copyright IBM Corp. 2011
+ *
* The source code for this program is not published or other-
* wise divested of its trade secrets, irrespective of what has
* been deposited with the U.S. Copyright Office.
@@ -260,14 +260,9 @@ class TracInit
/* Constructor */
/*------------------------------------------------------------------------*/
- TracInit(trace_desc_t **o_td, const char *i_comp,const size_t i_size)
- {
- TRAC_INIT_BUFFER(o_td,i_comp,i_size);
- }
+ TracInit(trace_desc_t **o_td, const char *i_comp,const size_t i_size);
- ~TracInit()
- {
- }
+ ~TracInit();
};
diff --git a/src/usr/trace/trace.C b/src/usr/trace/trace.C
index cdad6103c..d52274473 100644
--- a/src/usr/trace/trace.C
+++ b/src/usr/trace/trace.C
@@ -40,11 +40,11 @@ const uint32_t TRAC_TIME_200MHZ = 2;
const uint32_t TRAC_TIME_167MHZ = 3; // 166666667Hz
const uint32_t COMP_NAME_SIZE = 16; // NULL terminated string
-// Initial implementation is to allocate a fixed 2KB buffer to each
+// Initial implementation is to allocate a fixed 2KB buffer to each
// component on request.
// NOTE: any change to this value will require change to Trace::initBuffer()
// since currently malloc() does not work for large allocations/fragmentations
-// and we are using PageManager::allocatePage() to allocate space for two
+// and we are using PageManager::allocatePage() to allocate space for two
// buffers at a time. Once malloc() works, we can remove this constraint.
const uint64_t TRAC_DEFAULT_BUFFER_SIZE = 0x0800; //2KB
@@ -64,6 +64,22 @@ typedef struct trace_desc_array {
trace_desc_array_t g_desc_array[TRAC_MAX_NUM_BUFFERS];
/******************************************************************************/
+// TracInit::TracInit()
+/******************************************************************************/
+TracInit::TracInit(trace_desc_t **o_td, const char *i_comp,const size_t i_size)
+{
+ TRAC_INIT_BUFFER(o_td,i_comp,i_size);
+}
+
+/******************************************************************************/
+// TracInit::~TracInit()
+/******************************************************************************/
+TracInit::~TracInit()
+{
+}
+
+
+/******************************************************************************/
// Trace::getTheInstance
/******************************************************************************/
Trace& Trace::getTheInstance()
@@ -108,7 +124,7 @@ void Trace::initBuffer(trace_desc_t **o_td, const char* i_comp,
/*------------------------------------------------------------------------*/
if(*o_td == NULL)
{
- // Limit component name to 15 characters.
+ // Limit component name to 15 characters.
// Too bad we don't have strncpy(), strncmp()
if (strlen(i_comp) > (COMP_NAME_SIZE -1))
{
@@ -155,7 +171,7 @@ void Trace::initBuffer(trace_desc_t **o_td, const char* i_comp,
// one buffer at a time.
l_td = static_cast<char *>(PageManager::allocatePage());
- g_desc_array[i].td_entry =
+ g_desc_array[i].td_entry =
reinterpret_cast<trace_desc_t *>(l_td);
g_desc_array[i+1].td_entry =
@@ -178,7 +194,7 @@ void Trace::initBuffer(trace_desc_t **o_td, const char* i_comp,
{
//printk("Trace::initBuffer - allocate default buffer %d\n", i);
- // We're out of buffers to allocate.
+ // We're out of buffers to allocate.
// Use the default buffer reserved for everyone else.
// Initialize only once
if (strlen(g_desc_array[i].comp) == 0)
@@ -186,7 +202,7 @@ void Trace::initBuffer(trace_desc_t **o_td, const char* i_comp,
// Set the component name for the buffer
strcpy(g_desc_array[i].comp, TRAC_DEFAULT_BUFFER_NAME);
- // Allocate memory if needed
+ // Allocate memory if needed
// Memory should have already been reserved if
// TRAC_MAX_NUM_BUFFERS is an even # and we're using
// PageManager::allocatePage(). Add check just in
@@ -200,9 +216,9 @@ void Trace::initBuffer(trace_desc_t **o_td, const char* i_comp,
// Throw away the last 2KB for now to keep code simple
// until we decide to add support for variable-sized
- // buffers. Also, once we change to use malloc(),
+ // buffers. Also, once we change to use malloc(),
// we won't have this problem.
- g_desc_array[i].td_entry =
+ g_desc_array[i].td_entry =
reinterpret_cast<trace_desc_t *>(l_td);
}
@@ -550,7 +566,7 @@ trace_desc_t * Trace::getTd(const char *i_comp)
if (strlen(i_comp) != 0)
{
- // Limit component name to 15 characters.
+ // Limit component name to 15 characters.
if (strlen(i_comp) > (COMP_NAME_SIZE -1))
{
memcpy(l_comp, i_comp, COMP_NAME_SIZE - 1);
@@ -562,7 +578,7 @@ trace_desc_t * Trace::getTd(const char *i_comp)
// Search all allocated component buffers
for(i=0;
- (i < (TRAC_MAX_NUM_BUFFERS - 1)) &&
+ (i < (TRAC_MAX_NUM_BUFFERS - 1)) &&
(strlen(g_desc_array[i].comp) != 0);
i++)
{
@@ -576,7 +592,7 @@ trace_desc_t * Trace::getTd(const char *i_comp)
if (((TRAC_MAX_NUM_BUFFERS - 1) == i) &&
(strlen(g_desc_array[i].comp) != 0))
-
+
{
// Must be the default buffer
l_td = g_desc_array[i].td_entry;
OpenPOWER on IntegriCloud