aboutsummaryrefslogtreecommitdiff
path: root/gold/arm.cc
diff options
context:
space:
mode:
authorDoug Kwan <dougkwan@google.com>2010-01-13 02:00:39 +0000
committerDoug Kwan <dougkwan@google.com>2010-01-13 02:00:39 +0000
commit20138696beff2774d82f6fa26ca65a16af3c3e58 (patch)
tree7697aa9a61da97af11f7dfd3fa8628c91bc7be78 /gold/arm.cc
parenta8506f49f7446a1bf1eca995c39e2c973d6704f1 (diff)
downloadgdb-20138696beff2774d82f6fa26ca65a16af3c3e58.zip
gdb-20138696beff2774d82f6fa26ca65a16af3c3e58.tar.gz
gdb-20138696beff2774d82f6fa26ca65a16af3c3e58.tar.bz2
2010-01-12 Doug Kwan <dougkwan@google.com>
* arm.cc (Arm_relobj::mapping_symbols_info_): New data member. (Arm_relobj::Mapping_symbol_position, Arm_reloj::Mapping_symbol_position_less, Arm_relobj::Mapping_symbols_info): New types. (Target_arm::is_mapping_symbol_name): New method definition. (Arm_relobj::do_count_local_symbols): Save information about mapping symbols.
Diffstat (limited to 'gold/arm.cc')
-rw-r--r--gold/arm.cc67
1 files changed, 66 insertions, 1 deletions
diff --git a/gold/arm.cc b/gold/arm.cc
index a91df6c..401f04d 100644
--- a/gold/arm.cc
+++ b/gold/arm.cc
@@ -1069,7 +1069,8 @@ class Arm_relobj : public Sized_relobj<32, big_endian>
const typename elfcpp::Ehdr<32, big_endian>& ehdr)
: Sized_relobj<32, big_endian>(name, input_file, offset, ehdr),
stub_tables_(), local_symbol_is_thumb_function_(),
- attributes_section_data_(NULL), section_has_cortex_a8_workaround_(NULL)
+ attributes_section_data_(NULL), mapping_symbols_info_(),
+ section_has_cortex_a8_workaround_(NULL)
{ }
~Arm_relobj()
@@ -1133,6 +1134,26 @@ class Arm_relobj : public Sized_relobj<32, big_endian>
attributes_section_data() const
{ return this->attributes_section_data_; }
+ // Mapping symbol location.
+ typedef std::pair<unsigned int, Arm_address> Mapping_symbol_position;
+
+ // Functor for STL container.
+ struct Mapping_symbol_position_less
+ {
+ bool
+ operator()(const Mapping_symbol_position& p1,
+ const Mapping_symbol_position& p2) const
+ {
+ return (p1.first < p2.first
+ || (p1.first == p2.first && p1.second < p2.second));
+ }
+ };
+
+ // We only care about the first character of a mapping symbol, so
+ // we only store that instead of the whole symbol name.
+ typedef std::map<Mapping_symbol_position, char,
+ Mapping_symbol_position_less> Mapping_symbols_info;
+
// Whether a section contains any Cortex-A8 workaround.
bool
section_has_cortex_a8_workaround(unsigned int shndx) const
@@ -1193,6 +1214,8 @@ class Arm_relobj : public Sized_relobj<32, big_endian>
elfcpp::Elf_Word processor_specific_flags_;
// Object attributes if there is an .ARM.attributes section or NULL.
Attributes_section_data* attributes_section_data_;
+ // Mapping symbols information.
+ Mapping_symbols_info mapping_symbols_info_;
// Bitmap to indicate sections with Cortex-A8 workaround or NULL.
std::vector<bool>* section_has_cortex_a8_workaround_;
};
@@ -1579,6 +1602,16 @@ class Target_arm : public Sized_target<32, big_endian>
static bool
reloc_uses_thumb_bit(unsigned int r_type);
+ // Whether NAME belongs to a mapping symbol.
+ static bool
+ is_mapping_symbol_name(const char* name)
+ {
+ return (name
+ && name[0] == '$'
+ && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
+ && (name[2] == '\0' || name[2] == '.'));
+ }
+
protected:
// Make an ELF object.
Object*
@@ -4209,6 +4242,27 @@ Arm_relobj<big_endian>::do_count_local_symbols(
const unsigned char* psyms = this->get_view(symtabshdr.get_sh_offset(),
locsize, true, true);
+ // For mapping symbol processing, we need to read the symbol names.
+ unsigned int strtab_shndx = this->adjust_shndx(symtabshdr.get_sh_link());
+ if (strtab_shndx >= this->shnum())
+ {
+ this->error(_("invalid symbol table name index: %u"), strtab_shndx);
+ return;
+ }
+
+ elfcpp::Shdr<32, big_endian>
+ strtabshdr(this, this->elf_file()->section_header(strtab_shndx));
+ if (strtabshdr.get_sh_type() != elfcpp::SHT_STRTAB)
+ {
+ this->error(_("symbol table name section has wrong type: %u"),
+ static_cast<unsigned int>(strtabshdr.get_sh_type()));
+ return;
+ }
+ const char* pnames =
+ reinterpret_cast<const char*>(this->get_view(strtabshdr.get_sh_offset(),
+ strtabshdr.get_sh_size(),
+ false, false));
+
// Loop over the local symbols and mark any local symbols pointing
// to THUMB functions.
@@ -4223,6 +4277,17 @@ Arm_relobj<big_endian>::do_count_local_symbols(
Symbol_value<32>& lv((*plocal_values)[i]);
Arm_address input_value = lv.input_value();
+ // Check to see if this is a mapping symbol.
+ const char* sym_name = pnames + sym.get_st_name();
+ if (Target_arm<big_endian>::is_mapping_symbol_name(sym_name))
+ {
+ unsigned int input_shndx = sym.get_st_shndx();
+
+ // Strip of LSB in case this is a THUMB symbol.
+ Mapping_symbol_position msp(input_shndx, input_value & ~1U);
+ this->mapping_symbols_info_[msp] = sym_name[1];
+ }
+
if (st_type == elfcpp::STT_ARM_TFUNC
|| (st_type == elfcpp::STT_FUNC && ((input_value & 1) != 0)))
{