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 #include "crazy_linker_shared_library.h" | 5 #include "crazy_linker_shared_library.h" |
6 | 6 |
7 #include <dlfcn.h> | 7 #include <dlfcn.h> |
8 #include <stdlib.h> | 8 #include <stdlib.h> |
9 #include <sys/mman.h> | 9 #include <sys/mman.h> |
10 #include <elf.h> | 10 #include <elf.h> |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 // An instance of ElfRelocator::SymbolResolver that can be used | 94 // An instance of ElfRelocator::SymbolResolver that can be used |
95 // to resolve symbols in a shared library being loaded by | 95 // to resolve symbols in a shared library being loaded by |
96 // LibraryList::LoadLibrary. | 96 // LibraryList::LoadLibrary. |
97 class SharedLibraryResolver : public ElfRelocations::SymbolResolver { | 97 class SharedLibraryResolver : public ElfRelocations::SymbolResolver { |
98 public: | 98 public: |
99 SharedLibraryResolver(SharedLibrary* lib, | 99 SharedLibraryResolver(SharedLibrary* lib, |
100 LibraryList* lib_list, | 100 LibraryList* lib_list, |
101 Vector<LibraryView*>* preloads, | 101 Vector<LibraryView*>* preloads, |
102 Vector<LibraryView*>* dependencies) | 102 Vector<LibraryView*>* dependencies) |
103 : main_program_handle_(::dlopen(NULL, RTLD_NOW)), | 103 : main_program_handle_(::dlopen(NULL, RTLD_NOW)), |
104 sdk_build_version_(*Globals::GetSDKBuildVersion()), | |
105 lib_(lib), preloads_(preloads), dependencies_(dependencies) {} | 104 lib_(lib), preloads_(preloads), dependencies_(dependencies) {} |
106 | 105 |
107 virtual void* Lookup(const char* symbol_name) { | 106 virtual void* Lookup(const char* symbol_name) { |
108 // First, look inside the current library. | 107 // First, look inside the current library. |
109 const ELF::Sym* entry = lib_->LookupSymbolEntry(symbol_name); | 108 const ELF::Sym* entry = lib_->LookupSymbolEntry(symbol_name); |
110 if (entry) | 109 if (entry) |
111 return reinterpret_cast<void*>(lib_->load_bias() + entry->st_value); | 110 return reinterpret_cast<void*>(lib_->load_bias() + entry->st_value); |
112 | 111 |
113 // Special case: redirect the dynamic linker symbols to our wrappers. | 112 // Special case: redirect the dynamic linker symbols to our wrappers. |
114 // This ensures that loaded libraries can call dlopen() / dlsym() | 113 // This ensures that loaded libraries can call dlopen() / dlsym() |
115 // and transparently use the crazy linker to perform their duty. | 114 // and transparently use the crazy linker to perform their duty. |
116 void* address = WrapLinkerSymbol(symbol_name); | 115 void* address = WrapLinkerSymbol(symbol_name); |
117 if (address) | 116 if (address) |
118 return address; | 117 return address; |
119 | 118 |
120 // Make sure that we do nothing here for non-Lollipop platforms. | 119 // Then look inside the preloads. |
121 // In practice, preloads_ will be empty (because we ignore LD_PRELOAD | |
122 // when not Lollipop) and searching in the main executable should be | |
123 // benign. But crbug/479220 is weird enough that we want to take all | |
124 // possible precautions. | |
125 // | 120 // |
126 // For more, see: | 121 // Note that searching preloads *before* the main executable is opposite |
127 // https://code.google.com/p/chromium/issues/detail?id=479220 | 122 // to the search ordering used by the system linker, but it is required |
128 if (sdk_build_version_ == SDK_VERSION_CODE_LOLLIPOP) { | 123 // to work round a dlsym() bug in some Android releases (on releases |
129 // Then look inside the preloads. | 124 // without this dlsym() bug preloads_ will be empty, making this preloads |
130 // | 125 // search a no-op). |
131 // Note that searching preloads *before* the main executable is opposite | |
132 // to the search ordering used by the system linker, but it is required | |
133 // to work round a dlsym() bug in some Android releases (on releases | |
134 // without this dlsym() bug preloads_ will be empty, making this preloads | |
135 // search a no-op). | |
136 // | |
137 // For more, see commentary in LibraryList(), and | |
138 // https://code.google.com/p/android/issues/detail?id=74255 | |
139 for (size_t n = 0; n < preloads_->GetCount(); ++n) { | |
140 LibraryView* wrap = (*preloads_)[n]; | |
141 // LOG("%s: Looking into preload %p (%s)\n", __FUNCTION__, wrap, | |
142 // wrap->GetName()); | |
143 address = LookupInWrap(symbol_name, wrap); | |
144 if (address) | |
145 return address; | |
146 } | |
147 } | |
148 | |
149 // Do not lookup inside the main executable for pre-Lollipop, for | |
150 // crbug/479220. We do however want to do it for Lollipop and | |
151 // later, because in Lollipop-mr1 the dlsym() bug is fixed, so that | |
152 // we don't explicitly handle LD_PRELOADS but instead rely on dlsym | |
153 // correctly searching preloads via the main executable. | |
154 // | 126 // |
155 // For more, see: | 127 // For more, see commentary in LibraryList(), and |
156 // https://code.google.com/p/chromium/issues/detail?id=479220 | 128 // https://code.google.com/p/android/issues/detail?id=74255 |
157 if (sdk_build_version_ >= SDK_VERSION_CODE_LOLLIPOP) { | 129 for (size_t n = 0; n < preloads_->GetCount(); ++n) { |
158 // Then look inside the main executable. | 130 LibraryView* wrap = (*preloads_)[n]; |
159 address = ::dlsym(main_program_handle_, symbol_name); | 131 // LOG("%s: Looking into preload %p (%s)\n", __FUNCTION__, wrap, |
| 132 // wrap->GetName()); |
| 133 address = LookupInWrap(symbol_name, wrap); |
160 if (address) | 134 if (address) |
161 return address; | 135 return address; |
162 } | 136 } |
163 | 137 |
| 138 // Then lookup inside the main executable. |
| 139 address = ::dlsym(main_program_handle_, symbol_name); |
| 140 if (address) |
| 141 return address; |
| 142 |
164 // Then look inside the dependencies. | 143 // Then look inside the dependencies. |
165 for (size_t n = 0; n < dependencies_->GetCount(); ++n) { | 144 for (size_t n = 0; n < dependencies_->GetCount(); ++n) { |
166 LibraryView* wrap = (*dependencies_)[n]; | 145 LibraryView* wrap = (*dependencies_)[n]; |
167 // LOG("%s: Looking into dependency %p (%s)\n", __FUNCTION__, wrap, | 146 // LOG("%s: Looking into dependency %p (%s)\n", __FUNCTION__, wrap, |
168 // wrap->GetName()); | 147 // wrap->GetName()); |
169 address = LookupInWrap(symbol_name, wrap); | 148 address = LookupInWrap(symbol_name, wrap); |
170 if (address) | 149 if (address) |
171 return address; | 150 return address; |
172 } | 151 } |
173 | 152 |
(...skipping 28 matching lines...) Expand all Loading... |
202 if (wrap->IsCrazy()) { | 181 if (wrap->IsCrazy()) { |
203 SharedLibrary* crazy = wrap->GetCrazy(); | 182 SharedLibrary* crazy = wrap->GetCrazy(); |
204 const ELF::Sym* entry = crazy->LookupSymbolEntry(symbol_name); | 183 const ELF::Sym* entry = crazy->LookupSymbolEntry(symbol_name); |
205 if (entry) | 184 if (entry) |
206 return reinterpret_cast<void*>(crazy->load_bias() + entry->st_value); | 185 return reinterpret_cast<void*>(crazy->load_bias() + entry->st_value); |
207 } | 186 } |
208 | 187 |
209 return NULL; | 188 return NULL; |
210 } | 189 } |
211 | 190 |
212 const int sdk_build_version_; | |
213 void* main_program_handle_; | 191 void* main_program_handle_; |
214 SharedLibrary* lib_; | 192 SharedLibrary* lib_; |
215 Vector<LibraryView*>* preloads_; | 193 Vector<LibraryView*>* preloads_; |
216 Vector<LibraryView*>* dependencies_; | 194 Vector<LibraryView*>* dependencies_; |
217 }; | 195 }; |
218 | 196 |
219 #if defined(__arm__) || defined(__aarch64__) | 197 #if defined(__arm__) || defined(__aarch64__) |
220 | 198 |
221 // Helper class to provide a simple scoped buffer. ScopedPtr is not | 199 // Helper class to provide a simple scoped buffer. ScopedPtr is not |
222 // usable here because it calls delete, not delete []. | 200 // usable here because it calls delete, not delete []. |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 if (iter_.GetTag() == DT_NEEDED) { | 585 if (iter_.GetTag() == DT_NEEDED) { |
608 dep_name_ = symbols_->GetStringById(iter_.GetValue()); | 586 dep_name_ = symbols_->GetStringById(iter_.GetValue()); |
609 iter_.GetNext(); | 587 iter_.GetNext(); |
610 return true; | 588 return true; |
611 } | 589 } |
612 } | 590 } |
613 return false; | 591 return false; |
614 } | 592 } |
615 | 593 |
616 } // namespace crazy | 594 } // namespace crazy |
OLD | NEW |