123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- // copy-relocs.h -- handle COPY relocations for gold -*- C++ -*-
- // Copyright (C) 2006-2015 Free Software Foundation, Inc.
- // Written by Ian Lance Taylor <iant@google.com>.
- // 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.
- #ifndef GOLD_COPY_RELOCS_H
- #define GOLD_COPY_RELOCS_H
- #include "elfcpp.h"
- #include "reloc-types.h"
- #include "output.h"
- namespace gold
- {
- // This class is used to manage COPY relocations. We try to avoid
- // them when possible. A COPY relocation may be required when an
- // executable refers to a variable defined in a shared library. COPY
- // relocations are problematic because they tie the executable to the
- // exact size of the variable in the shared library. We can avoid
- // them if all the references to the variable are in a writeable
- // section. In that case we can simply use dynamic relocations.
- // However, when scanning relocs, we don't know when we see the
- // relocation whether we will be forced to use a COPY relocation or
- // not. So we have to save the relocation during the reloc scanning,
- // and then emit it as a dynamic relocation if necessary. This class
- // implements that. It is used by the target specific code.
- // The template parameter SH_TYPE is the type of the reloc section to
- // be used for COPY relocs: elfcpp::SHT_REL or elfcpp::SHT_RELA.
- template<int sh_type, int size, bool big_endian>
- class Copy_relocs
- {
- private:
- typedef typename Reloc_types<sh_type, size, big_endian>::Reloc Reloc;
- public:
- Copy_relocs(unsigned int copy_reloc_type)
- : entries_(), copy_reloc_type_(copy_reloc_type), dynbss_(NULL)
- { }
- // This is called while scanning relocs if we see a relocation
- // against a symbol which may force us to generate a COPY reloc.
- // SYM is the symbol. OBJECT is the object whose relocs we are
- // scanning. The relocation is being applied to section SHNDX in
- // OBJECT. OUTPUT_SECTION is the output section where section SHNDX
- // will wind up. REL is the reloc itself. The Output_data_reloc
- // section is where the dynamic relocs are put.
- void
- copy_reloc(Symbol_table*, Layout*, Sized_symbol<size>* sym,
- Sized_relobj_file<size, big_endian>* object,
- unsigned int shndx, Output_section* output_section,
- const Reloc& rel,
- Output_data_reloc<sh_type, true, size, big_endian>*);
- // Return whether there are any saved relocations.
- bool
- any_saved_relocs() const
- { return !this->entries_.empty(); }
- // Emit any saved relocations which turn out to be needed. This is
- // called after all the relocs have been scanned.
- void
- emit(Output_data_reloc<sh_type, true, size, big_endian>*);
- // Emit a COPY reloc.
- void
- emit_copy_reloc(Symbol_table*, Sized_symbol<size>*,
- Output_data*, off_t,
- Output_data_reloc<sh_type, true, size, big_endian>*);
- protected:
- typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
- typedef typename elfcpp::Elf_types<size>::Elf_Addr Addend;
- // This POD class holds the relocations we are saving. We will emit
- // these relocations if it turns out that the symbol does not
- // require a COPY relocation.
- struct Copy_reloc_entry
- {
- Copy_reloc_entry(Symbol* sym, unsigned int reloc_type,
- Sized_relobj_file<size, big_endian>* relobj,
- unsigned int shndx,
- Output_section* output_section,
- Address address, Addend addend)
- : sym_(sym), reloc_type_(reloc_type), relobj_(relobj),
- shndx_(shndx), output_section_(output_section),
- address_(address), addend_(addend)
- { }
- Symbol* sym_;
- unsigned int reloc_type_;
- Sized_relobj_file<size, big_endian>* relobj_;
- unsigned int shndx_;
- Output_section* output_section_;
- Address address_;
- Addend addend_;
- };
- // Make a new COPY reloc and emit it.
- void
- make_copy_reloc(Symbol_table*, Layout*, Sized_symbol<size>*,
- Output_data_reloc<sh_type, true, size, big_endian>*);
- // A list of relocs to be saved.
- typedef std::vector<Copy_reloc_entry> Copy_reloc_entries;
- // The list of relocs we are saving.
- Copy_reloc_entries entries_;
- private:
- // Return whether we need a COPY reloc.
- bool
- need_copy_reloc(Sized_symbol<size>* gsym,
- Sized_relobj_file<size, big_endian>* object,
- unsigned int shndx) const;
- // Save a reloc against SYM for possible emission later.
- void
- save(Symbol*, Sized_relobj_file<size, big_endian>*, unsigned int shndx,
- Output_section*, const Reloc& rel);
- // The target specific relocation type of the COPY relocation.
- const unsigned int copy_reloc_type_;
- // The dynamic BSS data which goes into the .bss section. This is
- // where variables which require COPY relocations are placed.
- Output_data_space* dynbss_;
- };
- } // End namespace gold.
- #endif // !defined(GOLD_COPY_RELOCS_H)
|