|
15 | 15 | #include "SourceKit/Support/UIdent.h"
|
16 | 16 |
|
17 | 17 | #include "llvm/Support/ErrorHandling.h"
|
| 18 | +#include "llvm/Support/MemoryBuffer.h" |
18 | 19 | #include "llvm/Support/Mutex.h"
|
| 20 | +#include "llvm/Support/Path.h" |
| 21 | + |
| 22 | +#include <Block.h> |
19 | 23 | #include <chrono>
|
20 | 24 | #include <xpc/xpc.h>
|
21 | 25 | #include <dispatch/dispatch.h>
|
22 |
| - |
23 |
| -#include <Block.h> |
| 26 | +#include <dlfcn.h> |
24 | 27 |
|
25 | 28 | using namespace SourceKit;
|
26 | 29 | using namespace sourcekitd;
|
@@ -285,9 +288,31 @@ static void handleInternalUIDRequest(xpc_object_t XVal,
|
285 | 288 |
|
286 | 289 | static void handleInterruptedConnection(xpc_object_t event, xpc_connection_t conn);
|
287 | 290 |
|
| 291 | +extern "C" const char __dso_handle[]; |
| 292 | + |
288 | 293 | static void initializeXPCClient() {
|
289 | 294 | assert(!GlobalConn);
|
290 |
| - GlobalConn = xpc_connection_create(SOURCEKIT_XPCSERVICE_IDENTIFIER, nullptr); |
| 295 | + |
| 296 | + Dl_info dlinfo; |
| 297 | + dladdr(__dso_handle, &dlinfo); |
| 298 | + |
| 299 | + // '.../usr/lib/sourcekitd.framework/sourcekitd' |
| 300 | + llvm::SmallString<128> serviceNamePath(dlinfo.dli_fname); |
| 301 | + if (serviceNamePath.empty()) { |
| 302 | + llvm::report_fatal_error("Unable to find service name path"); |
| 303 | + } |
| 304 | + |
| 305 | + llvm::sys::path::remove_filename(serviceNamePath); |
| 306 | + // '.../usr/lib/sourcekitd.framework/Resources/xpc_service_name.txt' |
| 307 | + llvm::sys::path::append(serviceNamePath, "Resources", "xpc_service_name.txt"); |
| 308 | + |
| 309 | + auto bufferOrErr = llvm::MemoryBuffer::getFile(serviceNamePath); |
| 310 | + if (!bufferOrErr) { |
| 311 | + llvm::report_fatal_error("Unable to find service name"); |
| 312 | + } |
| 313 | + |
| 314 | + std::string serviceName = (*bufferOrErr)->getBuffer().trim().str(); |
| 315 | + GlobalConn = xpc_connection_create(serviceName.c_str(), nullptr); |
291 | 316 |
|
292 | 317 | xpc_connection_set_event_handler(GlobalConn, ^(xpc_object_t event) {
|
293 | 318 | xpc_type_t type = xpc_get_type(event);
|
@@ -390,7 +415,9 @@ void sourcekitd_register_plugin_path(const char *clientPlugin,
|
390 | 415 | }
|
391 | 416 |
|
392 | 417 | static xpc_connection_t getGlobalConnection() {
|
393 |
| - assert(GlobalConn); |
| 418 | + if (!GlobalConn) { |
| 419 | + llvm::report_fatal_error("Service is invalid"); |
| 420 | + } |
394 | 421 | return GlobalConn;
|
395 | 422 | }
|
396 | 423 |
|
|
0 commit comments