2019-05-16 17:26:57 +03:00
|
|
|
#!/usr/bin/ruby
|
2019-07-15 02:54:34 +03:00
|
|
|
require_relative 'lib/colorize'
|
2019-05-16 17:26:57 +03:00
|
|
|
|
|
|
|
until ARGV.empty?
|
|
|
|
case ARGV[0]
|
|
|
|
when /\ASYMBOL_PREFIX=(.*)/
|
|
|
|
SYMBOL_PREFIX = $1
|
|
|
|
when /\ANM=(.*)/ # may be multiple words
|
|
|
|
NM = $1
|
2020-12-27 08:58:00 +03:00
|
|
|
when /\APLATFORM=(.+)?/
|
|
|
|
platform = $1
|
2019-05-16 17:26:57 +03:00
|
|
|
else
|
|
|
|
break
|
|
|
|
end
|
|
|
|
ARGV.shift
|
|
|
|
end
|
|
|
|
|
|
|
|
config = ARGV.shift
|
|
|
|
count = 0
|
|
|
|
col = Colorize.new
|
2020-12-25 18:53:51 +03:00
|
|
|
config_code = File.read(config)
|
2020-12-26 15:47:57 +03:00
|
|
|
REPLACE = config_code.scan(/\bAC_(?:REPLACE|CHECK)_FUNCS?\((\w+)/).flatten
|
2020-12-27 08:05:24 +03:00
|
|
|
# REPLACE << 'memcmp' if /\bAC_FUNC_MEMCMP\b/ =~ config_code
|
2020-12-26 15:46:27 +03:00
|
|
|
REPLACE.push('main', 'DllMain')
|
2020-12-27 08:58:00 +03:00
|
|
|
if platform and !platform.empty?
|
|
|
|
begin
|
|
|
|
h = File.read(platform)
|
|
|
|
rescue Errno::ENOENT
|
|
|
|
else
|
|
|
|
REPLACE.concat(
|
|
|
|
h .gsub(%r[/\*.*?\*/]m, " ") # delete block comments
|
|
|
|
.gsub(%r[//.*], ' ') # delete oneline comments
|
|
|
|
.gsub(/^\s*#.*(?:\\\n.*)*/, "") # delete preprocessor directives
|
|
|
|
.scan(/\b((?!rb_|DEPRECATED|_)\w+)\s*\(.*\);/)
|
|
|
|
.flatten)
|
|
|
|
end
|
|
|
|
end
|
2020-12-27 08:05:24 +03:00
|
|
|
missing = File.dirname(config) + "/missing/"
|
|
|
|
ARGV.reject! do |n|
|
|
|
|
unless (src = Dir.glob(missing + File.basename(n, ".*") + ".[cS]")).empty?
|
|
|
|
puts "Ignore #{n} because of #{src.map {|s| File.basename(s)}.join(', ')} under missing"
|
|
|
|
true
|
|
|
|
end
|
|
|
|
end
|
2019-05-16 17:26:57 +03:00
|
|
|
print "Checking leaked global symbols..."
|
|
|
|
STDOUT.flush
|
|
|
|
IO.foreach("|#{NM} -Pgp #{ARGV.join(' ')}") do |line|
|
|
|
|
n, t, = line.split
|
2020-06-04 10:24:45 +03:00
|
|
|
next unless /[A-TV-Z]/ =~ t
|
2019-05-16 17:26:57 +03:00
|
|
|
next unless n.sub!(/^#{SYMBOL_PREFIX}/o, "")
|
|
|
|
next if n.include?(".")
|
2020-12-29 15:00:02 +03:00
|
|
|
next if /\A(?:Init_|InitVM_|RUBY_|ruby_|rb_|[Oo]nig|dln_|mjit_|coroutine_)/ =~ n
|
2019-05-16 17:26:57 +03:00
|
|
|
next if REPLACE.include?(n)
|
|
|
|
puts col.fail("leaked") if count.zero?
|
|
|
|
count += 1
|
|
|
|
puts " #{n}"
|
|
|
|
end
|
|
|
|
case count
|
|
|
|
when 0
|
|
|
|
puts col.pass("none")
|
|
|
|
when 1
|
|
|
|
abort col.fail("1 un-prefixed symbol leaked")
|
|
|
|
else
|
|
|
|
abort col.fail("#{count} un-prefixed symbols leaked")
|
|
|
|
end
|