| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef CRAZY_LINKER_ELF_RELOCATIONS_H | 5 #ifndef CRAZY_LINKER_ELF_RELOCATIONS_H |
| 6 #define CRAZY_LINKER_ELF_RELOCATIONS_H | 6 #define CRAZY_LINKER_ELF_RELOCATIONS_H |
| 7 | 7 |
| 8 #include <string.h> | 8 #include <string.h> |
| 9 #include <unistd.h> | 9 #include <unistd.h> |
| 10 | 10 |
| 11 #include "crazy_linker_leb128.h" |
| 11 #include "elf_traits.h" | 12 #include "elf_traits.h" |
| 12 | 13 |
| 13 namespace crazy { | 14 namespace crazy { |
| 14 | 15 |
| 15 class ElfSymbols; | 16 class ElfSymbols; |
| 16 class ElfView; | 17 class ElfView; |
| 17 class Error; | 18 class Error; |
| 18 | 19 |
| 19 // An ElfRelocations instance holds information about relocations in a mapped | 20 // An ElfRelocations instance holds information about relocations in a mapped |
| 20 // ELF binary. | 21 // ELF binary. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 37 | 38 |
| 38 // Apply all relocations to the target mapped ELF binary. Must be called | 39 // Apply all relocations to the target mapped ELF binary. Must be called |
| 39 // after Init(). | 40 // after Init(). |
| 40 // |symbols| maps to the symbol entries for the target library only. | 41 // |symbols| maps to the symbol entries for the target library only. |
| 41 // |resolver| can resolve symbols out of the current library. | 42 // |resolver| can resolve symbols out of the current library. |
| 42 // On error, return false and set |error| message. | 43 // On error, return false and set |error| message. |
| 43 bool ApplyAll(const ElfSymbols* symbols, | 44 bool ApplyAll(const ElfSymbols* symbols, |
| 44 SymbolResolver* resolver, | 45 SymbolResolver* resolver, |
| 45 Error* error); | 46 Error* error); |
| 46 | 47 |
| 47 #if defined(__arm__) || defined(__aarch64__) | |
| 48 // Register packed relocations to apply. | |
| 49 // |packed_relocs| is a pointer to packed relocations data. | |
| 50 void RegisterPackedRelocations(uint8_t* packed_relocations); | |
| 51 #endif | |
| 52 | |
| 53 // This function is used to adjust relocated addresses in a copy of an | 48 // This function is used to adjust relocated addresses in a copy of an |
| 54 // existing section of an ELF binary. I.e. |src_addr|...|src_addr + size| | 49 // existing section of an ELF binary. I.e. |src_addr|...|src_addr + size| |
| 55 // must be inside the mapped ELF binary, this function will first copy its | 50 // must be inside the mapped ELF binary, this function will first copy its |
| 56 // content into |dst_addr|...|dst_addr + size|, then adjust all relocated | 51 // content into |dst_addr|...|dst_addr + size|, then adjust all relocated |
| 57 // addresses inside the destination section as if it was loaded/mapped | 52 // addresses inside the destination section as if it was loaded/mapped |
| 58 // at |map_addr|...|map_addr + size|. Only relative relocations are processed, | 53 // at |map_addr|...|map_addr + size|. Only relative relocations are processed, |
| 59 // symbolic ones are ignored. | 54 // symbolic ones are ignored. |
| 60 void CopyAndRelocate(size_t src_addr, | 55 void CopyAndRelocate(size_t src_addr, |
| 61 size_t dst_addr, | 56 size_t dst_addr, |
| 62 size_t map_addr, | 57 size_t map_addr, |
| 63 size_t size); | 58 size_t size); |
| 64 | 59 |
| 65 private: | 60 private: |
| 66 bool ResolveSymbol(unsigned rel_type, | 61 bool ResolveSymbol(unsigned rel_type, |
| 67 unsigned rel_symbol, | 62 unsigned rel_symbol, |
| 68 const ElfSymbols* symbols, | 63 const ElfSymbols* symbols, |
| 69 SymbolResolver* resolver, | 64 SymbolResolver* resolver, |
| 70 ELF::Addr reloc, | 65 ELF::Addr reloc, |
| 71 ELF::Addr* sym_addr, | 66 ELF::Addr* sym_addr, |
| 72 Error* error); | 67 Error* error); |
| 68 bool ApplyResolvedRelaReloc(const ELF::Rela* rela, |
| 69 ELF::Addr sym_addr, |
| 70 bool resolved, |
| 71 Error* error); |
| 72 bool ApplyResolvedRelReloc(const ELF::Rel* rel, |
| 73 ELF::Addr sym_addr, |
| 74 bool resolved, |
| 75 Error* error); |
| 73 bool ApplyRelaReloc(const ELF::Rela* rela, | 76 bool ApplyRelaReloc(const ELF::Rela* rela, |
| 74 ELF::Addr sym_addr, | 77 const ElfSymbols* symbols, |
| 75 bool resolved, | 78 SymbolResolver* resolver, |
| 76 Error* error); | 79 Error* error); |
| 77 bool ApplyRelReloc(const ELF::Rel* rel, | 80 bool ApplyRelReloc(const ELF::Rel* rel, |
| 78 ELF::Addr sym_addr, | 81 const ElfSymbols* symbols, |
| 79 bool resolved, | 82 SymbolResolver* resolver, |
| 80 Error* error); | 83 Error* error); |
| 81 bool ApplyRelaRelocs(const ELF::Rela* relocs, | 84 bool ApplyRelaRelocs(const ELF::Rela* relocs, |
| 82 size_t relocs_count, | 85 size_t relocs_count, |
| 83 const ElfSymbols* symbols, | 86 const ElfSymbols* symbols, |
| 84 SymbolResolver* resolver, | 87 SymbolResolver* resolver, |
| 85 Error* error); | 88 Error* error); |
| 86 bool ApplyRelRelocs(const ELF::Rel* relocs, | 89 bool ApplyRelRelocs(const ELF::Rel* relocs, |
| 87 size_t relocs_count, | 90 size_t relocs_count, |
| 88 const ElfSymbols* symbols, | 91 const ElfSymbols* symbols, |
| 89 SymbolResolver* resolver, | 92 SymbolResolver* resolver, |
| 90 Error* error); | 93 Error* error); |
| 91 void AdjustRelocation(ELF::Word rel_type, | 94 void AdjustRelocation(ELF::Word rel_type, |
| 92 ELF::Addr src_reloc, | 95 ELF::Addr src_reloc, |
| 93 size_t dst_delta, | 96 size_t dst_delta, |
| 94 size_t map_delta); | 97 size_t map_delta); |
| 95 void RelocateRela(size_t src_addr, | 98 void RelocateRela(size_t src_addr, |
| 96 size_t dst_addr, | 99 size_t dst_addr, |
| 97 size_t map_addr, | 100 size_t map_addr, |
| 98 size_t size); | 101 size_t size); |
| 99 void RelocateRel(size_t src_addr, | 102 void RelocateRel(size_t src_addr, |
| 100 size_t dst_addr, | 103 size_t dst_addr, |
| 101 size_t map_addr, | 104 size_t map_addr, |
| 102 size_t size); | 105 size_t size); |
| 106 void RelocateAndroidReloc(const ELF::Rela* relocation, |
| 107 size_t src_addr, |
| 108 size_t dst_addr, |
| 109 size_t map_addr, |
| 110 size_t size); |
| 103 | 111 |
| 104 #if defined(__arm__) || defined(__aarch64__) | 112 // Android packed relocations unpacker. Calls the given handler for |
| 105 // Apply packed rel or rela relocations. On error, return false. | 113 // each relocation in the unpacking stream. |
| 106 bool ApplyPackedRel(const uint8_t* packed_relocations, Error* error); | 114 typedef bool (*RelocationHandler)(ElfRelocations* relocations, |
| 107 bool ApplyPackedRela(const uint8_t* packed_relocations, Error* error); | 115 const ELF::Rela* relocation, |
| 116 void* opaque); |
| 117 bool ForEachAndroidRelocation(RelocationHandler handler, |
| 118 void* opaque); |
| 108 | 119 |
| 109 // Apply packed relocations. | 120 // Apply Android packed relocations. |
| 110 // On error, return false and set |error| message. No-op if no packed | 121 // On error, return false and set |error| message. |
| 111 // relocations were registered. | 122 // The static function is the ForEachAndroidRelocation() handler. |
| 112 bool ApplyPackedRelocations(Error* error); | 123 bool ApplyAndroidRelocations(const ElfSymbols* symbols, |
| 113 #endif | 124 SymbolResolver* resolver, |
| 125 Error* error); |
| 126 static bool ApplyAndroidRelocation(ElfRelocations* relocations, |
| 127 const ELF::Rela* relocation, |
| 128 void* opaque); |
| 129 |
| 130 // Relocate Android packed relocations. |
| 131 // The static function is the ForEachAndroidRelocation() handler. |
| 132 void RelocateAndroidRelocations(size_t src_addr, |
| 133 size_t dst_addr, |
| 134 size_t map_addr, |
| 135 size_t size); |
| 136 static bool RelocateAndroidRelocation(ElfRelocations* relocations, |
| 137 const ELF::Rela* relocation, |
| 138 void* opaque); |
| 114 | 139 |
| 115 #if defined(__mips__) | 140 #if defined(__mips__) |
| 116 bool RelocateMipsGot(const ElfSymbols* symbols, | 141 bool RelocateMipsGot(const ElfSymbols* symbols, |
| 117 SymbolResolver* resolver, | 142 SymbolResolver* resolver, |
| 118 Error* error); | 143 Error* error); |
| 119 #endif | 144 #endif |
| 120 | 145 |
| 121 const ELF::Phdr* phdr_; | 146 const ELF::Phdr* phdr_; |
| 122 size_t phdr_count_; | 147 size_t phdr_count_; |
| 123 size_t load_bias_; | 148 size_t load_bias_; |
| 124 | 149 |
| 125 ELF::Addr relocations_type_; | 150 ELF::Addr relocations_type_; |
| 126 ELF::Addr plt_relocations_; | 151 ELF::Addr plt_relocations_; |
| 127 size_t plt_relocations_size_; | 152 size_t plt_relocations_size_; |
| 128 ELF::Addr* plt_got_; | 153 ELF::Addr* plt_got_; |
| 129 | 154 |
| 130 ELF::Addr relocations_; | 155 ELF::Addr relocations_; |
| 131 size_t relocations_size_; | 156 size_t relocations_size_; |
| 132 | 157 |
| 133 #if defined(__mips__) | 158 #if defined(__mips__) |
| 134 // MIPS-specific relocation fields. | 159 // MIPS-specific relocation fields. |
| 135 ELF::Word mips_symtab_count_; | 160 ELF::Word mips_symtab_count_; |
| 136 ELF::Word mips_local_got_count_; | 161 ELF::Word mips_local_got_count_; |
| 137 ELF::Word mips_gotsym_; | 162 ELF::Word mips_gotsym_; |
| 138 #endif | 163 #endif |
| 139 | 164 |
| 140 #if defined(__arm__) || defined(__aarch64__) | 165 uint8_t* android_relocations_; |
| 141 uint8_t* packed_relocations_; | 166 size_t android_relocations_size_; |
| 142 #endif | |
| 143 | 167 |
| 144 bool has_text_relocations_; | 168 bool has_text_relocations_; |
| 145 bool has_symbolic_; | 169 bool has_symbolic_; |
| 146 }; | 170 }; |
| 147 | 171 |
| 148 } // namespace crazy | 172 } // namespace crazy |
| 149 | 173 |
| 150 #endif // CRAZY_LINKER_ELF_RELOCATIONS_H | 174 #endif // CRAZY_LINKER_ELF_RELOCATIONS_H |
| OLD | NEW |