Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle linker scripts #5

Merged
1 commit merged into from Nov 22, 2010
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 28 additions & 1 deletion lib/dynamic_library.js
Expand Up @@ -5,7 +5,34 @@ var DynamicLibrary = module.exports = function(path, mode) {
this._handle = this._dlopen(path, mode || DynamicLibrary.FLAGS.RTLD_NOW);

if (this._handle.isNull()) {
throw new Error("Dynamic Linking Error: " + this._dlerror());
var err = this._dlerror();

// THIS CODE IS BASED ON GHC Trac ticket #2615
// http://hackage.haskell.org/trac/ghc/attachment/ticket/2615

// On some systems (e.g., Gentoo Linux) dynamic files (e.g. libc.so)
// contain linker scripts rather than ELF-format object code. This
// code handles the situation by recognizing the real object code
// file name given in the linker script.

// If an "invalid ELF header" error occurs, it is assumed that the
// .so file contains a linker script instead of ELF object code.
// In this case, the code looks for the GROUP ( ... ) linker
// directive. If one is found, the first file name inside the
// parentheses is treated as the name of a dynamic library and the
// code attempts to dlopen that file. If this is also unsuccessful,
// an error message is returned.

// see if the error message is due to an invalid ELF header
var match;
if (match = err.match(/^(([^ \t()])+\.so([^ \t:()])*):([ \t])*invalid ELF header$/)) {
var content = require("fs").readFileSync(match[1], 'ascii');
// try to find a GROUP ( ... ) command
if (match = content.match(/GROUP *\( *(([^ )])+)/)){
return DynamicLibrary.call(this, match[1], mode);
}
}
throw new Error("Dynamic Linking Error: " + err);
}
};

Expand Down