mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			55 lines
		
	
	
	
		
			1.5 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			55 lines
		
	
	
	
		
			1.5 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| #
 | |
| # Listing C's global variables in .so or .o, or .bundle on Mac OS using "objdump -t" (elf64-x86-64)
 | |
| # to check ractor-safety.
 | |
| #
 | |
| # Usage: ruby search-cgvars.rb foo.so bar.o .ext/x86_64-darwin18/psych.bundle
 | |
| #
 | |
| MAC_OS = RbConfig::CONFIG['host_os'].match? /darwin|mac os/
 | |
| 
 | |
| def gvars file
 | |
|   # '0000000000031ac8 g     O .bss   0000000000000008              rb_cSockIfaddr'
 | |
|   # On mac, with .bundle files:
 | |
|   # '0000000000004258 l     O __DATA,__bss  _passwd_blocking'
 | |
| 
 | |
|   strs = `objdump -t #{file}`
 | |
|   found = {}
 | |
|   strs.each_line{|line|
 | |
|     if /[\da-f]{16} / =~ line
 | |
|       addr = line[0...16]
 | |
|       flags = line[17...24].tr(' ', '').split(//).sort.uniq
 | |
|       rest = line[25..]
 | |
|       if MAC_OS
 | |
|         seg, name = rest.split(/\s+/)
 | |
|       else
 | |
|         seg, size, name = rest.split(/\s+/)
 | |
|       end
 | |
|       if flags.include?('O')
 | |
|         # p [addr, flags, seg, size, name]
 | |
|         found[name] = [flags, seg, *size]
 | |
|       end
 | |
|     end
 | |
|   }
 | |
|   puts "## #{file}:"
 | |
|   found.sort_by{|name, (flags, *)|
 | |
|     [flags, name]
 | |
|   }.each{|name, rest|
 | |
|     flags, seg, size = *rest
 | |
|     next if (size.to_i == 0 && !MAC_OS) && seg != '*UND*'
 | |
|     case seg
 | |
|     when ".rodata", ".data.rel.ro", ".got.plt", ".eh_frame", ".fini_array"
 | |
|       next
 | |
|     when /,__const$/ # Mac OS
 | |
|       next
 | |
|     end
 | |
|     case name
 | |
|     when /^id_/, /^rbimpl_id/, /^sym_/, /^rb_[cme]/, /\Acompleted\.\d+\z/
 | |
|       next
 | |
|     when /^_id_/, /\.rbimpl_id(\.\d+)?$/ # Mac OS
 | |
|       next
 | |
|     end
 | |
|     puts "  %40s %s" % [name, rest.inspect]
 | |
|   }
 | |
| end
 | |
| ARGV.each{|file|
 | |
|   gvars file
 | |
| }
 | 
