X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gold%2Fobject.cc;h=d8b3b901d2cd81a2177e544350a8379f0c03f8bd;hb=27b7985a736004936de48808cc24e3b19ff71ca1;hp=1d20b764ae5570fcc8365c97d3f8c89954789be6;hpb=cba134d613067d071aa58118435ed0b4ce9caffc;p=deliverable%2Fbinutils-gdb.git diff --git a/gold/object.cc b/gold/object.cc index 1d20b764ae..d8b3b901d2 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -1,5 +1,25 @@ // object.cc -- support for an object file for linking in gold +// Copyright 2006, 2007 Free Software Foundation, Inc. +// Written by Ian Lance Taylor . + +// This file is part of gold. + +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +// MA 02110-1301, USA. + #include "gold.h" #include @@ -53,11 +73,11 @@ Object::error(const char* format, ...) // Return a view of the contents of a section. const unsigned char* -Object::section_contents(unsigned int shndx, off_t* plen) +Object::section_contents(unsigned int shndx, off_t* plen, bool cache) { Location loc(this->do_section_contents(shndx)); *plen = loc.data_size; - return this->get_view(loc.file_offset, loc.data_size); + return this->get_view(loc.file_offset, loc.data_size, cache); } // Read the section data into SD. This is code common to Sized_relobj @@ -73,7 +93,7 @@ Object::read_section_data(elfcpp::Elf_file* elf_file, // Read the section headers. const off_t shoff = elf_file->shoff(); const unsigned int shnum = this->shnum(); - sd->section_headers = this->get_lasting_view(shoff, shnum * shdr_size); + sd->section_headers = this->get_lasting_view(shoff, shnum * shdr_size, true); // Read the section names. const unsigned char* pshdrs = sd->section_headers->data(); @@ -91,7 +111,7 @@ Object::read_section_data(elfcpp::Elf_file* elf_file, sd->section_names_size = shdrnames.get_sh_size(); sd->section_names = this->get_lasting_view(shdrnames.get_sh_offset(), - sd->section_names_size); + sd->section_names_size, false); } // If NAME is the name of a special .gnu.warning section, arrange for @@ -127,7 +147,8 @@ Sized_relobj::Sized_relobj( output_local_symbol_count_(0), symbols_(NULL), local_symbol_offset_(0), - local_values_() + local_values_(), + local_got_offsets_() { } @@ -219,7 +240,7 @@ Sized_relobj::do_read_symbols(Read_symbols_data* sd) off_t extsize = symtabshdr.get_sh_size() - locsize; // Read the symbol table. - File_view* fvsymtab = this->get_lasting_view(extoff, extsize); + File_view* fvsymtab = this->get_lasting_view(extoff, extsize, false); // Read the section header for the symbol names. unsigned int strtab_shndx = symtabshdr.get_sh_link(); @@ -241,7 +262,7 @@ Sized_relobj::do_read_symbols(Read_symbols_data* sd) // Read the symbol names. File_view* fvstrtab = this->get_lasting_view(strtabshdr.get_sh_offset(), - strtabshdr.get_sh_size()); + strtabshdr.get_sh_size(), true); sd->symbols = fvsymtab; sd->symbols_size = extsize; @@ -265,7 +286,7 @@ Sized_relobj::include_section_group( { // Read the section contents. const unsigned char* pcon = this->get_view(shdr.get_sh_offset(), - shdr.get_sh_size()); + shdr.get_sh_size(), false); const elfcpp::Elf_Word* pword = reinterpret_cast(pcon); @@ -294,13 +315,14 @@ Sized_relobj::include_section_group( gold_exit(false); } off_t symoff = symshdr.get_sh_offset() + shdr.get_sh_info() * This::sym_size; - const unsigned char* psym = this->get_view(symoff, This::sym_size); + const unsigned char* psym = this->get_view(symoff, This::sym_size, true); elfcpp::Sym sym(psym); // Read the symbol table names. off_t symnamelen; const unsigned char* psymnamesu; - psymnamesu = this->section_contents(symshdr.get_sh_link(), &symnamelen); + psymnamesu = this->section_contents(symshdr.get_sh_link(), &symnamelen, + true); const char* psymnames = reinterpret_cast(psymnamesu); // Get the section group signature. @@ -386,8 +408,7 @@ Sized_relobj::include_linkonce_section( template void -Sized_relobj::do_layout(const General_options& options, - Symbol_table* symtab, +Sized_relobj::do_layout(Symbol_table* symtab, Layout* layout, Read_symbols_data* sd) { @@ -427,7 +448,7 @@ Sized_relobj::do_layout(const General_options& options, if (this->handle_gnu_warning_section(name, i, symtab)) { - if (!options.is_relocatable()) + if (!parameters->output_is_object()) omit[i] = true; } @@ -482,7 +503,7 @@ Sized_relobj::do_add_symbols(Symbol_table* symtab, const int sym_size = This::sym_size; size_t symcount = sd->symbols_size / sym_size; - if (symcount * sym_size != sd->symbols_size) + if (static_cast(symcount * sym_size) != sd->symbols_size) { fprintf(stderr, _("%s: %s: size of symbols is not multiple of symbol size\n"), @@ -538,7 +559,7 @@ Sized_relobj::do_finalize_local_symbols(unsigned int index, gold_assert(loccount == symtabshdr.get_sh_info()); off_t locsize = loccount * sym_size; const unsigned char* psyms = this->get_view(symtabshdr.get_sh_offset(), - locsize); + locsize, true); this->local_values_.resize(loccount); @@ -546,7 +567,8 @@ Sized_relobj::do_finalize_local_symbols(unsigned int index, const unsigned int strtab_shndx = symtabshdr.get_sh_link(); off_t strtab_size; const unsigned char* pnamesu = this->section_contents(strtab_shndx, - &strtab_size); + &strtab_size, + true); const char* pnames = reinterpret_cast(pnamesu); // Loop over the local symbols. @@ -565,6 +587,9 @@ Sized_relobj::do_finalize_local_symbols(unsigned int index, unsigned int shndx = sym.get_st_shndx(); lv.set_input_shndx(shndx); + if (sym.get_st_type() == elfcpp::STT_SECTION) + lv.set_is_section_symbol(); + if (shndx >= elfcpp::SHN_LORESERVE) { if (shndx == elfcpp::SHN_ABS) @@ -627,7 +652,7 @@ Sized_relobj::do_finalize_local_symbols(unsigned int index, } const char* name = pnames + sym.get_st_name(); - pool->add(name, NULL); + pool->add(name, true, NULL); lv.set_output_symtab_index(index); ++index; ++count; @@ -638,13 +663,26 @@ Sized_relobj::do_finalize_local_symbols(unsigned int index, return index; } +// Return the value of the local symbol symndx. +template +typename elfcpp::Elf_types::Elf_Addr +Sized_relobj::local_symbol_value(unsigned int symndx) const +{ + gold_assert(symndx < this->local_symbol_count_); + gold_assert(symndx < this->local_values_.size()); + const Symbol_value& lv(this->local_values_[symndx]); + return lv.value(this, 0); +} + // Return the value of a local symbol defined in input section SHNDX, -// with value VALUE, adding addend ADDEND. This handles SHF_MERGE -// sections. +// with value VALUE, adding addend ADDEND. IS_SECTION_SYMBOL +// indicates whether the symbol is a section symbol. This handles +// SHF_MERGE sections. template typename elfcpp::Elf_types::Elf_Addr Sized_relobj::local_value(unsigned int shndx, Address value, + bool is_section_symbol, Address addend) const { const std::vector& mo(this->map_to_output()); @@ -652,7 +690,22 @@ Sized_relobj::local_value(unsigned int shndx, if (os == NULL) return addend; gold_assert(mo[shndx].offset == -1); - return os->output_address(this, shndx, value + addend); + + // Do the mapping required by the output section. If this is not a + // section symbol, then we want to map the symbol value, and then + // include the addend. If this is a section symbol, then we need to + // include the addend to figure out where in the section we are, + // before we do the mapping. This will do the right thing provided + // the assembler is careful to only convert a relocation in a merged + // section to a section symbol if there is a zero addend. If the + // assembler does not do this, then in general we can't know what to + // do, because we can't distinguish the addend for the instruction + // format from the addend for the section offset. + + if (is_section_symbol) + return os->output_address(this, shndx, value + addend); + else + return addend + os->output_address(this, shndx, value); } // Write out the local symbols. @@ -662,6 +715,9 @@ void Sized_relobj::write_local_symbols(Output_file* of, const Stringpool* sympool) { + if (parameters->strip_all()) + return; + gold_assert(this->symtab_shndx_ != -1U); if (this->symtab_shndx_ == 0) { @@ -681,13 +737,14 @@ Sized_relobj::write_local_symbols(Output_file* of, const int sym_size = This::sym_size; off_t locsize = loccount * sym_size; const unsigned char* psyms = this->get_view(symtabshdr.get_sh_offset(), - locsize); + locsize, false); // Read the symbol names. const unsigned int strtab_shndx = symtabshdr.get_sh_link(); off_t strtab_size; const unsigned char* pnamesu = this->section_contents(strtab_shndx, - &strtab_size); + &strtab_size, + true); const char* pnames = reinterpret_cast(pnamesu); // Get a view into the output file. @@ -767,11 +824,14 @@ Input_objects::add_object(Object* obj) this->target_ = target; else if (this->target_ != target) { - fprintf(stderr, "%s: %s: incompatible target\n", + fprintf(stderr, _("%s: %s: incompatible target\n"), program_name, obj->name().c_str()); gold_exit(false); } + set_parameters_size_and_endianness(target->get_size(), + target->is_big_endian()); + return true; }