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 |