aboutsummaryrefslogtreecommitdiff
path: root/gold/object.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2006-08-18 22:29:20 +0000
committerIan Lance Taylor <iant@google.com>2006-08-18 22:29:20 +0000
commit14bfc3f55540e60253cc4aae73261325309f750a (patch)
treecb74fe438b44c7aa6e02f05e14f13ba1ae0b508a /gold/object.cc
parent476308bf9bd077b87791da50a13a74b2698c01c7 (diff)
downloadgdb-14bfc3f55540e60253cc4aae73261325309f750a.zip
gdb-14bfc3f55540e60253cc4aae73261325309f750a.tar.gz
gdb-14bfc3f55540e60253cc4aae73261325309f750a.tar.bz2
Another snapshot of the current state of the sources. Gets to the
point of symbol resolution and can now issue a multiple definition error. Also added target selection infrastructure.
Diffstat (limited to 'gold/object.cc')
-rw-r--r--gold/object.cc65
1 files changed, 39 insertions, 26 deletions
diff --git a/gold/object.cc b/gold/object.cc
index 8835915..bad7f47 100644
--- a/gold/object.cc
+++ b/gold/object.cc
@@ -7,6 +7,7 @@
#include <cassert>
#include "object.h"
+#include "target-select.h"
namespace gold
{
@@ -40,16 +41,16 @@ Sized_object<size, big_endian>::Sized_object(
Input_file* input_file,
off_t offset,
const elfcpp::Ehdr<size, big_endian>& ehdr)
- : Object(name, input_file, offset),
+ : Object(name, input_file, false, offset),
osabi_(ehdr.get_e_ident()[elfcpp::EI_OSABI]),
abiversion_(ehdr.get_e_ident()[elfcpp::EI_ABIVERSION]),
machine_(ehdr.get_e_machine()),
flags_(ehdr.get_e_flags()),
- target_(NULL),
shoff_(ehdr.get_e_shoff()),
shnum_(0),
shstrndx_(0),
- symtab_shnum_(0)
+ symtab_shnum_(0),
+ symbols_(NULL)
{
if (ehdr.get_e_ehsize() != elfcpp::Elf_sizes<size>::ehdr_size)
{
@@ -80,8 +81,15 @@ void
Sized_object<size, big_endian>::setup(
const elfcpp::Ehdr<size, big_endian>& ehdr)
{
- // this->target_ = select_target(this->machine_, size, big_endian,
- // this->osabi_, this->abiversion_);
+ Target* target = select_target(this->machine_, size, big_endian,
+ this->osabi_, this->abiversion_);
+ if (target == NULL)
+ {
+ fprintf(stderr, _("%s: %s: unsupported ELF machine number %d\n"),
+ program_name, this->name().c_str(), this->machine_);
+ gold_exit(false);
+ }
+ this->set_target(target);
unsigned int shnum = ehdr.get_e_shnum();
unsigned int shstrndx = ehdr.get_e_shstrndx();
if ((shnum == 0 || shstrndx == elfcpp::SHN_XINDEX)
@@ -143,9 +151,14 @@ Sized_object<size, big_endian>::do_read_symbols()
elfcpp::Shdr<size, big_endian> symtabshdr(psymtabshdr);
assert(symtabshdr.get_sh_type() == elfcpp::SHT_SYMTAB);
+ // We only need the external symbols.
+ int sym_size = elfcpp::Elf_sizes<size>::sym_size;
+ off_t locsize = symtabshdr.get_sh_info() * sym_size;
+ off_t extoff = symtabshdr.get_sh_offset() + locsize;
+ off_t extsize = symtabshdr.get_sh_size() - locsize;
+
// Read the symbol table.
- File_view* fvsymtab = this->get_lasting_view(symtabshdr.get_sh_offset(),
- symtabshdr.get_sh_size());
+ File_view* fvsymtab = this->get_lasting_view(extoff, extsize);
// Read the section header for the symbol names.
unsigned int strtab_shnum = symtabshdr.get_sh_link();
@@ -173,7 +186,7 @@ Sized_object<size, big_endian>::do_read_symbols()
Read_symbols_data ret;
ret.symbols = fvsymtab;
- ret.symbols_size = symtabshdr.get_sh_size();
+ ret.symbols_size = extsize;
ret.symbol_names = fvstrtab;
ret.symbol_names_size = strtabshdr.get_sh_size();
@@ -184,7 +197,8 @@ Sized_object<size, big_endian>::do_read_symbols()
template<int size, bool big_endian>
void
-Sized_object<size, big_endian>::do_add_symbols(Read_symbols_data sd)
+Sized_object<size, big_endian>::do_add_symbols(Symbol_table* symtab,
+ Read_symbols_data sd)
{
if (sd.symbols == NULL)
{
@@ -192,25 +206,24 @@ Sized_object<size, big_endian>::do_add_symbols(Read_symbols_data sd)
return;
}
- int sym_size = elfcpp::Elf_sizes<size>::sym_size;
- const unsigned char* symstart = sd.symbols->data();
- const unsigned char* symend = symstart + sd.symbols_size;
- for (const unsigned char* p = symstart; p < symend; p += sym_size)
+ unsigned int sym_size = elfcpp::Elf_sizes<size>::sym_size;
+ size_t symcount = sd.symbols_size / sym_size;
+ if (symcount * sym_size != sd.symbols_size)
{
- elfcpp::Sym<size, big_endian> sym(p);
-
- unsigned int nameoff = sym.get_st_name();
- if (nameoff >= sd.symbol_names_size)
- {
- fprintf(stderr,
- _("%s: %s: invalid symbol name offset %u for symbol %d\n"),
- program_name, this->name().c_str(), nameoff,
- (p - symstart) / sym_size);
- gold_exit(false);
- }
- const unsigned char* name = sd.symbol_names->data() + nameoff;
- printf("%s\n", name);
+ fprintf(stderr,
+ _("%s: %s: size of symbols is not multiple of symbol size\n"),
+ program_name, this->name().c_str());
+ gold_exit(false);
}
+
+ this->symbols_ = new Symbol*[symcount];
+
+ const elfcpp::Sym<size, big_endian>* syms =
+ reinterpret_cast<const elfcpp::Sym<size, big_endian>*>(sd.symbols->data());
+ const char* sym_names =
+ reinterpret_cast<const char*>(sd.symbol_names->data());
+ symtab->add_from_object(this, syms, symcount, sym_names,
+ sd.symbol_names_size, this->symbols_);
}
} // End namespace gold.