X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gold%2Fcopy-relocs.cc;h=41b65631aad8f9f69c592c3519a9aa5c5c06d915;hb=e2ef962041bbe1ed89b238e11ee5a48487f386fb;hp=6ef72d3ed38677ca903142989e4ba28c5cd6ee4b;hpb=966d4097440bd7c3e35524bebf39d8bbe2e26fd6;p=platform%2Fupstream%2Fbinutils.git diff --git a/gold/copy-relocs.cc b/gold/copy-relocs.cc index 6ef72d3..41b6563 100644 --- a/gold/copy-relocs.cc +++ b/gold/copy-relocs.cc @@ -1,6 +1,6 @@ // copy-relocs.cc -- handle COPY relocations for gold. -// Copyright 2006, 2007, 2008 Free Software Foundation, Inc. +// Copyright (C) 2006-2014 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -28,25 +28,6 @@ namespace gold { -// Copy_relocs::Copy_reloc_entry methods. - -// Emit the reloc if appropriate. - -template -void -Copy_relocs::Copy_reloc_entry::emit( - Output_data_reloc* reloc_section) -{ - // If the symbol is no longer defined in a dynamic object, then we - // emitted a COPY relocation, and we do not want to emit this - // dynamic relocation. - if (this->sym_->is_from_dynobj()) - reloc_section->add_global(this->sym_, this->reloc_type_, - this->output_section_, this->relobj_, - this->shndx_, this->address_, - this->addend_); -} - // Copy_relocs methods. // Handle a relocation against a symbol which may force us to generate @@ -58,14 +39,14 @@ Copy_relocs::copy_reloc( Symbol_table* symtab, Layout* layout, Sized_symbol* sym, - Sized_relobj* object, + Sized_relobj_file* object, unsigned int shndx, - Output_section *output_section, + Output_section* output_section, const Reloc& rel, Output_data_reloc* reloc_section) { if (this->need_copy_reloc(sym, object, shndx)) - this->emit_copy_reloc(symtab, layout, sym, reloc_section); + this->make_copy_reloc(symtab, layout, sym, reloc_section); else { // We may not need a COPY relocation. Save this relocation to @@ -81,7 +62,7 @@ template bool Copy_relocs::need_copy_reloc( Sized_symbol* sym, - Sized_relobj* object, + Sized_relobj_file* object, unsigned int shndx) const { if (!parameters->options().copyreloc()) @@ -106,6 +87,25 @@ template void Copy_relocs::emit_copy_reloc( Symbol_table* symtab, + Sized_symbol* sym, + Output_data* posd, + off_t offset, + Output_data_reloc* reloc_section) +{ + // Define the symbol as being copied. + symtab->define_with_copy_reloc(sym, posd, offset); + + // Add the COPY relocation to the dynamic reloc section. + reloc_section->add_global_generic(sym, this->copy_reloc_type_, posd, + offset, 0); +} + +// Make a COPY relocation for SYM and emit it. + +template +void +Copy_relocs::make_copy_reloc( + Symbol_table* symtab, Layout* layout, Sized_symbol* sym, Output_data_reloc* reloc_section) @@ -125,20 +125,32 @@ Copy_relocs::emit_copy_reloc( bool is_ordinary; unsigned int shndx = sym->shndx(&is_ordinary); gold_assert(is_ordinary); - typename elfcpp::Elf_types::Elf_WXword addralign = - sym->object()->section_addralign(shndx); + typename elfcpp::Elf_types::Elf_WXword addralign; + + { + // Lock the object so we can read from it. This is only called + // single-threaded from scan_relocs, so it is OK to lock. + // Unfortunately we have no way to pass in a Task token. + const Task* dummy_task = reinterpret_cast(-1); + Object* obj = sym->object(); + Task_lock_obj tl(dummy_task, obj); + addralign = obj->section_addralign(shndx); + } typename Sized_symbol::Value_type value = sym->value(); while ((value & (addralign - 1)) != 0) addralign >>= 1; + // Mark the dynamic object as needed for the --as-needed option. + sym->object()->set_is_needed(); + if (this->dynbss_ == NULL) { this->dynbss_ = new Output_data_space(addralign, "** dynbss"); layout->add_output_section_data(".bss", elfcpp::SHT_NOBITS, elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE, - this->dynbss_); + this->dynbss_, ORDER_BSS, false); } Output_data_space* dynbss = this->dynbss_; @@ -152,24 +164,7 @@ Copy_relocs::emit_copy_reloc( section_size_type offset = dynbss_size; dynbss->set_current_data_size(dynbss_size + symsize); - // Define the symbol as being copied. - symtab->define_with_copy_reloc(sym, dynbss, offset); - - // Add the COPY relocation to the dynamic reloc section. - this->add_copy_reloc(sym, offset, reloc_section); -} - -// Add a COPY relocation for SYM to RELOC_SECTION. - -template -void -Copy_relocs::add_copy_reloc( - Symbol* sym, - section_size_type offset, - Output_data_reloc* reloc_section) -{ - reloc_section->add_global(sym, this->copy_reloc_type_, this->dynbss_, - offset, 0); + this->emit_copy_reloc(symtab, sym, dynbss, offset, reloc_section); } // Save a relocation to possibly be emitted later. @@ -178,7 +173,7 @@ template void Copy_relocs::save( Symbol* sym, - Sized_relobj* object, + Sized_relobj_file* object, unsigned int shndx, Output_section* output_section, const Reloc& rel) @@ -201,7 +196,18 @@ Copy_relocs::emit( for (typename Copy_reloc_entries::iterator p = this->entries_.begin(); p != this->entries_.end(); ++p) - p->emit(reloc_section); + { + Copy_reloc_entry& entry = *p; + + // If the symbol is no longer defined in a dynamic object, then we + // emitted a COPY relocation, and we do not want to emit this + // dynamic relocation. + if (entry.sym_->is_from_dynobj()) + reloc_section->add_global_generic(entry.sym_, entry.reloc_type_, + entry.output_section_, entry.relobj_, + entry.shndx_, entry.address_, + entry.addend_); + } // We no longer need the saved information. this->entries_.clear();