dwarves 0.1.0 → 0.1.1
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/.rubocop.yml +4 -0
- data/README.md +37 -7
- data/bin/readelf +1 -1
- data/dwarves.gemspec +1 -1
- data/exe/dwarves +10 -10
- data/lib/dwarves/parser/4/ast.rb +102 -0
- data/lib/dwarves/parser/4/parser.rb +4 -4
- data/lib/dwarves/parser/4/transformer.rb +54 -0
- data/lib/dwarves/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 79492a5fd9500086eba68e2fe04ef72105f9e8cf72132cde00ce2cda180b30b5
|
|
4
|
+
data.tar.gz: 2bb7c214096e59f0cd83aecd0bca48b75970233b1691186bc4e5a1ebba378deb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 719c2e7c990ae149e8e945060dbd46f4440d917043b884b1b5818eee5b6d8a448fddd34f2922c0235d008d1a514cbaf35e53d013eec33b4ce01167eeaf25b3e5
|
|
7
|
+
data.tar.gz: e89dcc65262224f4b6cc3116bbe76d66c24bd08ddb4350262f104d9c3614381f39d6a3d82c126866f9ec0e66fc9c3c935f420377f4b50c7ccfbbeffa297eb481
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
|
@@ -12,8 +12,16 @@ Source code is avaiable under MIT license at https://github.com/jethrodaniel/dwa
|
|
|
12
12
|
|
|
13
13
|
## What it do
|
|
14
14
|
|
|
15
|
+
Parses DWARF format, as outputed by the following:
|
|
16
|
+
|
|
17
|
+
- `readelf --debug-dump=info`
|
|
18
|
+
- `objdump --dwarf=info`
|
|
19
|
+
|
|
15
20
|
```
|
|
16
|
-
λ
|
|
21
|
+
λ ./bin/setup
|
|
22
|
+
...
|
|
23
|
+
λ readelf --debug-dump=info spec/fixtures/c/build/example.so > spec/fixtures/out.dwarves
|
|
24
|
+
λ dwarves -T < spec/fixtures/out.dwarves | head
|
|
17
25
|
|
|
18
26
|
{
|
|
19
27
|
:compilation_unit_offset => "0x0"@66,
|
|
@@ -24,14 +32,28 @@ Source code is avaiable under MIT license at https://github.com/jethrodaniel/dwa
|
|
|
24
32
|
:pointer_size => "8"@164,
|
|
25
33
|
:dies => [
|
|
26
34
|
{
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
35
|
+
:depth => "0"@168,
|
|
36
|
+
...
|
|
37
|
+
λ dwarves < spec/fixtures/out.dwarves | head
|
|
38
|
+
|
|
39
|
+
Contents of the .debug_info section:
|
|
40
|
+
|
|
41
|
+
Compilation Unit @ offset 0x0:
|
|
42
|
+
Length: 0x112 (32-bit)
|
|
43
|
+
Version: 4
|
|
44
|
+
Abbrev Offset: 0x0
|
|
45
|
+
Pointer Size: 8
|
|
46
|
+
<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
|
|
47
|
+
<c> DW_AT_producer : (indirect string, offset: 0x91): GNU C11 7.4.0 -mtune=generic -march=x86-64 -g -fPIC -fstack-protector-strong
|
|
48
|
+
<10> DW_AT_language : 12 (ANSI C99)
|
|
32
49
|
...
|
|
33
50
|
```
|
|
34
51
|
|
|
52
|
+
## Future
|
|
53
|
+
|
|
54
|
+
- more than just `.debug_info` section
|
|
55
|
+
- parse object files with [rbelftools][2]
|
|
56
|
+
|
|
35
57
|
## Installation
|
|
36
58
|
|
|
37
59
|
```
|
|
@@ -51,10 +73,17 @@ rake doc # Generates documentation
|
|
|
51
73
|
rake install # Build and install dwarves-0.1.0.gem into system gems
|
|
52
74
|
rake install:local # Build and install dwarves-0.1.0.gem into system gems without network access
|
|
53
75
|
rake lint # Runs the linter
|
|
54
|
-
rake release[remote] # Create tag v0.1.0 and build and push dwarves-0.1.0.gem to
|
|
76
|
+
rake release[remote] # Create tag v0.1.0 and build and push dwarves-0.1.0.gem to 'https://rubygems.org'
|
|
55
77
|
rake test # Run tests
|
|
56
78
|
```
|
|
57
79
|
|
|
80
|
+
A good test for the parser is to parse its own input, since we reconstruct the
|
|
81
|
+
output when printing.
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
./bin/readelf | bundle exec ./exe/dwarves | bundle exec ./exe/dwarves
|
|
85
|
+
```
|
|
86
|
+
|
|
58
87
|
## Contributing
|
|
59
88
|
|
|
60
89
|
Bug reports and pull requests are welcome on GitHub at https://github.com/jethrodaniel/dwarves.
|
|
@@ -71,3 +100,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
|
71
100
|
- http://dwarfstd.org/doc/DWARF5.pdf
|
|
72
101
|
|
|
73
102
|
[1]: https://github.com/kschiess/parslet
|
|
103
|
+
[2]: https://github.com/david942j/rbelftools
|
data/bin/readelf
CHANGED
data/dwarves.gemspec
CHANGED
|
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
|
9
9
|
spec.email = ["jethrodaniel@gmail.com"]
|
|
10
10
|
|
|
11
11
|
spec.summary = <<~MSG
|
|
12
|
-
DWARF parser (only the
|
|
12
|
+
DWARF parser (only the .debug_info section for now).
|
|
13
13
|
MSG
|
|
14
14
|
spec.homepage = "https://github.com/jethrodaniel/dwarves"
|
|
15
15
|
spec.license = "MIT"
|
data/exe/dwarves
CHANGED
|
@@ -8,13 +8,15 @@ require "awesome_print"
|
|
|
8
8
|
require_relative "../lib/dwarves"
|
|
9
9
|
|
|
10
10
|
options = {
|
|
11
|
-
|
|
12
|
-
transform: false
|
|
11
|
+
transform: true
|
|
13
12
|
}
|
|
14
13
|
|
|
15
14
|
OptionParser.new do |opts|
|
|
15
|
+
# @todo support filenames instead of just stdin
|
|
16
16
|
opts.banner = <<~MSG
|
|
17
17
|
Usage: dwarves [options]... [file]...
|
|
18
|
+
|
|
19
|
+
Works the same as `readelf --debug-dump=info`
|
|
18
20
|
MSG
|
|
19
21
|
|
|
20
22
|
opts.on "-h", "--help", "print this help" do
|
|
@@ -27,20 +29,18 @@ OptionParser.new do |opts|
|
|
|
27
29
|
exit
|
|
28
30
|
end
|
|
29
31
|
|
|
30
|
-
opts.on "-
|
|
31
|
-
options[:transform] =
|
|
32
|
-
options[:json] = true
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
opts.on "-t", "--transform", "transform the parser output" do
|
|
36
|
-
options[:transform] = true
|
|
32
|
+
opts.on "-T", "--no-transform", "don't transform the parser output" do
|
|
33
|
+
options[:transform] = false
|
|
37
34
|
end
|
|
38
35
|
end.parse!
|
|
39
36
|
|
|
40
37
|
begin
|
|
41
38
|
tree = Dwarves::Parser[4].new.parse ARGF.read
|
|
42
39
|
|
|
43
|
-
|
|
40
|
+
if options[:transform]
|
|
41
|
+
puts Dwarves::Parser[4].new.apply(tree)
|
|
42
|
+
exit
|
|
43
|
+
end
|
|
44
44
|
|
|
45
45
|
ap tree, indent: 2, index: false
|
|
46
46
|
rescue Parslet::ParseFailed => e
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Dwarves
|
|
4
|
+
module Parser
|
|
5
|
+
class AST; end
|
|
6
|
+
|
|
7
|
+
# The basic DWARF descriptive unit, the Debugging Information Entry (DIE).
|
|
8
|
+
#
|
|
9
|
+
# This is a node in the parse tree that DWARF generates.
|
|
10
|
+
#
|
|
11
|
+
# These represent types, variables, and functions.
|
|
12
|
+
#
|
|
13
|
+
class DIE < AST
|
|
14
|
+
attr_reader *%i[
|
|
15
|
+
tag
|
|
16
|
+
children
|
|
17
|
+
siblings
|
|
18
|
+
attributes
|
|
19
|
+
address
|
|
20
|
+
depth
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
def initialize opts = {}
|
|
24
|
+
@tag = opts[:tag]
|
|
25
|
+
@children = opts[:children] || []
|
|
26
|
+
@siblings = opts[:siblings] || []
|
|
27
|
+
@attributes = opts[:attributes] || []
|
|
28
|
+
@address = opts[:address]
|
|
29
|
+
@depth = opts[:depth]
|
|
30
|
+
@abbrev_number = opts[:abbrev_number]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def to_s
|
|
34
|
+
attrs = if @attributes.empty?
|
|
35
|
+
""
|
|
36
|
+
else
|
|
37
|
+
%(\n#{@attributes.map(&:to_s).join("\n")})
|
|
38
|
+
end
|
|
39
|
+
depth_addr =
|
|
40
|
+
"<#{@depth}><#{@address}>: Abbrev Number: #{@abbrev_number}"
|
|
41
|
+
|
|
42
|
+
if @tag
|
|
43
|
+
" #{depth_addr} (#{@tag})#{attrs}"
|
|
44
|
+
else
|
|
45
|
+
" #{depth_addr}#{attrs}"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Compilation Unit
|
|
51
|
+
#
|
|
52
|
+
# @todo clean this up
|
|
53
|
+
class CU < AST
|
|
54
|
+
attr_reader *%i[
|
|
55
|
+
compilation_unit_offset
|
|
56
|
+
length
|
|
57
|
+
architecture
|
|
58
|
+
version
|
|
59
|
+
abbrev_offset
|
|
60
|
+
pointer_size
|
|
61
|
+
dies
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
def initialize opts = {}
|
|
65
|
+
@compilation_unit_offset = opts[:compilation_unit_offset]
|
|
66
|
+
@length = opts[:length]
|
|
67
|
+
@architecture = opts[:architecture]
|
|
68
|
+
@version = opts[:version]
|
|
69
|
+
@abbrev_offset = opts[:abbrev_offset]
|
|
70
|
+
@pointer_size = opts[:pointer_size]
|
|
71
|
+
@dies = opts[:dies] || []
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def to_s
|
|
75
|
+
"Contents of the .debug_info section:\n" \
|
|
76
|
+
"\n" \
|
|
77
|
+
" Compilation Unit @ offset #{@compilation_unit_offset}:\n" \
|
|
78
|
+
" Length: #{@length} (#{@architecture})\n" \
|
|
79
|
+
" Version: #{@version}\n" \
|
|
80
|
+
" Abbrev Offset: #{@abbrev_offset}\n" \
|
|
81
|
+
" Pointer Size: #{@pointer_size}\n" \
|
|
82
|
+
"#{@dies.map(&:to_s).join("\n")}\n\n"
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
class Attribute < AST
|
|
87
|
+
attr_reader :name, :value, :address
|
|
88
|
+
|
|
89
|
+
def initialize opts = {}
|
|
90
|
+
@name = opts[:name]
|
|
91
|
+
@value = opts[:value]
|
|
92
|
+
@address = opts[:address]
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def to_s
|
|
96
|
+
formatted_address = "<#{@address}>".ljust(3, " ")
|
|
97
|
+
formatted_name = name.to_s.ljust(18, " ") + ":"
|
|
98
|
+
" #{formatted_address} #{formatted_name} #{@value}"
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
@@ -103,13 +103,13 @@ module Dwarves
|
|
|
103
103
|
rule :die_header do
|
|
104
104
|
_ >>
|
|
105
105
|
str("<") >>
|
|
106
|
-
integer.as(:
|
|
106
|
+
integer.as(:depth) >>
|
|
107
107
|
str(">") >>
|
|
108
108
|
str("<") >>
|
|
109
109
|
word.as(:address) >>
|
|
110
110
|
str(">") >>
|
|
111
111
|
str(": Abbrev Number: ") >>
|
|
112
|
-
integer.as(:
|
|
112
|
+
integer.as(:abbrev_number) >>
|
|
113
113
|
(
|
|
114
114
|
_ >>
|
|
115
115
|
str("(") >>
|
|
@@ -122,7 +122,7 @@ module Dwarves
|
|
|
122
122
|
# @!method die_body
|
|
123
123
|
#
|
|
124
124
|
# @example
|
|
125
|
-
# <1><2d>: Abbrev Number: 2 (
|
|
125
|
+
# <1><2d>: Abbrev Number: 2 (abbrev_number)
|
|
126
126
|
# <2e> DW_AT_byte_size : 4
|
|
127
127
|
# <2f> DW_AT_encoding : 5 (signed)
|
|
128
128
|
# <30> DW_AT_name : int
|
|
@@ -137,7 +137,7 @@ module Dwarves
|
|
|
137
137
|
rule :attribute do
|
|
138
138
|
_ >>
|
|
139
139
|
str("<") >>
|
|
140
|
-
word.as(:
|
|
140
|
+
word.as(:address) >>
|
|
141
141
|
str(">") >>
|
|
142
142
|
_ >>
|
|
143
143
|
word.as(:name) >>
|
|
@@ -2,11 +2,65 @@
|
|
|
2
2
|
|
|
3
3
|
require "parslet"
|
|
4
4
|
|
|
5
|
+
require "dwarves/parser/4/ast"
|
|
6
|
+
|
|
5
7
|
module Dwarves
|
|
6
8
|
module Parser
|
|
7
9
|
# Transformer to turn the parser output into meaningful classes
|
|
8
10
|
#
|
|
9
11
|
class V4Transformer < Parslet::Transform
|
|
12
|
+
rule(
|
|
13
|
+
compilation_unit_offset: simple(:c),
|
|
14
|
+
length: simple(:l),
|
|
15
|
+
architecture: simple(:arch),
|
|
16
|
+
version: simple(:v),
|
|
17
|
+
abbrev_offset: simple(:ab),
|
|
18
|
+
pointer_size: simple(:p),
|
|
19
|
+
dies: subtree(:d)
|
|
20
|
+
) do
|
|
21
|
+
Dwarves::Parser::CU.new \
|
|
22
|
+
compilation_unit_offset: c,
|
|
23
|
+
length: l,
|
|
24
|
+
architecture: arch,
|
|
25
|
+
version: v,
|
|
26
|
+
abbrev_offset: ab,
|
|
27
|
+
pointer_size: p,
|
|
28
|
+
dies: d
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
rule(
|
|
32
|
+
depth: simple(:d),
|
|
33
|
+
address: simple(:a),
|
|
34
|
+
abbrev_number: simple(:an),
|
|
35
|
+
attributes: subtree(:attrs)
|
|
36
|
+
) do
|
|
37
|
+
Dwarves::Parser::DIE.new \
|
|
38
|
+
attributes: attrs,
|
|
39
|
+
address: a,
|
|
40
|
+
abbrev_number: an,
|
|
41
|
+
depth: d
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
rule(
|
|
45
|
+
depth: simple(:d),
|
|
46
|
+
address: simple(:a),
|
|
47
|
+
abbrev_number: simple(:an),
|
|
48
|
+
type: simple(:t),
|
|
49
|
+
attributes: subtree(:attrs)
|
|
50
|
+
) do
|
|
51
|
+
Dwarves::Parser::DIE.new \
|
|
52
|
+
tag: t,
|
|
53
|
+
children: [],
|
|
54
|
+
siblings: [],
|
|
55
|
+
attributes: attrs,
|
|
56
|
+
address: a,
|
|
57
|
+
abbrev_number: an,
|
|
58
|
+
depth: d
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
rule address: simple(:a), name: simple(:n), description: simple(:d) do
|
|
62
|
+
Dwarves::Parser::Attribute.new name: n, value: d, address: a
|
|
63
|
+
end
|
|
10
64
|
end
|
|
11
65
|
end
|
|
12
66
|
end
|
data/lib/dwarves/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dwarves
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mark Delk
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2019-11-
|
|
11
|
+
date: 2019-11-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: awesome_print
|
|
@@ -176,6 +176,7 @@ files:
|
|
|
176
176
|
- lib/dwarves.rb
|
|
177
177
|
- lib/dwarves/parser.rb
|
|
178
178
|
- lib/dwarves/parser/4.rb
|
|
179
|
+
- lib/dwarves/parser/4/ast.rb
|
|
179
180
|
- lib/dwarves/parser/4/parser.rb
|
|
180
181
|
- lib/dwarves/parser/4/transformer.rb
|
|
181
182
|
- lib/dwarves/parser/basic_rules.rb
|
|
@@ -206,5 +207,5 @@ requirements: []
|
|
|
206
207
|
rubygems_version: 3.0.3
|
|
207
208
|
signing_key:
|
|
208
209
|
specification_version: 4
|
|
209
|
-
summary: DWARF parser (only the
|
|
210
|
+
summary: DWARF parser (only the .debug_info section for now).
|
|
210
211
|
test_files: []
|