Skip to content

Commit 49ea149

Browse files
committed
Add support for linker script on Linux
GitHub: fix GH-107 Reported by nicholas a. evans. Thanks!!!
1 parent 9a5a1da commit 49ea149

File tree

2 files changed

+64
-1
lines changed

2 files changed

+64
-1
lines changed

lib/fiddle.rb

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,36 @@ def self.last_error= error
5858
#
5959
# See Fiddle::Handle.new for more.
6060
def dlopen library
61-
Fiddle::Handle.new library
61+
begin
62+
Fiddle::Handle.new(library)
63+
rescue DLError => error
64+
case RUBY_PLATFORM
65+
when /linux/
66+
case error.message
67+
when /\A(\/.+?): (?:invalid ELF header|file too short)/
68+
# This may be a linker script:
69+
# https://sourceware.org/binutils/docs/ld.html#Scripts
70+
path = $1
71+
else
72+
raise
73+
end
74+
else
75+
raise
76+
end
77+
78+
File.open(path) do |input|
79+
input.each_line do |line|
80+
case line
81+
when /\A\s*(?:INPUT|GROUP)\s*\(\s*([^\s,\)]+)/
82+
# TODO: Should we support multiple files?
83+
return dlopen($1)
84+
end
85+
end
86+
end
87+
88+
# Not found
89+
raise
90+
end
6291
end
6392
module_function :dlopen
6493

test/fiddle/test_fiddle.rb

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,38 @@ def test_windows_constant
1414
end
1515
end
1616

17+
def test_dlopen_linker_script_input_linux
18+
omit("This is only for Linux") unless RUBY_PLATFORM.match?("linux")
19+
if Dir.glob("/usr/lib/*/libncurses.so").empty?
20+
omit("libncurses.so is needed")
21+
end
22+
# libncurses.so uses INPUT() on Debian GNU/Linux
23+
# $ cat /usr/lib/x86_64-linux-gnu/libncurses.so
24+
# INPUT(libncurses.so.6 -ltinfo)
25+
handle = Fiddle.dlopen("libncurses.so")
26+
begin
27+
assert_equal("libncurses.so",
28+
File.basename(handle.file_name, ".*"))
29+
ensure
30+
handle.close
31+
end
32+
end
33+
34+
def test_dlopen_linker_script_group_linux
35+
omit("This is only for Linux") unless RUBY_PLATFORM.match?("linux")
36+
# libc.so uses GROUP() on Debian GNU/Linux
37+
# $ cat /usr/lib/x86_64-linux-gnu/libc.so
38+
# /* GNU ld script
39+
# Use the shared library, but some functions are only in
40+
# the static library, so try that secondarily. */
41+
# OUTPUT_FORMAT(elf64-x86-64)
42+
# GROUP ( /lib/x86_64-linux-gnu/libc.so.6 /usr/lib/x86_64-linux-gnu/libc_nonshared.a AS_NEEDED ( /lib64/ld-linux-x86-64.so.2 ) )
43+
handle = Fiddle.dlopen("libc.so")
44+
begin
45+
assert_equal("libc.so",
46+
File.basename(handle.file_name, ".*"))
47+
ensure
48+
handle.close
49+
end
50+
end
1751
end if defined?(Fiddle)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy