OLD | NEW |
1 // Copyright 2016 The Native Client Authors. All rights reserved. | 1 // Copyright 2016 The Native Client 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 "native_client/src/untrusted/pll_loader/pll_loader.h" | 5 #include "native_client/src/untrusted/pll_loader/pll_loader.h" |
6 | 6 |
7 #include <pthread.h> | 7 #include <pthread.h> |
8 #include <stdlib.h> | 8 #include <stdlib.h> |
9 #include <string.h> | 9 #include <string.h> |
10 #include <sys/stat.h> | 10 #include <sys/stat.h> |
11 | 11 |
12 #include <algorithm> | 12 #include <algorithm> |
| 13 #include <string> |
13 #include <vector> | 14 #include <vector> |
14 | 15 |
15 #include "native_client/src/shared/platform/nacl_check.h" | 16 #include "native_client/src/shared/platform/nacl_check.h" |
16 #include "native_client/src/shared/platform/nacl_log.h" | 17 #include "native_client/src/shared/platform/nacl_log.h" |
17 #include "native_client/src/untrusted/pnacl_dynloader/dynloader.h" | 18 #include "native_client/src/untrusted/pnacl_dynloader/dynloader.h" |
18 | 19 |
19 namespace { | 20 namespace { |
20 | 21 |
21 // Array of modules, used for instantiating their TLS blocks. This is used | 22 // Array of modules, used for instantiating their TLS blocks. This is used |
22 // concurrently and is protected by g_modules_mutex. | 23 // concurrently and is protected by g_modules_mutex. |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 | 150 |
150 tls_block_getter->func = TLSBlockGetter; | 151 tls_block_getter->func = TLSBlockGetter; |
151 tls_block_getter->arg = (void *) module_index; | 152 tls_block_getter->arg = (void *) module_index; |
152 } | 153 } |
153 } | 154 } |
154 | 155 |
155 void ModuleSet::SetSonameSearchPath(const std::vector<std::string> &dir_list) { | 156 void ModuleSet::SetSonameSearchPath(const std::vector<std::string> &dir_list) { |
156 search_path_ = dir_list; | 157 search_path_ = dir_list; |
157 } | 158 } |
158 | 159 |
159 void ModuleSet::AddBySoname(const char *soname) { | 160 PLLRoot *ModuleSet::AddBySoname(const char *soname) { |
160 // TODO(smklein): Deduplicate rather than failing once dependencies are added. | |
161 if (sonames_.count(soname) != 0) { | 161 if (sonames_.count(soname) != 0) { |
162 NaClLog(LOG_FATAL, "PLL Loader found duplicate soname: %s\n", soname); | 162 // This module has already been added to the ModuleSet. |
| 163 return NULL; |
163 } | 164 } |
164 sonames_.insert(soname); | 165 sonames_.insert(soname); |
165 | 166 |
166 // Actually load the module implied by the soname. | 167 // Actually load the module implied by the soname. |
167 for (auto path : search_path_) { | 168 for (auto path : search_path_) { |
168 // Appending "/" might be unnecessary, but "foo/bar" and "foo//bar" should | 169 // Appending "/" might be unnecessary, but "foo/bar" and "foo//bar" should |
169 // point to the same file. | 170 // point to the same file. |
170 path.append("/"); | 171 path.append("/"); |
171 path.append(soname); | 172 path.append(soname); |
| 173 path.append(".translated"); |
172 struct stat buf; | 174 struct stat buf; |
173 if (stat(path.c_str(), &buf) == 0) { | 175 if (stat(path.c_str(), &buf) == 0) { |
174 AddByFilename(path.c_str()); | 176 return AddByFilename(path.c_str()); |
175 return; | |
176 } | 177 } |
177 } | 178 } |
178 | 179 |
179 NaClLog(LOG_FATAL, "PLL Loader cannot find shared object file: %s\n", soname); | 180 NaClLog(LOG_FATAL, "PLL Loader cannot find shared object: %s\n", soname); |
| 181 return NULL; |
180 } | 182 } |
181 | 183 |
182 void ModuleSet::AddByFilename(const char *filename) { | 184 PLLRoot *ModuleSet::AddByFilename(const char *filename) { |
183 void *pso_root; | 185 void *pso_root; |
184 int err = pnacl_load_elf_file(filename, &pso_root); | 186 int err = pnacl_load_elf_file(filename, &pso_root); |
185 if (err != 0) { | 187 if (err != 0) { |
186 NaClLog(LOG_FATAL, "pnacl_load_elf_file() failed: errno=%d\n", err); | 188 NaClLog(LOG_FATAL, |
| 189 "pll_loader could not open %s: errno=%d\n", filename, err); |
187 } | 190 } |
188 modules_.push_back(PLLModule((const PLLRoot *) pso_root)); | 191 PLLModule module((const PLLRoot *) pso_root); |
| 192 modules_.push_back(module); |
| 193 const char *dependencies_list = module.root()->dependencies_list; |
| 194 size_t dependencies_count = module.root()->dependencies_count; |
| 195 size_t string_offset = 0; |
| 196 for (size_t i = 0; i < dependencies_count; i++) { |
| 197 std::string dependency_filename(dependencies_list + string_offset); |
| 198 string_offset += dependency_filename.length() + 1; |
| 199 AddBySoname(dependency_filename.c_str()); |
| 200 } |
| 201 return (PLLRoot *) pso_root; |
189 } | 202 } |
190 | 203 |
191 void *ModuleSet::GetSym(const char *name) { | 204 void *ModuleSet::GetSym(const char *name) { |
192 for (auto &module : modules_) { | 205 for (auto &module : modules_) { |
193 if (void *sym = module.GetExportedSym(name)) | 206 if (void *sym = module.GetExportedSym(name)) |
194 return sym; | 207 return sym; |
195 } | 208 } |
196 return NULL; | 209 return NULL; |
197 } | 210 } |
198 | 211 |
199 void ModuleSet::ResolveRefs() { | 212 void ModuleSet::ResolveRefs() { |
200 for (auto &module : modules_) { | 213 for (auto &module : modules_) { |
201 for (size_t index = 0, count = module.root()->import_count; | 214 for (size_t index = 0, count = module.root()->import_count; |
202 index < count; ++index) { | 215 index < count; ++index) { |
203 const char *sym_name = module.GetImportedSymbolName(index); | 216 const char *sym_name = module.GetImportedSymbolName(index); |
204 uintptr_t sym_value = (uintptr_t) GetSym(sym_name); | 217 uintptr_t sym_value = (uintptr_t) GetSym(sym_name); |
205 if (sym_value == 0) { | 218 if (sym_value == 0) { |
206 NaClLog(LOG_FATAL, "Undefined symbol: \"%s\"\n", sym_name); | 219 NaClLog(LOG_FATAL, "Undefined symbol: \"%s\"\n", sym_name); |
207 } | 220 } |
208 *(uintptr_t *) module.root()->imported_ptrs[index] += sym_value; | 221 *(uintptr_t *) module.root()->imported_ptrs[index] += sym_value; |
209 } | 222 } |
210 | 223 |
211 module.InitializeTLS(); | 224 module.InitializeTLS(); |
212 } | 225 } |
213 } | 226 } |
OLD | NEW |