-
Notifications
You must be signed in to change notification settings - Fork 30.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
src: add support to pass flags to dlopen
This commit introduces an optional parameter for process.dlopen(), allowing to pass dlopen flags (using values from os.constants.dlopen). If no flags are passed, the default behavior is to load the library with RTLD_LAZY (perform lazy binding) and RTLD_LOCAL (symbols are available only locally). Signed-off-by: Ezequiel Garcia <[email protected]>
- Loading branch information
1 parent
6ec4386
commit 3ca00e7
Showing
6 changed files
with
217 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
#include <node.h> | ||
#include <v8.h> | ||
|
||
#ifndef _WIN32 | ||
|
||
#include <dlfcn.h> | ||
|
||
extern "C" const char* dlopen_pong(void) { | ||
return "pong"; | ||
} | ||
|
||
namespace { | ||
|
||
using v8::FunctionCallbackInfo; | ||
using v8::Isolate; | ||
using v8::Local; | ||
using v8::Object; | ||
using v8::String; | ||
using v8::Value; | ||
|
||
typedef const char* (*ping)(void); | ||
|
||
static ping ping_func; | ||
|
||
void LoadLibrary(const FunctionCallbackInfo<Value>& args) { | ||
const String::Utf8Value filename(args[0]); | ||
void* handle = dlopen(*filename, RTLD_LAZY); | ||
assert(handle != nullptr); | ||
ping_func = reinterpret_cast<ping>(dlsym(handle, "dlopen_ping")); | ||
assert(ping_func != nullptr); | ||
} | ||
|
||
void Ping(const FunctionCallbackInfo<Value>& args) { | ||
Isolate* isolate = args.GetIsolate(); | ||
assert(ping_func != nullptr); | ||
args.GetReturnValue().Set(String::NewFromUtf8(isolate, ping_func())); | ||
} | ||
|
||
void init(Local<Object> exports) { | ||
NODE_SET_METHOD(exports, "load", LoadLibrary); | ||
NODE_SET_METHOD(exports, "ping", Ping); | ||
} | ||
|
||
NODE_MODULE(binding, init) | ||
|
||
} // anonymous namespace | ||
|
||
#endif // _WIN32 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
{ | ||
'targets': [ | ||
{ | ||
'target_name': 'ping', | ||
'product_extension': 'so', | ||
'type': 'shared_library', | ||
'sources': [ 'ping.c' ], | ||
'conditions': [ | ||
['OS=="mac"', { | ||
'xcode_settings': { | ||
'OTHER_LDFLAGS': [ '-Wl,-undefined', '-Wl,dynamic_lookup' ] | ||
}}], | ||
# Pass erok flag to the linker, to prevent unresolved symbols | ||
# from failing. Still, the test won't pass, so we'll skip it on AIX. | ||
['OS=="aix"', { | ||
'ldflags': [ '-Wl,-berok' ] | ||
}]], | ||
}, | ||
{ | ||
'target_name': 'binding', | ||
'defines': [ 'V8_DEPRECATION_WARNINGS=1' ], | ||
'sources': [ 'binding.cc' ], | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#ifndef _WIN32 | ||
|
||
const char* dlopen_pong(void); | ||
|
||
const char* dlopen_ping(void) { | ||
return dlopen_pong(); | ||
} | ||
|
||
#endif // _WIN32 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
'use strict'; | ||
const common = require('../../common'); | ||
|
||
if (common.isWindows) | ||
common.skip('dlopen global symbol loading is not supported on this os.'); | ||
|
||
if (common.isAIX) | ||
common.skip('this test does not pass on AIX.'); | ||
|
||
const assert = require('assert'); | ||
const path = require('path'); | ||
const os = require('os'); | ||
|
||
const bindingPath = require.resolve(`./build/${common.buildType}/binding`); | ||
process.dlopen(module, bindingPath, | ||
os.constants.dlopen.RTLD_NOW | os.constants.dlopen.RTLD_GLOBAL); | ||
module.exports.load(path.dirname(bindingPath) + '/ping.so'); | ||
assert.strictEqual(module.exports.ping(), 'pong'); | ||
|
||
// Check that after the addon is loaded with | ||
// process.dlopen() a require() call fails. | ||
const re = /^Error: Module did not self-register\.$/; | ||
assert.throws(() => require(`./build/${common.buildType}/binding`), re); |