copy-relocs.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. // copy-relocs.h -- handle COPY relocations for gold -*- C++ -*-
  2. // Copyright (C) 2006-2022 Free Software Foundation, Inc.
  3. // Written by Ian Lance Taylor <iant@google.com>.
  4. // This file is part of gold.
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 3 of the License, or
  8. // (at your option) any later version.
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // You should have received a copy of the GNU General Public License
  14. // along with this program; if not, write to the Free Software
  15. // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
  16. // MA 02110-1301, USA.
  17. #ifndef GOLD_COPY_RELOCS_H
  18. #define GOLD_COPY_RELOCS_H
  19. #include "elfcpp.h"
  20. #include "reloc-types.h"
  21. #include "output.h"
  22. namespace gold
  23. {
  24. // This class is used to manage COPY relocations. We try to avoid
  25. // them when possible. A COPY relocation may be required when an
  26. // executable refers to a variable defined in a shared library. COPY
  27. // relocations are problematic because they tie the executable to the
  28. // exact size of the variable in the shared library. We can avoid
  29. // them if all the references to the variable are in a writeable
  30. // section. In that case we can simply use dynamic relocations.
  31. // However, when scanning relocs, we don't know when we see the
  32. // relocation whether we will be forced to use a COPY relocation or
  33. // not. So we have to save the relocation during the reloc scanning,
  34. // and then emit it as a dynamic relocation if necessary. This class
  35. // implements that. It is used by the target specific code.
  36. // The template parameter SH_TYPE is the type of the reloc section to
  37. // be used for COPY relocs: elfcpp::SHT_REL or elfcpp::SHT_RELA.
  38. template<int sh_type, int size, bool big_endian>
  39. class Copy_relocs
  40. {
  41. private:
  42. typedef typename Reloc_types<sh_type, size, big_endian>::Reloc Reloc;
  43. public:
  44. Copy_relocs(unsigned int copy_reloc_type)
  45. : entries_(), copy_reloc_type_(copy_reloc_type), dynbss_(NULL),
  46. dynrelro_(NULL)
  47. { }
  48. // This is called while scanning relocs if we see a relocation
  49. // against a symbol which may force us to generate a COPY reloc.
  50. // SYM is the symbol. OBJECT is the object whose relocs we are
  51. // scanning. The relocation is being applied to section SHNDX in
  52. // OBJECT. OUTPUT_SECTION is the output section where section SHNDX
  53. // will wind up. REL is the reloc itself. The Output_data_reloc
  54. // section is where the dynamic relocs are put.
  55. void
  56. copy_reloc(Symbol_table*,
  57. Layout*,
  58. Sized_symbol<size>* sym,
  59. Sized_relobj_file<size, big_endian>* object,
  60. unsigned int shndx,
  61. Output_section* output_section,
  62. unsigned int r_type,
  63. typename elfcpp::Elf_types<size>::Elf_Addr r_offset,
  64. typename elfcpp::Elf_types<size>::Elf_Swxword r_addend,
  65. Output_data_reloc<sh_type, true, size, big_endian>*);
  66. // Return whether there are any saved relocations.
  67. bool
  68. any_saved_relocs() const
  69. { return !this->entries_.empty(); }
  70. // Emit any saved relocations which turn out to be needed. This is
  71. // called after all the relocs have been scanned.
  72. void
  73. emit(Output_data_reloc<sh_type, true, size, big_endian>*);
  74. // Emit a COPY reloc.
  75. void
  76. emit_copy_reloc(Symbol_table*, Sized_symbol<size>*,
  77. Output_data*, off_t,
  78. Output_data_reloc<sh_type, true, size, big_endian>*);
  79. protected:
  80. typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
  81. typedef typename elfcpp::Elf_types<size>::Elf_Addr Addend;
  82. // This POD class holds the relocations we are saving. We will emit
  83. // these relocations if it turns out that the symbol does not
  84. // require a COPY relocation.
  85. struct Copy_reloc_entry
  86. {
  87. Copy_reloc_entry(Symbol* sym, unsigned int reloc_type,
  88. Sized_relobj_file<size, big_endian>* relobj,
  89. unsigned int shndx,
  90. Output_section* output_section,
  91. Address address, Addend addend)
  92. : sym_(sym), reloc_type_(reloc_type), relobj_(relobj),
  93. shndx_(shndx), output_section_(output_section),
  94. address_(address), addend_(addend)
  95. { }
  96. Symbol* sym_;
  97. unsigned int reloc_type_;
  98. Sized_relobj_file<size, big_endian>* relobj_;
  99. unsigned int shndx_;
  100. Output_section* output_section_;
  101. Address address_;
  102. Addend addend_;
  103. };
  104. // Make a new COPY reloc and emit it.
  105. void
  106. make_copy_reloc(Symbol_table*, Layout*, Sized_symbol<size>*,
  107. Sized_relobj_file<size, big_endian>* object,
  108. Output_data_reloc<sh_type, true, size, big_endian>*);
  109. // A list of relocs to be saved.
  110. typedef std::vector<Copy_reloc_entry> Copy_reloc_entries;
  111. // The list of relocs we are saving.
  112. Copy_reloc_entries entries_;
  113. private:
  114. // Return whether we need a COPY reloc.
  115. bool
  116. need_copy_reloc(Sized_symbol<size>* gsym,
  117. Sized_relobj_file<size, big_endian>* object,
  118. unsigned int shndx) const;
  119. // Save a reloc against SYM for possible emission later.
  120. void
  121. save(Symbol*,
  122. Sized_relobj_file<size, big_endian>*,
  123. unsigned int shndx,
  124. Output_section*,
  125. unsigned int r_type,
  126. typename elfcpp::Elf_types<size>::Elf_Addr r_offset,
  127. typename elfcpp::Elf_types<size>::Elf_Swxword r_addend);
  128. // The target specific relocation type of the COPY relocation.
  129. const unsigned int copy_reloc_type_;
  130. // The dynamic BSS data which goes into the .bss section. This is
  131. // where writable variables which require COPY relocations are placed.
  132. Output_data_space* dynbss_;
  133. // The dynamic read-only data, which goes into the .data.rel.ro section.
  134. // This is where read-only variables which require COPY relocations are
  135. // placed.
  136. Output_data_space* dynrelro_;
  137. };
  138. } // End namespace gold.
  139. #endif // !defined(GOLD_COPY_RELOCS_H)