seafoam 0.11 → 0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/seafoam/commands.rb +0 -44
- data/lib/seafoam/version.rb +1 -1
- data/lib/seafoam.rb +0 -2
- metadata +8 -41
- data/bin/cfg2asm +0 -20
- data/lib/seafoam/cfg/cfg_parser.rb +0 -93
- data/lib/seafoam/cfg/disassembler.rb +0 -70
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5365ea61783b2be678609c214262d4df073fa4e66df60e9370b6fd33dd73825a
|
|
4
|
+
data.tar.gz: 322fe5170082c57d51120c3fa43910ca2e79a7839737167955ad1f330084af83
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 33cdf9e0f73e9a41d11ee2c19f60b015f8fe5168ddd92eaee1a254c13c6296e8696514858e0fc0c77c583657c3d01b2292919077f9131768198801bd9610dbc9
|
|
7
|
+
data.tar.gz: 2354dd4f1c5d87c83d265577a0e64b5130cd9dc7de46e6222629b985bdac038b6977f3fe10ffc2624e45b2cc56dbd67ea243734a528a17eab780a80c00996621
|
data/lib/seafoam/commands.rb
CHANGED
|
@@ -147,50 +147,6 @@ module Seafoam
|
|
|
147
147
|
end
|
|
148
148
|
end
|
|
149
149
|
|
|
150
|
-
def cfg2asm(*args)
|
|
151
|
-
case args.first
|
|
152
|
-
when nil, 'help', '-h', '--help', '-help'
|
|
153
|
-
args = args.drop(1)
|
|
154
|
-
raise ArgumentError, "unexpected arguments #{args.join(' ')}" unless args.empty?
|
|
155
|
-
|
|
156
|
-
@out.puts 'cfg2asm file.bgv...'
|
|
157
|
-
@out.puts ' --no-comments'
|
|
158
|
-
@out.puts ' --help'
|
|
159
|
-
@out.puts ' --version'
|
|
160
|
-
when 'version', '-v', '-version', '--version'
|
|
161
|
-
args = args.drop(1)
|
|
162
|
-
version(*args)
|
|
163
|
-
else
|
|
164
|
-
comments = true
|
|
165
|
-
files = []
|
|
166
|
-
|
|
167
|
-
until args.empty?
|
|
168
|
-
arg = args.shift
|
|
169
|
-
if arg.start_with?('-')
|
|
170
|
-
case arg
|
|
171
|
-
when '--no-comments'
|
|
172
|
-
comments = false
|
|
173
|
-
else
|
|
174
|
-
raise ArgumentError, "unknown option #{arg}"
|
|
175
|
-
end
|
|
176
|
-
else
|
|
177
|
-
files.push arg
|
|
178
|
-
end
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
files.each_with_index do |file, n|
|
|
182
|
-
parser = Seafoam::CFG::CFGParser.new(@out, file)
|
|
183
|
-
parser.skip_over_cfg 'After code installation'
|
|
184
|
-
nmethod = parser.read_nmethod
|
|
185
|
-
|
|
186
|
-
disassembler = Seafoam::CFG::Disassembler.new(@out)
|
|
187
|
-
@out.puts if n.positive?
|
|
188
|
-
@out.puts "[#{file}]"
|
|
189
|
-
disassembler.disassemble(nmethod, comments)
|
|
190
|
-
end
|
|
191
|
-
end
|
|
192
|
-
end
|
|
193
|
-
|
|
194
150
|
private
|
|
195
151
|
|
|
196
152
|
# seafoam file.bgv info
|
data/lib/seafoam/version.rb
CHANGED
data/lib/seafoam.rb
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
require 'seafoam/version'
|
|
2
2
|
require 'seafoam/binary/io_binary_reader'
|
|
3
3
|
require 'seafoam/bgv/bgv_parser'
|
|
4
|
-
require 'seafoam/cfg/cfg_parser'
|
|
5
|
-
require 'seafoam/cfg/disassembler'
|
|
6
4
|
require 'seafoam/colors'
|
|
7
5
|
require 'seafoam/graph'
|
|
8
6
|
require 'seafoam/graal/graph_description'
|
metadata
CHANGED
|
@@ -1,43 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: seafoam
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: '0.
|
|
4
|
+
version: '0.12'
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Chris Seaton
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-
|
|
11
|
+
date: 2022-02-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
-
- !ruby/object:Gem::Dependency
|
|
14
|
-
name: crabstone
|
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
|
16
|
-
requirements:
|
|
17
|
-
- - "~>"
|
|
18
|
-
- !ruby/object:Gem::Version
|
|
19
|
-
version: '4.0'
|
|
20
|
-
type: :runtime
|
|
21
|
-
prerelease: false
|
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
-
requirements:
|
|
24
|
-
- - "~>"
|
|
25
|
-
- !ruby/object:Gem::Version
|
|
26
|
-
version: '4.0'
|
|
27
|
-
- !ruby/object:Gem::Dependency
|
|
28
|
-
name: benchmark-ips
|
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
|
30
|
-
requirements:
|
|
31
|
-
- - "~>"
|
|
32
|
-
- !ruby/object:Gem::Version
|
|
33
|
-
version: '2.7'
|
|
34
|
-
type: :development
|
|
35
|
-
prerelease: false
|
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
-
requirements:
|
|
38
|
-
- - "~>"
|
|
39
|
-
- !ruby/object:Gem::Version
|
|
40
|
-
version: '2.7'
|
|
41
13
|
- !ruby/object:Gem::Dependency
|
|
42
14
|
name: rake
|
|
43
15
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -80,25 +52,21 @@ dependencies:
|
|
|
80
52
|
- - "~>"
|
|
81
53
|
- !ruby/object:Gem::Version
|
|
82
54
|
version: '0.74'
|
|
83
|
-
description:
|
|
84
|
-
email:
|
|
55
|
+
description:
|
|
56
|
+
email:
|
|
85
57
|
executables:
|
|
86
58
|
- seafoam
|
|
87
59
|
- bgv2json
|
|
88
60
|
- bgv2isabelle
|
|
89
|
-
- cfg2asm
|
|
90
61
|
extensions: []
|
|
91
62
|
extra_rdoc_files: []
|
|
92
63
|
files:
|
|
93
64
|
- bin/bgv2isabelle
|
|
94
65
|
- bin/bgv2json
|
|
95
|
-
- bin/cfg2asm
|
|
96
66
|
- bin/seafoam
|
|
97
67
|
- lib/seafoam.rb
|
|
98
68
|
- lib/seafoam/bgv/bgv_parser.rb
|
|
99
69
|
- lib/seafoam/binary/io_binary_reader.rb
|
|
100
|
-
- lib/seafoam/cfg/cfg_parser.rb
|
|
101
|
-
- lib/seafoam/cfg/disassembler.rb
|
|
102
70
|
- lib/seafoam/colors.rb
|
|
103
71
|
- lib/seafoam/commands.rb
|
|
104
72
|
- lib/seafoam/formatters/base.rb
|
|
@@ -122,7 +90,7 @@ homepage: https://github.com/Shopify/seafoam
|
|
|
122
90
|
licenses:
|
|
123
91
|
- MIT
|
|
124
92
|
metadata: {}
|
|
125
|
-
post_install_message:
|
|
93
|
+
post_install_message:
|
|
126
94
|
rdoc_options: []
|
|
127
95
|
require_paths:
|
|
128
96
|
- lib
|
|
@@ -137,9 +105,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
137
105
|
- !ruby/object:Gem::Version
|
|
138
106
|
version: '0'
|
|
139
107
|
requirements: []
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
signing_key:
|
|
108
|
+
rubygems_version: 3.3.3
|
|
109
|
+
signing_key:
|
|
143
110
|
specification_version: 4
|
|
144
111
|
summary: A tool for working with compiler graphs
|
|
145
112
|
test_files: []
|
data/bin/cfg2asm
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
|
|
3
|
-
require 'seafoam'
|
|
4
|
-
|
|
5
|
-
# This is the 'cfg2asm' command line entry point.
|
|
6
|
-
|
|
7
|
-
begin
|
|
8
|
-
# Run the command line.
|
|
9
|
-
commands = Seafoam::Commands.new($stdout)
|
|
10
|
-
commands.cfg2asm(*ARGV)
|
|
11
|
-
rescue StandardError => e
|
|
12
|
-
if $DEBUG
|
|
13
|
-
# Re-raise the exception so the user sees it, if debugging is
|
|
14
|
-
# enabled (ruby -d).
|
|
15
|
-
raise e
|
|
16
|
-
else
|
|
17
|
-
# Otherwise, just print the message.
|
|
18
|
-
warn "seafoam: #{e.message}"
|
|
19
|
-
end
|
|
20
|
-
end
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
require 'stringio'
|
|
2
|
-
require 'zlib'
|
|
3
|
-
|
|
4
|
-
module Seafoam
|
|
5
|
-
module CFG
|
|
6
|
-
Code = Struct.new(:arch, :arch_width, :base, :code)
|
|
7
|
-
Comment = Struct.new(:offset, :comment)
|
|
8
|
-
NMethod = Struct.new(:code, :comments)
|
|
9
|
-
|
|
10
|
-
# A parser for CFG files.
|
|
11
|
-
class CFGParser
|
|
12
|
-
def initialize(out, file)
|
|
13
|
-
@out = out
|
|
14
|
-
data = File.read(file, encoding: Encoding::ASCII_8BIT)
|
|
15
|
-
if data[0..1].bytes == [0x1f, 0x8b]
|
|
16
|
-
data = Zlib.gunzip(data)
|
|
17
|
-
end
|
|
18
|
-
@reader = StringIO.new(data)
|
|
19
|
-
@state = :any
|
|
20
|
-
@cfg_name = nil
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def skip_over_cfg(name)
|
|
24
|
-
loop do
|
|
25
|
-
line = @reader.readline("\n")
|
|
26
|
-
case line
|
|
27
|
-
when "begin_cfg\n"
|
|
28
|
-
@state = :cfg
|
|
29
|
-
@cfg_name = nil
|
|
30
|
-
when / name "(.*)"\n/
|
|
31
|
-
if @state == :cfg
|
|
32
|
-
@cfg_name = Regexp.last_match(1)
|
|
33
|
-
end
|
|
34
|
-
when "end_cfg\n"
|
|
35
|
-
raise unless @state == :cfg
|
|
36
|
-
|
|
37
|
-
@state = :any
|
|
38
|
-
break if @cfg_name == name
|
|
39
|
-
else
|
|
40
|
-
next
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def read_nmethod
|
|
46
|
-
raise unless @state == :any
|
|
47
|
-
|
|
48
|
-
arch = nil
|
|
49
|
-
arch_width = nil
|
|
50
|
-
code = nil
|
|
51
|
-
comments = []
|
|
52
|
-
raise unless @reader.readline == "begin_nmethod\n"
|
|
53
|
-
|
|
54
|
-
loop do
|
|
55
|
-
line = @reader.readline("\n")
|
|
56
|
-
case line
|
|
57
|
-
when / Platform (.*) (.*) <\|\|@\n/
|
|
58
|
-
arch = Regexp.last_match(1)
|
|
59
|
-
arch_width = Regexp.last_match(2)
|
|
60
|
-
when / HexCode (.*) (.*) <\|\|@\n/
|
|
61
|
-
base = Regexp.last_match(1).to_i(16)
|
|
62
|
-
code = [Regexp.last_match(2)].pack('H*')
|
|
63
|
-
raise if arch.nil? || arch_width.nil?
|
|
64
|
-
|
|
65
|
-
code = Code.new(arch, arch_width, base, code)
|
|
66
|
-
when / Comment (\d*) (.*) <\|\|@\n/
|
|
67
|
-
offset = Regexp.last_match(1).to_i
|
|
68
|
-
comment = Regexp.last_match(2)
|
|
69
|
-
comments.push Comment.new(offset, comment)
|
|
70
|
-
when " <<<HexCodeFile\n"
|
|
71
|
-
next
|
|
72
|
-
when " HexCodeFile>>> <|@\n"
|
|
73
|
-
next
|
|
74
|
-
when "end_nmethod\n"
|
|
75
|
-
break
|
|
76
|
-
when / (.*) <\|\|@\n/
|
|
77
|
-
offset = -1
|
|
78
|
-
comment = Regexp.last_match(1)
|
|
79
|
-
comments.push Comment.new(offset, comment)
|
|
80
|
-
when / (.*)\n/
|
|
81
|
-
offset = -1
|
|
82
|
-
comment = Regexp.last_match(1)
|
|
83
|
-
comments.push Comment.new(offset, comment)
|
|
84
|
-
else
|
|
85
|
-
# In case anything was missed
|
|
86
|
-
raise 'There is currently no case for this line. Please open an issue so it can be addressed.'
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
NMethod.new(code, comments)
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
end
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
require 'stringio'
|
|
2
|
-
|
|
3
|
-
module Seafoam
|
|
4
|
-
module CFG
|
|
5
|
-
# Disassemble and print comments from cfg files
|
|
6
|
-
class Disassembler
|
|
7
|
-
def initialize(out)
|
|
8
|
-
@out = out
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def disassemble(nmethod, print_comments)
|
|
12
|
-
require_crabstone
|
|
13
|
-
|
|
14
|
-
comments = nmethod.comments
|
|
15
|
-
comments_n = 0
|
|
16
|
-
|
|
17
|
-
case [nmethod.code.arch, nmethod.code.arch_width]
|
|
18
|
-
when %w[AMD64 64]
|
|
19
|
-
crabstone_arch = [Crabstone::ARCH_X86, Crabstone::MODE_64]
|
|
20
|
-
else
|
|
21
|
-
raise "Unknown architecture #{nmethod.code.arch} and bit width #{nmethod.code.arch_width}"
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
cs = Crabstone::Disassembler.new(*crabstone_arch)
|
|
25
|
-
begin
|
|
26
|
-
cs.disasm(nmethod.code.code, nmethod.code.base).each do |i|
|
|
27
|
-
if print_comments
|
|
28
|
-
# Print comments associated to the instruction.
|
|
29
|
-
last_comment = i.address + i.bytes.length - nmethod.code.base
|
|
30
|
-
while comments_n < comments.length && comments[comments_n].offset < last_comment
|
|
31
|
-
if comments[comments_n].offset == -1
|
|
32
|
-
@out.printf("\t\t\t\t;%<comment>s\n", comment: comments[comments_n].comment)
|
|
33
|
-
else
|
|
34
|
-
@out.printf(
|
|
35
|
-
"\t\t\t\t;Comment %<loc>i:\t%<comment>s\n",
|
|
36
|
-
loc: comments[comments_n].offset,
|
|
37
|
-
comment: comments[comments_n].comment
|
|
38
|
-
)
|
|
39
|
-
end
|
|
40
|
-
comments_n += 1
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
# Print the instruction.
|
|
45
|
-
@out.printf(
|
|
46
|
-
"\t0x%<address>x:\t%<instruction>s\t%<details>s\n",
|
|
47
|
-
address: i.address,
|
|
48
|
-
instruction: i.mnemonic,
|
|
49
|
-
details: i.op_str
|
|
50
|
-
)
|
|
51
|
-
end
|
|
52
|
-
rescue StandardError => e
|
|
53
|
-
raise "Disassembly error: #{e.message}"
|
|
54
|
-
ensure
|
|
55
|
-
cs.close
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def require_crabstone
|
|
60
|
-
require 'crabstone'
|
|
61
|
-
rescue LoadError => e
|
|
62
|
-
if $DEBUG
|
|
63
|
-
raise e
|
|
64
|
-
else
|
|
65
|
-
raise 'Could not load Capstone - is it installed?'
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
end
|