Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(306)

Side by Side Diff: gold/nacl_file.cc

Issue 770833002: Gold translator: Use IRT open_resource instead of SRPC conn to nameservice. (Closed) Base URL: https://chromium.googlesource.com/native_client/nacl-binutils.git@master
Patch Set: review Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // nacl_file.cc -- handle file lookups for NaCl version of gold -*- C++ -*- 1 // nacl_file.cc -- handle file lookups for NaCl version of gold -*- C++ -*-
2 2
3 // Copyright 2012 Free Software Foundation, Inc. 3 // Copyright 2012 Free Software Foundation, Inc.
4 // Written by the Native Client authors. 4 // Written by the Native Client authors.
5 5
6 // This file is part of gold. 6 // This file is part of gold.
7 7
8 // This program is free software; you can redistribute it and/or modify 8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by 9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 3 of the License, or 10 // the Free Software Foundation; either version 3 of the License, or
(...skipping 15 matching lines...) Expand all
26 #if !defined(__native_client__) 26 #if !defined(__native_client__)
27 #error "Cannot build nacl_file.cc without __native_client__" 27 #error "Cannot build nacl_file.cc without __native_client__"
28 #endif 28 #endif
29 29
30 #include <fcntl.h> 30 #include <fcntl.h>
31 #include <map> 31 #include <map>
32 #include <string> 32 #include <string>
33 #include <unistd.h> 33 #include <unistd.h>
34 #include <vector> 34 #include <vector>
35 35
36 #include "native_client/src/public/imc_syscalls.h" 36 #include <irt.h>
37 #include "native_client/src/public/name_service.h"
38 #include "native_client/src/shared/srpc/nacl_srpc.h" 37 #include "native_client/src/shared/srpc/nacl_srpc.h"
39 38
40 #include "gold.h" 39 #include "gold.h"
41 40
42 using namespace gold; 41 using namespace gold;
43 42
44 extern int gold_main(int argc, char** argv); 43 extern int gold_main(int argc, char** argv);
45 44
46 #define FILENAME_OUTPUT "a.out" 45 #define FILENAME_OUTPUT "a.out"
47 #define FILENAME_OBJ "__PNACL_GENERATED" 46 #define FILENAME_OBJ "__PNACL_GENERATED"
48 47
49 const int kMaxArgc = 256; 48 const int kMaxArgc = 256;
50 // This value cannot change without also changing the signature of the 49 // This value cannot change without also changing the signature of the
51 // RunWithSplit RPC 50 // RunWithSplit RPC
52 const int kMaxObjectFiles = 16; 51 const int kMaxObjectFiles = 16;
53 52
54 namespace 53 namespace
55 { 54 {
56 std::map<std::string, int> g_preopened_files; 55 std::map<std::string, int> g_preopened_files;
56 struct nacl_irt_resource_open g_irt_resource_open;
57 57
58 // Register some filename -> fd mappings so that we do not 58 // Register some filename -> fd mappings that correspond to pre-opened fds.
59 // need to use the ManifestNameService (aka directory) service. 59 // Otherwise files are opened via the IRT open_resource() function.
60 // Note, there seems to be the following convention:
61 // the directory service knows about files like "files/<filename>".
62 // Locally, we refer to the files as <filename>.
63 // For object files passed in via Srpc, we register the incoming .o
64 // descriptor as FILENAME_OBJ WITHOUT the "files/" prefix.
65 void RegisterPreopenedFd(const char* filename, int fd) { 60 void RegisterPreopenedFd(const char* filename, int fd) {
66 std::string key(filename); 61 std::string key(filename);
67 std::map<std::string, int>::iterator it = g_preopened_files.find(key); 62 std::map<std::string, int>::iterator it = g_preopened_files.find(key);
68 63
69 if (it != g_preopened_files.end()) { 64 if (it != g_preopened_files.end()) {
70 gold_fatal(_("nacl_file::set_preopened_fd already set %s to %d."), 65 gold_fatal(_("nacl_file::set_preopened_fd already set %s to %d."),
71 filename, it->second); 66 filename, it->second);
72 } else { 67 } else {
73 g_preopened_files[key] = fd; 68 g_preopened_files[key] = fd;
74 } 69 }
75 } 70 }
76 71
77 // Look up additional resource files through the nacl manifest service 72 // Set up interfaces for IRT open_resource.
78 // which essentially maps a (file)name to a (file)descriptor 73 void GetIRTInterface() {
79 NaClSrpcChannel g_nacl_manifest_channel; 74 size_t query_result = nacl_interface_query(
80 75 NACL_IRT_RESOURCE_OPEN_v0_1,
81 // Make ManifestNameService service available for lookups. 76 &g_irt_resource_open, sizeof(g_irt_resource_open));
82 void ManifestLookupInit() { 77 if (query_result != sizeof(g_irt_resource_open)) {
83 int nameservice_address = -1; 78 gold_fatal(_("nacl_file::GetIRTInterface failed"));
84 int nameservice_fd = -1;
85 int manifest_address = -1;
86 int manifest_fd = -1;
87 int status;
88 NaClSrpcChannel nameservice_channel;
89
90 /* Attach to the reverse service for doing manifest file queries. */
91 nacl_nameservice(&nameservice_address);
92 if (nameservice_address == -1) {
93 gold_fatal(_("nacl_nameservice failed\n"));
94 }
95 nameservice_fd = imc_connect(nameservice_address);
96 close(nameservice_address);
97 if (nameservice_fd == -1) {
98 gold_fatal(_("name service connect failed\n"));
99 }
100 if (!NaClSrpcClientCtor(&nameservice_channel, nameservice_fd)) {
101 gold_fatal(_("name service channel ctor failed\n"));
102 }
103 if (NACL_SRPC_RESULT_OK !=
104 NaClSrpcInvokeBySignature(&nameservice_channel, NACL_NAME_SERVICE_LOOKUP,
105 "ManifestNameService", O_RDWR,
106 &status, &manifest_address)) {
107 gold_fatal(_("ManifestNameService SRPC failed, status %d\n"), status);
108 }
109 NaClSrpcDtor(&nameservice_channel);
110 if (manifest_address == -1) {
111 gold_fatal(_("manifest name service address is -1\n"));
112 }
113 manifest_fd = imc_connect(manifest_address);
114 close(manifest_address);
115 if (manifest_fd == -1) {
116 gold_fatal(_("manifest name service connect failed\n"));
117 }
118 if (!NaClSrpcClientCtor(&g_nacl_manifest_channel, manifest_fd)) {
119 gold_fatal(_("manifest channel ctor failed\n"));
120 } 79 }
121 } 80 }
122 81
123 void ManifestLookupFini() { 82 int IrtOpenFile(const char* filename) {
124 NaClSrpcDtor(&g_nacl_manifest_channel); 83 int fd = -1;
125 } 84 if (int res = g_irt_resource_open.open_resource(filename, &fd)) {
126 85 gold_fatal(_("IrtOpenFile (%s) failed: %d\n"), filename, res);
127 const int kUnknownFd = -1;
128
129 int LookupFileByName(const char* filename) {
130 int fd = kUnknownFd;
131 int status;
132 // Files looked up via the nameservice are assumed to have a "files/" prefix.
133 std::string prefix("files/");
134 std::string full_filename = prefix + std::string(filename);
135 NaClSrpcError error =
136 NaClSrpcInvokeBySignature(&g_nacl_manifest_channel,
137 NACL_NAME_SERVICE_LOOKUP,
138 full_filename.c_str(),
139 O_RDONLY,
140 &status,
141 &fd);
142 if (error != NACL_SRPC_RESULT_OK) {
143 gold_fatal(_("Lookup (%s) failed.\n"), filename);
144 } 86 }
145 return fd; 87 return fd;
146 } 88 }
147 89
148 void RunCommon(const std::vector<std::string>& arg_vec, 90 void RunCommon(const std::vector<std::string>& arg_vec,
149 NaClSrpcRpc* rpc, 91 NaClSrpcRpc* rpc,
150 NaClSrpcClosure* done) { 92 NaClSrpcClosure* done) {
151 // repackage the commandline to what main() expects 93 // repackage the commandline to what main() expects
152 const char* argv[kMaxArgc]; 94 const char* argv[kMaxArgc];
153 if (arg_vec.size() > kMaxArgc) { 95 if (arg_vec.size() > kMaxArgc) {
154 gold_fatal(_("commandline too long")); 96 gold_fatal(_("commandline too long"));
155 } 97 }
156 for (size_t i = 0; i < arg_vec.size(); ++i) argv[i] = arg_vec[i].c_str(); 98 for (size_t i = 0; i < arg_vec.size(); ++i) argv[i] = arg_vec[i].c_str();
157 99
158 // call hijacked main() 100 // call hijacked main()
159 int ret = gold_main(arg_vec.size(), const_cast<char**>(&argv[0])); 101 int ret = gold_main(arg_vec.size(), const_cast<char**>(&argv[0]));
160 rpc->result = ret > 0 ? NACL_SRPC_RESULT_APP_ERROR : NACL_SRPC_RESULT_OK; 102 rpc->result = ret > 0 ? NACL_SRPC_RESULT_APP_ERROR : NACL_SRPC_RESULT_OK;
161 done->Run(done); 103 done->Run(done);
162 } 104 }
163 105
164 106 // c.f.: pnacl/driver/nativeld.py
165 // c.f.: pnacl/driver/pnacl-nativeld.py
166 const char* kDefaultCommandCommon[] = { 107 const char* kDefaultCommandCommon[] = {
167 "gold", 108 "gold",
168 "--eh-frame-hdr", 109 "--eh-frame-hdr",
169 "-nostdlib", 110 "-nostdlib",
170 // ARM only but added to everything for convenience 111 // ARM only but added to everything for convenience
171 "--no-fix-cortex-a8", 112 "--no-fix-cortex-a8",
172 "-o", 113 "-o",
173 FILENAME_OUTPUT, 114 FILENAME_OUTPUT,
174 0 115 0
175 }; 116 };
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 } 192 }
252 command_line[arg] = 0; 193 command_line[arg] = 0;
253 194
254 ProcessCommandline(command_line, &result_arg_vec); 195 ProcessCommandline(command_line, &result_arg_vec);
255 for (int i = 0; i < object_count; i++) { 196 for (int i = 0; i < object_count; i++) {
256 delete [] filenames[i]; 197 delete [] filenames[i];
257 } 198 }
258 RunCommon(result_arg_vec, rpc, done); 199 RunCommon(result_arg_vec, rpc, done);
259 } 200 }
260 201
261 } // End namespace gold. 202 } // End anonymous namespace.
262 203
263 namespace nacl_file 204 namespace nacl_file
264 { 205 {
265 206
266 // This is the only exported API from this file
267 int NaClOpenFileDescriptor(const char *filename) { 207 int NaClOpenFileDescriptor(const char *filename) {
268 std::string key(filename); 208 std::string key(filename);
269 std::map<std::string, int>::iterator it = g_preopened_files.find(key); 209 std::map<std::string, int>::iterator it = g_preopened_files.find(key);
270 int fd; 210 int fd;
211 // First check if it is a pre-opened file.
271 if (it != g_preopened_files.end()) { 212 if (it != g_preopened_files.end()) {
272 fd = it->second; 213 fd = it->second;
273 } else { 214 } else {
274 // Otherwise, ask the nameservice. 215 // Otherwise, open the file through the IRT.
275 fd = LookupFileByName(filename); 216 fd = IrtOpenFile(filename);
276 } 217 }
277 // in case the file was re-opened, say to do --start/end-group 218 // In case the file was re-opened, seek back to the beginning.
219 // This might be the case for the --start/end-group implementation.
278 lseek(fd, 0, SEEK_SET); 220 lseek(fd, 0, SEEK_SET);
279 return fd; 221 return fd;
280 } 222 }
281 223
282 void NaClReleaseFileDescriptor(int fd) { 224 void NaClReleaseFileDescriptor(int fd) {
283 // Note: we do not close the fd as it maybe opened again. 225 // Note: we do not close the fd as it maybe opened again.
284 // For now we are getting lucky: 226 // For now we are getting lucky:
285 // gold is not closing any of the libraries. And it IS closing 227 // gold is not closing any of the libraries. And it IS closing
286 // the nexe for us in Output_file::close 228 // the nexe for us in Output_file::close
287 } 229 }
288 230
289 } // End namespace nacl_file. 231 } // End namespace nacl_file.
290 232
291 233
292 int 234 int main() {
293 main()
294 {
295 if (!NaClSrpcModuleInit()) { 235 if (!NaClSrpcModuleInit()) {
296 gold_fatal(_("NaClSrpcModuleInit failed\n")); 236 gold_fatal(_("NaClSrpcModuleInit failed\n"));
297 } 237 }
298 ManifestLookupInit(); 238 GetIRTInterface();
299 239
300 // Start the message loop to process SRPCs. 240 // Start the message loop to process SRPCs.
301 // It usually never terminates unless killed. 241 // It usually never terminates unless killed.
302 const struct NaClSrpcHandlerDesc srpc_methods[] = { 242 const struct NaClSrpcHandlerDesc srpc_methods[] = {
303 { "RunWithSplit:ihhhhhhhhhhhhhhhhh:", SrpcRunWithSplit }, 243 { "RunWithSplit:ihhhhhhhhhhhhhhhhh:", SrpcRunWithSplit },
304 { NULL, NULL }, 244 { NULL, NULL },
305 }; 245 };
306 246
307 if (!NaClSrpcAcceptClientConnection(srpc_methods)) { 247 if (!NaClSrpcAcceptClientConnection(srpc_methods)) {
308 gold_fatal(_("NaClSrpcAcceptClientConnection failed\n")); 248 gold_fatal(_("NaClSrpcAcceptClientConnection failed\n"));
309 } 249 }
310 250
311 ManifestLookupFini();
312 NaClSrpcModuleFini(); 251 NaClSrpcModuleFini();
313 return 0; 252 return 0;
314 } 253 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698