aboutsummaryrefslogtreecommitdiff
path: root/gold/object.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2007-05-16 17:42:48 +0000
committerIan Lance Taylor <iant@google.com>2007-05-16 17:42:48 +0000
commitb8e6aad9606384125f588d531c567f49bad346e2 (patch)
treee1172d50384713b91c329cc88cabcd2728f929a9 /gold/object.cc
parent60dfee729999b913a247956c4816e758afb86a4b (diff)
downloadgdb-b8e6aad9606384125f588d531c567f49bad346e2.zip
gdb-b8e6aad9606384125f588d531c567f49bad346e2.tar.gz
gdb-b8e6aad9606384125f588d531c567f49bad346e2.tar.bz2
Add support for SHF_MERGE sections.
Diffstat (limited to 'gold/object.cc')
-rw-r--r--gold/object.cc61
1 files changed, 40 insertions, 21 deletions
diff --git a/gold/object.cc b/gold/object.cc
index 01c4c16..eb975c6 100644
--- a/gold/object.cc
+++ b/gold/object.cc
@@ -127,8 +127,7 @@ Sized_relobj<size, big_endian>::Sized_relobj(
output_local_symbol_count_(0),
symbols_(NULL),
local_symbol_offset_(0),
- local_values_(),
- local_indexes_()
+ local_values_()
{
}
@@ -505,10 +504,9 @@ Sized_relobj<size, big_endian>::do_add_symbols(Symbol_table* symtab,
// Finalize the local symbols. Here we record the file offset at
// which they should be output, we add their names to *POOL, and we
-// add their values to THIS->LOCAL_VALUES_ and their indexes in the
-// output symbol table to THIS->LOCAL_INDEXES_. Return the symbol
-// index. This function is always called from the main thread. The
-// actual output of the local symbols will occur in a separate task.
+// add their values to THIS->LOCAL_VALUES_. Return the symbol index.
+// This function is always called from the main thread. The actual
+// output of the local symbols will occur in a separate task.
template<int size, bool big_endian>
unsigned int
@@ -542,7 +540,6 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(unsigned int index,
locsize);
this->local_values_.resize(loccount);
- this->local_indexes_.resize(loccount);
// Read the symbol names.
const unsigned int strtab_shndx = symtabshdr.get_sh_link();
@@ -562,12 +559,15 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(unsigned int index,
{
elfcpp::Sym<size, big_endian> sym(psyms);
+ Symbol_value<size>& lv(this->local_values_[i]);
+
unsigned int shndx = sym.get_st_shndx();
+ lv.set_input_shndx(shndx);
if (shndx >= elfcpp::SHN_LORESERVE)
{
if (shndx == elfcpp::SHN_ABS)
- this->local_values_[i] = sym.get_st_value();
+ lv.set_output_value(sym.get_st_value());
else
{
// FIXME: Handle SHN_XINDEX.
@@ -589,23 +589,28 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(unsigned int index,
gold_exit(false);
}
- if (mo[shndx].output_section == NULL)
+ Output_section* os = mo[shndx].output_section;
+
+ if (os == NULL)
{
- this->local_values_[i] = 0;
- this->local_indexes_[i] = -1U;
+ lv.set_output_value(0);
+ lv.set_no_output_symtab_entry();
continue;
}
- this->local_values_[i] = (mo[shndx].output_section->address()
- + mo[shndx].offset
- + sym.get_st_value());
+ if (mo[shndx].offset == -1)
+ lv.set_input_value(sym.get_st_value());
+ else
+ lv.set_output_value(mo[shndx].output_section->address()
+ + mo[shndx].offset
+ + sym.get_st_value());
}
// Decide whether this symbol should go into the output file.
if (sym.get_st_type() == elfcpp::STT_SECTION)
{
- this->local_indexes_[i] = -1U;
+ lv.set_no_output_symtab_entry();
continue;
}
@@ -622,9 +627,8 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(unsigned int index,
const char* name = pnames + sym.get_st_name();
pool->add(name, NULL);
- this->local_indexes_[i] = index;
+ lv.set_output_symtab_index(index);
++index;
- off += sym_size;
++count;
}
@@ -633,6 +637,23 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(unsigned int index,
return index;
}
+// Return the value of a local symbol defined in input section SHNDX,
+// with value VALUE, adding addend ADDEND. This handles SHF_MERGE
+// sections.
+template<int size, bool big_endian>
+typename elfcpp::Elf_types<size>::Elf_Addr
+Sized_relobj<size, big_endian>::local_value(unsigned int shndx,
+ Address value,
+ Address addend) const
+{
+ const std::vector<Map_to_output>& mo(this->map_to_output());
+ Output_section* os = mo[shndx].output_section;
+ if (os == NULL)
+ return addend;
+ gold_assert(mo[shndx].offset == -1);
+ return os->output_address(this, shndx, value + addend);
+}
+
// Write out the local symbols.
template<int size, bool big_endian>
@@ -676,7 +697,6 @@ Sized_relobj<size, big_endian>::write_local_symbols(Output_file* of,
const std::vector<Map_to_output>& mo(this->map_to_output());
gold_assert(this->local_values_.size() == loccount);
- gold_assert(this->local_indexes_.size() == loccount);
unsigned char* ov = oview;
psyms += sym_size;
@@ -684,9 +704,8 @@ Sized_relobj<size, big_endian>::write_local_symbols(Output_file* of,
{
elfcpp::Sym<size, big_endian> isym(psyms);
- if (this->local_indexes_[i] == -1U)
+ if (!this->local_values_[i].needs_output_symtab_entry())
continue;
- gold_assert(this->local_indexes_[i] != 0);
unsigned int st_shndx = isym.get_st_shndx();
if (st_shndx < elfcpp::SHN_LORESERVE)
@@ -702,7 +721,7 @@ Sized_relobj<size, big_endian>::write_local_symbols(Output_file* of,
gold_assert(isym.get_st_name() < strtab_size);
const char* name = pnames + isym.get_st_name();
osym.put_st_name(sympool->get_offset(name));
- osym.put_st_value(this->local_values_[i]);
+ osym.put_st_value(this->local_values_[i].value(this, 0));
osym.put_st_size(isym.get_st_size());
osym.put_st_info(isym.get_st_info());
osym.put_st_other(isym.get_st_other());