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
 | 
						|
}
 |