Chromium Code Reviews| 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 <stdlib.h> | 7 #include <stdlib.h> |
| 8 #include <string.h> | 8 #include <string.h> |
| 9 #include <sys/stat.h> | 9 #include <sys/stat.h> |
| 10 | 10 |
| 11 #include <algorithm> | 11 #include <algorithm> |
| 12 #include <string> | |
| 12 | 13 |
| 13 #include "native_client/src/shared/platform/nacl_log.h" | 14 #include "native_client/src/shared/platform/nacl_log.h" |
| 14 #include "native_client/src/untrusted/pnacl_dynloader/dynloader.h" | 15 #include "native_client/src/untrusted/pnacl_dynloader/dynloader.h" |
| 15 | 16 |
| 16 namespace { | 17 namespace { |
| 17 | 18 |
| 18 // This is a simple implementation that does not support multiple threads. | 19 // This is a simple implementation that does not support multiple threads. |
| 19 // It demonstrates how we can optimize if we know that pthread_create() | 20 // It demonstrates how we can optimize if we know that pthread_create() |
| 20 // will never be called. | 21 // will never be called. |
| 21 void *TLSBlockGetter(PLLTLSBlockGetter *closure) { | 22 void *TLSBlockGetter(PLLTLSBlockGetter *closure) { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 83 root_->tls_template_data_size); | 84 root_->tls_template_data_size); |
| 84 memset((char *) base + root_->tls_template_data_size, 0, bss_size); | 85 memset((char *) base + root_->tls_template_data_size, 0, bss_size); |
| 85 return base; | 86 return base; |
| 86 } | 87 } |
| 87 | 88 |
| 88 void ModuleSet::SetSonameSearchPath(const std::vector<std::string> &dir_list) { | 89 void ModuleSet::SetSonameSearchPath(const std::vector<std::string> &dir_list) { |
| 89 search_path_ = dir_list; | 90 search_path_ = dir_list; |
| 90 } | 91 } |
| 91 | 92 |
| 92 void ModuleSet::AddBySoname(const char *soname) { | 93 void ModuleSet::AddBySoname(const char *soname) { |
| 93 // TODO(smklein): Deduplicate rather than failing once dependencies are added. | 94 // TODO(smklein): Deduplicate rather than failing once dependencies are added. |
|
Mark Seaborn
2016/03/30 23:24:57
You can remove this since you've addressed it.
Sean Klein
2016/04/01 23:12:24
Done.
| |
| 94 if (sonames_.count(soname) != 0) { | 95 if (sonames_.count(soname) != 0) { |
| 95 NaClLog(LOG_FATAL, "PLL Loader found duplicate soname: %s\n", soname); | 96 // This module has already been added to the ModuleSet. |
| 97 return; | |
| 96 } | 98 } |
| 97 sonames_.insert(soname); | 99 sonames_.insert(soname); |
| 98 | 100 |
| 99 // Actually load the module implied by the soname. | 101 // Actually load the module implied by the soname. |
| 100 for (auto path : search_path_) { | 102 for (auto path : search_path_) { |
| 101 // Appending "/" might be unnecessary, but "foo/bar" and "foo//bar" should | 103 // Appending "/" might be unnecessary, but "foo/bar" and "foo//bar" should |
| 102 // point to the same file. | 104 // point to the same file. |
| 103 path.append("/"); | 105 path.append("/"); |
| 104 path.append(soname); | 106 path.append(soname); |
| 107 path.append(".translated"); | |
| 105 struct stat buf; | 108 struct stat buf; |
| 106 if (stat(path.c_str(), &buf) == 0) { | 109 if (stat(path.c_str(), &buf) == 0) { |
| 107 AddByFilename(path.c_str()); | 110 AddByFilename(path.c_str()); |
| 108 return; | 111 return; |
| 109 } | 112 } |
| 110 } | 113 } |
| 111 | 114 |
| 112 NaClLog(LOG_FATAL, "PLL Loader cannot find shared object file: %s\n", soname); | 115 NaClLog(LOG_FATAL, "PLL Loader cannot find shared object file: %s\n", soname); |
| 113 } | 116 } |
| 114 | 117 |
| 115 void ModuleSet::AddByFilename(const char *filename) { | 118 void ModuleSet::AddByFilename(const char *filename) { |
| 116 void *pso_root; | 119 void *pso_root; |
| 117 int err = pnacl_load_elf_file(filename, &pso_root); | 120 int err = pnacl_load_elf_file(filename, &pso_root); |
| 118 if (err != 0) { | 121 if (err != 0) { |
| 119 NaClLog(LOG_FATAL, "pnacl_load_elf_file() failed: errno=%d\n", err); | 122 NaClLog(LOG_FATAL, |
| 123 "pll_loader could not open %s: errno=%d\n", filename, err); | |
| 120 } | 124 } |
| 121 modules_.push_back(PLLModule((const PLLRoot *) pso_root)); | 125 const PLLModule module = PLLModule((const PLLRoot *) pso_root); |
|
Mark Seaborn
2016/03/30 23:24:57
Just:
PLLModule module((const PLLRoot *) pso_root)
Sean Klein
2016/04/01 23:12:24
Done, but with const as well.
| |
| 126 modules_.push_back(module); | |
| 127 const char *dependencies_list = module.GetDependenciesList(); | |
| 128 size_t dependencies_count = module.GetDependenciesCount(); | |
| 129 size_t string_index = 0; | |
|
Mark Seaborn
2016/03/30 23:24:57
Maybe "offset" rather than "index"?
Sean Klein
2016/04/01 23:12:24
Done.
| |
| 130 for (size_t i = 0; i < dependencies_count; i++) { | |
| 131 std::string dependency_filename(dependencies_list + string_index); | |
| 132 string_index += dependency_filename.length() + 1; | |
| 133 dependency_filename.append(".translated"); | |
| 134 AddByFilename(dependency_filename.c_str()); | |
| 135 } | |
| 122 } | 136 } |
| 123 | 137 |
| 124 void *ModuleSet::GetSym(const char *name) { | 138 void *ModuleSet::GetSym(const char *name) { |
| 125 for (auto &module : modules_) { | 139 for (auto &module : modules_) { |
| 126 if (void *sym = module.GetExportedSym(name)) | 140 if (void *sym = module.GetExportedSym(name)) |
| 127 return sym; | 141 return sym; |
| 128 } | 142 } |
| 129 return NULL; | 143 return NULL; |
| 130 } | 144 } |
| 131 | 145 |
| 132 void ModuleSet::ResolveRefs() { | 146 void ModuleSet::ResolveRefs() { |
| 133 for (auto &module : modules_) { | 147 for (auto &module : modules_) { |
| 134 for (size_t index = 0, count = module.root()->import_count; | 148 for (size_t index = 0, count = module.root()->import_count; |
| 135 index < count; ++index) { | 149 index < count; ++index) { |
| 136 const char *sym_name = module.GetImportedSymbolName(index); | 150 const char *sym_name = module.GetImportedSymbolName(index); |
| 137 uintptr_t sym_value = (uintptr_t) GetSym(sym_name); | 151 uintptr_t sym_value = (uintptr_t) GetSym(sym_name); |
| 138 if (sym_value == 0) { | 152 if (sym_value == 0) { |
| 139 NaClLog(LOG_FATAL, "Undefined symbol: \"%s\"\n", sym_name); | 153 NaClLog(LOG_FATAL, "Undefined symbol: \"%s\"\n", sym_name); |
| 140 } | 154 } |
| 141 *(uintptr_t *) module.root()->imported_ptrs[index] += sym_value; | 155 *(uintptr_t *) module.root()->imported_ptrs[index] += sym_value; |
| 142 } | 156 } |
| 143 | 157 |
| 144 // Initialize TLS. | 158 // Initialize TLS. |
| 145 if (PLLTLSBlockGetter *tls_block_getter = module.root()->tls_block_getter) { | 159 if (PLLTLSBlockGetter *tls_block_getter = module.root()->tls_block_getter) { |
| 146 tls_block_getter->func = TLSBlockGetter; | 160 tls_block_getter->func = TLSBlockGetter; |
| 147 tls_block_getter->arg = module.InstantiateTLSBlock(); | 161 tls_block_getter->arg = module.InstantiateTLSBlock(); |
| 148 } | 162 } |
| 149 } | 163 } |
| 150 } | 164 } |
| OLD | NEW |