diff options
author | Ian Lance Taylor <iant@google.com> | 2006-11-16 00:38:25 +0000 |
---|---|---|
committer | Ian Lance Taylor <iant@google.com> | 2006-11-16 00:38:25 +0000 |
commit | c06b7b0ba3f6aaa4a3f9586689ef8bfdbd17454e (patch) | |
tree | 732f3a1719d66e1fd993872ecd58ca282d2858f8 /gold/object.cc | |
parent | 7495b3afc0d28e2d64995f383e2436a35aa14e6d (diff) | |
download | gdb-c06b7b0ba3f6aaa4a3f9586689ef8bfdbd17454e.zip gdb-c06b7b0ba3f6aaa4a3f9586689ef8bfdbd17454e.tar.gz gdb-c06b7b0ba3f6aaa4a3f9586689ef8bfdbd17454e.tar.bz2 |
Snapshot. Includes first cut at output relocation sections.
Diffstat (limited to 'gold/object.cc')
-rw-r--r-- | gold/object.cc | 88 |
1 files changed, 53 insertions, 35 deletions
diff --git a/gold/object.cc b/gold/object.cc index 1bfd969..74c1347 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -128,7 +128,8 @@ Sized_relobj<size, big_endian>::Sized_relobj( output_local_symbol_count_(0), symbols_(NULL), local_symbol_offset_(0), - values_(NULL) + local_values_(), + local_indexes_() { } @@ -505,23 +506,25 @@ 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->VALUES_. Return the new file offset. -// 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_ 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. template<int size, bool big_endian> -off_t -Sized_relobj<size, big_endian>::do_finalize_local_symbols(off_t off, +unsigned int +Sized_relobj<size, big_endian>::do_finalize_local_symbols(unsigned int index, + off_t off, Stringpool* pool) { assert(this->symtab_shndx_ != -1U); if (this->symtab_shndx_ == 0) { // This object has no symbols. Weird but legal. - return off; + return index; } - off = align_address(off, size >> 3); + assert(off == static_cast<off_t>(align_address(off, size >> 3))); this->local_symbol_offset_ = off; @@ -539,7 +542,8 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(off_t off, const unsigned char* psyms = this->get_view(symtabshdr.get_sh_offset(), locsize); - this->values_ = new typename elfcpp::Elf_types<size>::Elf_Addr[loccount]; + this->local_values_.resize(loccount); + this->local_indexes_.resize(loccount); // Read the symbol names. const unsigned int strtab_shndx = symtabshdr.get_sh_link(); @@ -550,7 +554,7 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(off_t off, // Loop over the local symbols. - std::vector<Map_to_output>& mo(this->map_to_output()); + const std::vector<Map_to_output>& mo(this->map_to_output()); unsigned int shnum = this->shnum(); unsigned int count = 0; // Skip the first, dummy, symbol. @@ -564,7 +568,7 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(off_t off, if (shndx >= elfcpp::SHN_LORESERVE) { if (shndx == elfcpp::SHN_ABS) - this->values_[i] = sym.get_st_value(); + this->local_values_[i] = sym.get_st_value(); else { // FIXME: Handle SHN_XINDEX. @@ -588,37 +592,46 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(off_t off, if (mo[shndx].output_section == NULL) { - this->values_[i] = 0; + this->local_values_[i] = 0; + this->local_indexes_[i] = -1U; continue; } - this->values_[i] = (mo[shndx].output_section->address() - + mo[shndx].offset - + sym.get_st_value()); + this->local_values_[i] = (mo[shndx].output_section->address() + + mo[shndx].offset + + sym.get_st_value()); } - if (sym.get_st_type() != elfcpp::STT_SECTION) + // Decide whether this symbol should go into the output file. + + if (sym.get_st_type() == elfcpp::STT_SECTION) { - if (sym.get_st_name() >= strtab_size) - { - fprintf(stderr, - _("%s: %s: local symbol %u section name " - "out of range: %u >= %u\n"), - program_name, this->name().c_str(), - i, sym.get_st_name(), - static_cast<unsigned int>(strtab_size)); - gold_exit(false); - } + this->local_indexes_[i] = -1U; + continue; + } - pool->add(pnames + sym.get_st_name(), NULL); - off += sym_size; - ++count; + if (sym.get_st_name() >= strtab_size) + { + fprintf(stderr, + _("%s: %s: local symbol %u section name " + "out of range: %u >= %u\n"), + program_name, this->name().c_str(), + i, sym.get_st_name(), + static_cast<unsigned int>(strtab_size)); + gold_exit(false); } + + const char* name = pnames + sym.get_st_name(); + pool->add(name, NULL); + this->local_indexes_[i] = index; + ++index; + off += sym_size; + ++count; } this->output_local_symbol_count_ = count; - return off; + return index; } // Write out the local symbols. @@ -661,16 +674,20 @@ Sized_relobj<size, big_endian>::write_local_symbols(Output_file* of, unsigned char* oview = of->get_output_view(this->local_symbol_offset_, output_size); - std::vector<Map_to_output>& mo(this->map_to_output()); + const std::vector<Map_to_output>& mo(this->map_to_output()); + + assert(this->local_values_.size() == loccount); + assert(this->local_indexes_.size() == loccount); - psyms += sym_size; unsigned char* ov = oview; + psyms += sym_size; for (unsigned int i = 1; i < loccount; ++i, psyms += sym_size) { elfcpp::Sym<size, big_endian> isym(psyms); - if (isym.get_st_type() == elfcpp::STT_SECTION) + if (this->local_indexes_[i] == -1U) continue; + assert(this->local_indexes_[i] != 0); unsigned int st_shndx = isym.get_st_shndx(); if (st_shndx < elfcpp::SHN_LORESERVE) @@ -684,8 +701,9 @@ Sized_relobj<size, big_endian>::write_local_symbols(Output_file* of, elfcpp::Sym_write<size, big_endian> osym(ov); assert(isym.get_st_name() < strtab_size); - osym.put_st_name(sympool->get_offset(pnames + isym.get_st_name())); - osym.put_st_value(this->values_[i]); + 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_size(isym.get_st_size()); osym.put_st_info(isym.get_st_info()); osym.put_st_other(isym.get_st_other()); |