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!!!
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. | ||||
|   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 | ||||
|   module_function :dlopen | ||||
| 
 | ||||
|  |  | |||
|  | @ -14,4 +14,38 @@ class TestFiddle < Fiddle::TestCase | |||
|     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) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Sutou Kouhei
						Sutou Kouhei