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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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. |
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. |
Mark Seaborn
2016/03/30 23:24:57
I think your current test case doesn't actually ve
Sean Klein
2016/04/01 23:12:24
This is behavior I'm adding in this CL; I'll test
| |
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: %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); |
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; | |
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 AddBySoname(dependency_filename.c_str()); | |
134 } | |
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 |