mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
[ruby/fiddle] Add support for linker script on Linux
GitHub: fix https://github.com/ruby/fiddle/pull/107 Reported by nicholas a. evans. Thanks!!! https://github.com/ruby/fiddle/commit/49ea1490df
This commit is contained in:
parent
93da67d463
commit
e84ea4af69
Notes:
git
2022-10-18 08:22:06 +00:00
2 changed files with 64 additions and 1 deletions
|
@ -58,7 +58,36 @@ module Fiddle
|
||||||
#
|
#
|
||||||
# See Fiddle::Handle.new for more.
|
# See Fiddle::Handle.new for more.
|
||||||
def dlopen library
|
def dlopen library
|
||||||
Fiddle::Handle.new library
|
begin
|
||||||
|
Fiddle::Handle.new(library)
|
||||||
|
rescue DLError => error
|
||||||
|
case RUBY_PLATFORM
|
||||||
|
when /linux/
|
||||||
|
case error.message
|
||||||
|
when /\A(\/.+?): (?:invalid ELF header|file too short)/
|
||||||
|
# This may be a linker script:
|
||||||
|
# https://sourceware.org/binutils/docs/ld.html#Scripts
|
||||||
|
path = $1
|
||||||
|
else
|
||||||
|
raise
|
||||||
|
end
|
||||||
|
else
|
||||||
|
raise
|
||||||
|
end
|
||||||
|
|
||||||
|
File.open(path) do |input|
|
||||||
|
input.each_line do |line|
|
||||||
|
case line
|
||||||
|
when /\A\s*(?:INPUT|GROUP)\s*\(\s*([^\s,\)]+)/
|
||||||
|
# TODO: Should we support multiple files?
|
||||||
|
return dlopen($1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Not found
|
||||||
|
raise
|
||||||
|
end
|
||||||
end
|
end
|
||||||
module_function :dlopen
|
module_function :dlopen
|
||||||
|
|
||||||
|
|
|
@ -14,4 +14,38 @@ class TestFiddle < Fiddle::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_dlopen_linker_script_input_linux
|
||||||
|
omit("This is only for Linux") unless RUBY_PLATFORM.match?("linux")
|
||||||
|
if Dir.glob("/usr/lib/*/libncurses.so").empty?
|
||||||
|
omit("libncurses.so is needed")
|
||||||
|
end
|
||||||
|
# libncurses.so uses INPUT() on Debian GNU/Linux
|
||||||
|
# $ cat /usr/lib/x86_64-linux-gnu/libncurses.so
|
||||||
|
# INPUT(libncurses.so.6 -ltinfo)
|
||||||
|
handle = Fiddle.dlopen("libncurses.so")
|
||||||
|
begin
|
||||||
|
assert_equal("libncurses.so",
|
||||||
|
File.basename(handle.file_name, ".*"))
|
||||||
|
ensure
|
||||||
|
handle.close
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_dlopen_linker_script_group_linux
|
||||||
|
omit("This is only for Linux") unless RUBY_PLATFORM.match?("linux")
|
||||||
|
# libc.so uses GROUP() on Debian GNU/Linux
|
||||||
|
# $ cat /usr/lib/x86_64-linux-gnu/libc.so
|
||||||
|
# /* GNU ld script
|
||||||
|
# Use the shared library, but some functions are only in
|
||||||
|
# the static library, so try that secondarily. */
|
||||||
|
# OUTPUT_FORMAT(elf64-x86-64)
|
||||||
|
# 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 ) )
|
||||||
|
handle = Fiddle.dlopen("libc.so")
|
||||||
|
begin
|
||||||
|
assert_equal("libc.so",
|
||||||
|
File.basename(handle.file_name, ".*"))
|
||||||
|
ensure
|
||||||
|
handle.close
|
||||||
|
end
|
||||||
|
end
|
||||||
end if defined?(Fiddle)
|
end if defined?(Fiddle)
|
||||||
|
|
Loading…
Reference in a new issue