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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 82 size_t bss_size = (root_->tls_template_total_size - | 83 size_t bss_size = (root_->tls_template_total_size - |
| 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 if (sonames_.count(soname) != 0) { | 94 if (sonames_.count(soname) != 0) { |
| 95 NaClLog(LOG_FATAL, "PLL Loader found duplicate soname: %s\n", soname); | 95 // This module has already been added to the ModuleSet. |
| 96 return NULL; | |
| 96 } | 97 } |
| 97 sonames_.insert(soname); | 98 sonames_.insert(soname); |
| 98 | 99 |
| 99 // Actually load the module implied by the soname. | 100 // Actually load the module implied by the soname. |
| 100 for (auto path : search_path_) { | 101 for (auto path : search_path_) { |
| 101 // Appending "/" might be unnecessary, but "foo/bar" and "foo//bar" should | 102 // Appending "/" might be unnecessary, but "foo/bar" and "foo//bar" should |
| 102 // point to the same file. | 103 // point to the same file. |
| 103 path.append("/"); | 104 path.append("/"); |
| 104 path.append(soname); | 105 path.append(soname); |
| 106 path.append(".translated"); | |
| 105 struct stat buf; | 107 struct stat buf; |
| 106 if (stat(path.c_str(), &buf) == 0) { | 108 if (stat(path.c_str(), &buf) == 0) { |
| 107 AddByFilename(path.c_str()); | 109 return AddByFilename(path.c_str()); |
| 108 return; | |
| 109 } | 110 } |
| 110 } | 111 } |
| 111 | 112 |
| 112 NaClLog(LOG_FATAL, "PLL Loader cannot find shared object file: %s\n", soname); | 113 NaClLog(LOG_FATAL, "PLL Loader cannot find shared object: %s\n", soname); |
| 114 return NULL; | |
| 113 } | 115 } |
| 114 | 116 |
| 115 void ModuleSet::AddByFilename(const char *filename) { | 117 void *ModuleSet::AddByFilename(const char *filename) { |
| 116 void *pso_root; | 118 void *pso_root; |
| 117 int err = pnacl_load_elf_file(filename, &pso_root); | 119 int err = pnacl_load_elf_file(filename, &pso_root); |
| 118 if (err != 0) { | 120 if (err != 0) { |
| 119 NaClLog(LOG_FATAL, "pnacl_load_elf_file() failed: errno=%d\n", err); | 121 NaClLog(LOG_FATAL, |
| 122 "pll_loader could not open %s: errno=%d\n", filename, err); | |
| 120 } | 123 } |
| 121 modules_.push_back(PLLModule((const PLLRoot *) pso_root)); | 124 const PLLModule module((const PLLRoot *) pso_root); |
|
Mark Seaborn
2016/04/01 23:42:19
See other comment: you don't really need the first
Sean Klein
2016/04/02 00:50:33
Done.
| |
| 125 modules_.push_back(module); | |
| 126 const char *dependencies_list = module.root()->dependencies_list; | |
| 127 size_t dependencies_count = module.root()->dependencies_count; | |
| 128 size_t string_offset = 0; | |
| 129 for (size_t i = 0; i < dependencies_count; i++) { | |
| 130 std::string dependency_filename(dependencies_list + string_offset); | |
| 131 string_offset += dependency_filename.length() + 1; | |
| 132 AddBySoname(dependency_filename.c_str()); | |
| 133 } | |
| 134 return pso_root; | |
| 122 } | 135 } |
| 123 | 136 |
| 124 void *ModuleSet::GetSym(const char *name) { | 137 void *ModuleSet::GetSym(const char *name) { |
| 125 for (auto &module : modules_) { | 138 for (auto &module : modules_) { |
| 126 if (void *sym = module.GetExportedSym(name)) | 139 if (void *sym = module.GetExportedSym(name)) |
| 127 return sym; | 140 return sym; |
| 128 } | 141 } |
| 129 return NULL; | 142 return NULL; |
| 130 } | 143 } |
| 131 | 144 |
| 132 void ModuleSet::ResolveRefs() { | 145 void ModuleSet::ResolveRefs() { |
| 133 for (auto &module : modules_) { | 146 for (auto &module : modules_) { |
| 134 for (size_t index = 0, count = module.root()->import_count; | 147 for (size_t index = 0, count = module.root()->import_count; |
| 135 index < count; ++index) { | 148 index < count; ++index) { |
| 136 const char *sym_name = module.GetImportedSymbolName(index); | 149 const char *sym_name = module.GetImportedSymbolName(index); |
| 137 uintptr_t sym_value = (uintptr_t) GetSym(sym_name); | 150 uintptr_t sym_value = (uintptr_t) GetSym(sym_name); |
| 138 if (sym_value == 0) { | 151 if (sym_value == 0) { |
| 139 NaClLog(LOG_FATAL, "Undefined symbol: \"%s\"\n", sym_name); | 152 NaClLog(LOG_FATAL, "Undefined symbol: \"%s\"\n", sym_name); |
| 140 } | 153 } |
| 141 *(uintptr_t *) module.root()->imported_ptrs[index] += sym_value; | 154 *(uintptr_t *) module.root()->imported_ptrs[index] += sym_value; |
| 142 } | 155 } |
| 143 | 156 |
| 144 // Initialize TLS. | 157 // Initialize TLS. |
| 145 if (PLLTLSBlockGetter *tls_block_getter = module.root()->tls_block_getter) { | 158 if (PLLTLSBlockGetter *tls_block_getter = module.root()->tls_block_getter) { |
| 146 tls_block_getter->func = TLSBlockGetter; | 159 tls_block_getter->func = TLSBlockGetter; |
| 147 tls_block_getter->arg = module.InstantiateTLSBlock(); | 160 tls_block_getter->arg = module.InstantiateTLSBlock(); |
| 148 } | 161 } |
| 149 } | 162 } |
| 150 } | 163 } |
| OLD | NEW |