ruby-elf 1.0.7 → 1.0.8

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.
@@ -0,0 +1,64 @@
1
+ Ruby-Elf
2
+ ========
3
+
4
+ [![Flattr this!](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/thing/27866/Ruby-Elf)
5
+
6
+ Ruby-Elf is a pure-Ruby library for parse and fetch information about
7
+ ELF format used by Linux, FreeBSD, Solaris and other Unix-like
8
+ operating systems, and include a set of analysis tools helpful for
9
+ both optimisations and verification of compiled ELF files.
10
+
11
+ The library allows access to all the details of the ELF files (class,
12
+ type, architecture OS), and also implements Ruby-style access to the
13
+ most important sections in ELF files, such as symbol and string
14
+ tables, as well as dynamic information. Furthermore it implements
15
+ support for accessing extensions specifics for instance to the GNU
16
+ loader such as symbol version information.
17
+
18
+ Tools
19
+ -----
20
+
21
+ To complement the library raw access, the project also ships with a
22
+ number of tools, designed to analyse compiled code, in either
23
+ relocated object or final (executable or shared object) form. These
24
+ include both optimisation and verification tools:
25
+
26
+ * `cowstats`: allows identification and assessment of CoW data
27
+ objects inside ELF relocatable files. Should be used to reduce the
28
+ memory impact of a shared library used by many processes on the
29
+ system.
30
+
31
+ * `rbelf-size`: implements an alternative approach for the size
32
+ command available on standard Unix systems (as provided by binutils
33
+ or elfutils packages in most Linux distributions), that focus more
34
+ on relocation caused by PIC than the actual shared memory sizes.
35
+
36
+ * `rbelf-nm`: implements a quasi-compatible `nm(1)` command, more
37
+ resilient than GNU `nm` and more informative than the elfutils
38
+ variant.
39
+
40
+ * `verify-lfs`: checks executables and shared objects, or
41
+ alternatively relocatable object files, for LFS compliancy,
42
+ reporting those that don't make use of the largefile-compatible
43
+ interfaces or that mix old and new ones.
44
+
45
+ * `elfgrep`: looks for defined or required symbols in dynamic
46
+ executables and shared objects, with a command syntax similar to
47
+ the standard `grep` tool.
48
+
49
+ License
50
+ -------
51
+
52
+ Due to derivation, library and tools are released under the GNU GPL-2
53
+ license, or later. See the [`COPYING`](COPYING) file for the complete
54
+ text.
55
+
56
+ Resources
57
+ ---------
58
+
59
+ You can find the source code for the package at
60
+ [GitHub](https://github.com/Flameeyes/ruby-elf) — previously at
61
+ [Gitorious](https://gitorious.org/ruby-elf).
62
+
63
+ Development and file releases are on
64
+ [Rubyforge](http://rubyforge.org/projects/ruby-elf/).
data/lib/elf.rb CHANGED
@@ -29,7 +29,7 @@ require 'elf/file'
29
29
  require 'elf/section'
30
30
 
31
31
  module Elf
32
- VERSION = "1.0.7"
32
+ VERSION = "1.0.8"
33
33
 
34
34
  MagicString = "\177ELF"
35
35
 
@@ -0,0 +1,29 @@
1
+ # -*- ruby -*- coding: utf-8 -*-
2
+ $:.unshift(File.dirname(__FILE__) + '/lib')
3
+ require 'elf'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'ruby-elf'
7
+ s.version = Elf::VERSION
8
+ s.summary = "Pure Ruby ELF file parser and utilities"
9
+
10
+ s.requirements << 'none'
11
+ s.require_path = 'lib'
12
+ s.homepage = "http://www.flameeyes.eu/projects/ruby-elf"
13
+ s.license = "GPL-2 or later"
14
+ s.author = "Diego Elio Pettenò"
15
+ s.email = "flameeyes@flameeyes.eu"
16
+
17
+ s.description = <<EOF
18
+ Ruby-Elf is a pure-Ruby library for parse and fetch information about
19
+ ELF format used by Linux, FreeBSD, Solaris and other Unix-like
20
+ operating systems, and include a set of analysis tools helpful for
21
+ both optimisations and verification of compiled ELF files.
22
+ EOF
23
+
24
+ s.files = %w{COPYING README.md DONATING ruby-elf.gemspec}
25
+ s.files += Dir['lib/**/*.rb']
26
+ s.files += Dir['bin/**/*.rb']
27
+ s.files += Dir['tools/**/*.rb']
28
+ s.files += Dir['manpages/*.1']
29
+ end
metadata CHANGED
@@ -1,120 +1,84 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: ruby-elf
3
- version: !ruby/object:Gem::Version
4
- hash: 25
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.8
5
5
  prerelease:
6
- segments:
7
- - 1
8
- - 0
9
- - 7
10
- version: 1.0.7
11
6
  platform: ruby
12
- authors:
13
- - "Diego Elio Petten\xC3\xB2"
7
+ authors:
8
+ - Diego Elio Pettenò
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2012-12-27 00:00:00 Z
12
+ date: 2013-02-20 00:00:00.000000000 Z
19
13
  dependencies: []
14
+ description: ! 'Ruby-Elf is a pure-Ruby library for parse and fetch information about
20
15
 
21
- description: |
22
- Ruby-Elf is a pure-Ruby library for parse and fetch information about
23
16
  ELF format used by Linux, FreeBSD, Solaris and other Unix-like
17
+
24
18
  operating systems, and include a set of analysis tools helpful for
19
+
25
20
  both optimisations and verification of compiled ELF files.
26
21
 
22
+ '
27
23
  email: flameeyes@flameeyes.eu
28
- executables:
29
- - verify-lfs
30
- - rbelf-size
31
- - missingstatic
32
- - rbelf-nm
33
- - elfgrep
34
- - cowstats
35
- - rbelf-read
24
+ executables: []
36
25
  extensions: []
37
-
38
26
  extra_rdoc_files: []
39
-
40
- files:
27
+ files:
41
28
  - COPYING
29
+ - README.md
42
30
  - DONATING
43
- - bin/cowstats
44
- - bin/elfgrep
45
- - bin/missingstatic
46
- - bin/rbelf-nm
47
- - bin/rbelf-read
48
- - bin/rbelf-size
49
- - bin/verify-lfs
50
- - extras/README.extras
51
- - extras/bindings-parsers.rb
31
+ - ruby-elf.gemspec
52
32
  - lib/bytestream-reader.rb
53
33
  - lib/elf.rb
54
- - lib/elf/dynamic.rb
34
+ - lib/elf/symbol.rb
55
35
  - lib/elf/file.rb
56
36
  - lib/elf/gnu.rb
57
- - lib/elf/section.rb
58
- - lib/elf/stringtable.rb
59
37
  - lib/elf/sunw.rb
60
- - lib/elf/symbol.rb
61
- - lib/elf/symboltable.rb
38
+ - lib/elf/section.rb
62
39
  - lib/elf/tools.rb
63
- - lib/elf/utils/loader.rb
40
+ - lib/elf/dynamic.rb
64
41
  - lib/elf/utils/offsettable.rb
65
42
  - lib/elf/utils/pool.rb
43
+ - lib/elf/utils/loader.rb
44
+ - lib/elf/stringtable.rb
66
45
  - lib/elf/value.rb
67
- - manpages/cowstats.1.xml
68
- - manpages/elfgrep.1.xml
69
- - manpages/missingstatic.1.xml
70
- - manpages/rbelf-nm.1.xml
71
- - manpages/rbelf-size.1.xml
72
- - manpages/verify-lfs.1.xml
46
+ - lib/elf/symboltable.rb
73
47
  - tools/assess_duplicate_save.rb
74
48
  - tools/link-collisions/harvest.rb
75
- - tools/link-collisions/known-broken
76
- - tools/link-collisions/multimplementations
77
49
  - tools/link-collisions/suppress.rb
78
- - tools/link-collisions/suppressions
79
50
  - tools/rbelf-lddtree.rb
80
- - manpages/missingstatic.1
51
+ - manpages/rbelf-nm.1
81
52
  - manpages/verify-lfs.1
53
+ - manpages/rbelf-size.1
54
+ - manpages/missingstatic.1
82
55
  - manpages/elfgrep.1
83
56
  - manpages/cowstats.1
84
- - manpages/rbelf-size.1
85
- - manpages/rbelf-nm.1
86
57
  homepage: http://www.flameeyes.eu/projects/ruby-elf
87
- licenses:
58
+ licenses:
88
59
  - GPL-2 or later
89
60
  post_install_message:
90
61
  rdoc_options: []
91
-
92
- require_paths:
62
+ require_paths:
93
63
  - lib
94
- required_ruby_version: !ruby/object:Gem::Requirement
64
+ required_ruby_version: !ruby/object:Gem::Requirement
95
65
  none: false
96
- requirements:
97
- - - ">="
98
- - !ruby/object:Gem::Version
99
- hash: 3
100
- segments:
101
- - 0
102
- version: "0"
103
- required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
71
  none: false
105
- requirements:
106
- - - ">="
107
- - !ruby/object:Gem::Version
108
- hash: 3
109
- segments:
110
- - 0
111
- version: "0"
112
- requirements:
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ requirements:
113
77
  - none
114
- rubyforge_project: ruby-elf
78
+ rubyforge_project:
115
79
  rubygems_version: 1.8.24
116
80
  signing_key:
117
81
  specification_version: 3
118
82
  summary: Pure Ruby ELF file parser and utilities
119
83
  test_files: []
120
-
84
+ has_rdoc:
@@ -1,266 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # -*- mode: ruby; coding: utf-8 -*-
3
- # Copyright © 2008-2010 Diego Elio Pettenò <flameeyes@flameeyes.eu>
4
- #
5
- # This program is free software; you can redistribute it and/or modify
6
- # it under the terms of the GNU General Public License as published by
7
- # the Free Software Foundation; either version 2 of the License, or
8
- # (at your option) any later version.
9
- #
10
- # This program is distributed in the hope that it will be useful,
11
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- # GNU General Public License for more details.
14
- #
15
- # You should have received a copy of the GNU General Public License
16
- # along with this generator; if not, write to the Free Software
17
- # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
-
19
- # simple script to check for variables in copy-on-write sections
20
-
21
- require 'elf/tools'
22
-
23
- module Elf::Tools
24
- class CoWStats < Elf::Tool
25
-
26
- def self.initialize
27
- super
28
- @options |= [
29
- # Only show statistics for the various files
30
- ["--statistics", "-s", GetoptLong::NO_ARGUMENT],
31
- # Show the total size of COW pages
32
- ["--total", "-t", GetoptLong::NO_ARGUMENT],
33
- # Ignore C++ "false positives" (vtables and typeinfo)
34
- ["--ignore-cxx", "-x", GetoptLong::NO_ARGUMENT ],
35
- # Ignore Profiling false positives
36
- ["--ignore-profiling", "-p", GetoptLong::NO_ARGUMENT ],
37
- # Ignore .data.rel.ro relocated constants
38
- ["--ignore-data-rel-ro", "-r", GetoptLong::NO_ARGUMENT ],
39
- # Decide sorting column
40
- ["--sort-by", "-S", GetoptLong::REQUIRED_ARGUMENT ]
41
- ]
42
-
43
- @statistics = false
44
- @total = false
45
- @ignore_cxx = false
46
- @ignore_profiling = false
47
- @ignore_data_rel_ro = false
48
-
49
- @results_sorter = Proc.new do |x, y|
50
- # 0 is the filename
51
- x[0] <=> y[0]
52
- end
53
-
54
- @files_info = {}
55
-
56
- @data_total = 0
57
- @bss_total = 0
58
- @rel_total = 0
59
- @relro_total = 0
60
- end
61
-
62
- def self.sort_by_cb(column)
63
- case column
64
- when '.bss'
65
- @results_sorter = Proc.new do |x, y|
66
- x[1][:bss_size] <=> y[1][:bss_size]
67
- end
68
- when '.data'
69
- @results_sorter = Proc.new do |x, y|
70
- x[1][:data_size] <=> y[1][:data_size]
71
- end
72
- when '.data.rel'
73
- @results_sorter = Proc.new do |x, y|
74
- x[1][:rel_size] <=> y[1][:rel_size]
75
- end
76
- when '.data.rel.ro'
77
- @results_sorter = Proc.new do |x, y|
78
- x[1][:relro_size] <=> y[1][:relro_size]
79
- end
80
- else
81
- puterror "invalid sort column: #{column}"
82
- exit -1
83
- end
84
- end
85
-
86
- def self.analysis(file)
87
- data_vars = []
88
- data_size = 0
89
- bss_vars = []
90
- bss_size = 0
91
- rel_vars = []
92
- rel_size = 0
93
- relro_vars = []
94
- relro_size = 0
95
-
96
- Elf::File.open(file) do |elf|
97
- if elf.type != Elf::File::Type::Rel
98
- putnotice "#{file}: not an object file"
99
- next
100
- end
101
- if not elf.has_section?(".symtab")
102
- putnotice "#{file}: no .symtab section found"
103
- next
104
- end
105
-
106
- elf['.symtab'].each do |symbol|
107
- # Ignore undefined, absolute and common symbols.
108
- next unless symbol.section.is_a? Elf::Section
109
- # When the symbol name is empty, it refers to the
110
- # section itself.
111
- next if symbol.name == ""
112
-
113
- # Ignore C++ vtables and other symbols when requested
114
- next if @ignore_cxx and symbol.name =~ /^_ZT[VI](N[0-9]+[A-Z_].*)*[0-9]+[A-Z_].*/
115
- # Ignore profiling symbols when requested by user
116
- next if @ignore_profiling and symbol.name =~ /^__gcov_/
117
-
118
- # If the section is NoBits, then it's .bss or equivalent, handle
119
- # and skip right away.
120
- if symbol.section.type == Elf::Section::Type::NoBits
121
- bss_vars << symbol unless @statistics
122
- bss_size += symbol.size
123
- next
124
- end
125
-
126
- # Ignore executable code (.text, .init, .fini)
127
- next if symbol.section.flags.include? Elf::Section::Flags::ExecInstr
128
- # Ignore read-only sections (.rodata)
129
- next unless symbol.section.flags.include? Elf::Section::Flags::Write
130
- # Ignore non-allocated sections (all data sections are allocated)
131
- next unless symbol.section.flags.include? Elf::Section::Flags::Alloc
132
-
133
- # Until I can find a way to distinguish between relocated and
134
- # non-relocated sections, still use the name to choose between
135
- # them. If the name is not in this list, at least warn now
136
- # about it.
137
- #
138
- # The “l” prefix is used by Sun's compiler for x64-specific
139
- # sections that can hold over 2GiB of data. They don't change
140
- # for what we're concerned.
141
- case symbol.section.name
142
- when /^\.l?data\.rel\.ro(\..*)?/
143
- unless @inore_data_rel_ro
144
- relro_vars << symbol unless @statistics
145
- relro_size += symbol.size
146
- end
147
- when /^\.l?data\.rel(\..*)?/, /^\.picdata/
148
- rel_vars << symbol unless @statistics
149
- rel_size += symbol.size
150
- when /^\.l?t?data(\.local)?(\..*)?/
151
- data_vars << symbol unless @statistics
152
- data_size += symbol.size
153
- else
154
- puterror "symbol #{symbol.name} in unknown section #{symbol.section.name}"
155
- end
156
- end
157
-
158
- end
159
-
160
- return unless (data_size + bss_size + rel_size + relro_size ) > 0
161
-
162
- if @total
163
- @data_total += data_size
164
- @bss_total += bss_size
165
- @rel_total += rel_size
166
- @relro_total += relro_size
167
- end
168
-
169
- if @statistics
170
- @files_info[file] = {
171
- :data_size => data_size,
172
- :bss_size => bss_size,
173
- :rel_size => rel_size,
174
- :relro_size => relro_size
175
- }
176
- return
177
- end
178
-
179
- @output_mutex.synchronize do
180
- puts "Processing file #{file}"
181
-
182
- if bss_vars.length > 0
183
- puts " The following variables aren't initialised (Copy-On-Write):"
184
- bss_vars.each do |sym|
185
- puts " #{sym} (size: #{sym.size})"
186
- end
187
- end
188
-
189
- if data_vars.length > 0
190
- puts " The following variables are writable (Copy-On-Write):"
191
- data_vars.each do |sym|
192
- puts " #{sym} (size: #{sym.size})"
193
- end
194
- end
195
-
196
- if rel_vars.length > 0
197
- puts " The following variables need runtime relocation (Copy-On-Write):"
198
- rel_vars.each do |sym|
199
- puts " #{sym} (size: #{sym.size})"
200
- end
201
- end
202
-
203
- if relro_vars.length > 0
204
- puts " The following constants need runtime relocation (Prelinkable Copy-On-Write):"
205
- relro_vars.each do |sym|
206
- puts " #{sym} (size: #{sym.size})"
207
- end
208
- end
209
-
210
- if @total
211
- puts " Total non-initialised variables size: #{bss_size}" unless bss_size == 0
212
- puts " Total writable variables size: #{data_size}" unless data_size == 0
213
- puts " Total variables needing runtime relocation size: #{rel_size}" unless rel_size == 0
214
- unless @ignore_data_rel_ro
215
- puts " Total constants needing runtime relocation size: #{relro_size}" unless relro_size == 0
216
- end
217
- end
218
- end
219
- end
220
-
221
- def self.results
222
- if @statistics
223
- file_lengths = ["File name".length]
224
- bss_lengths = [".bss size".length]
225
- data_lengths = [".data size".length]
226
- rel_lengths = [".data.rel size".length]
227
- relro_lengths = [".data.rel.ro size".length] unless @no_datalrero
228
- @files_info.each_pair do |file, info|
229
- file_lengths << file.length
230
- bss_lengths << info[:bss_size] .to_s.length
231
- data_lengths << info[:data_size].to_s.length
232
- rel_lengths << info[:rel_size] .to_s.length
233
- relro_lengths<< info[:relro_size] .to_s.length
234
- end
235
-
236
- maxlen = file_lengths.max
237
- max_bss_len = bss_lengths .max
238
- max_data_len = data_lengths.max
239
- max_rel_len = rel_lengths .max
240
- max_relro_len= relro_lengths .max
241
-
242
- datarelro_header = @ignore_data_rel_ro ? "" : " | #{'.data.rel.ro size'.ljust max_relro_len}"
243
- puts "#{'File name'.ljust maxlen} | #{'.bss size'.ljust max_data_len} | #{'.data size'.ljust max_data_len} | #{'.data.rel size'.ljust max_rel_len}#{datarelro_header}"
244
-
245
- (@files_info.sort &@results_sorter).each do |file, info|
246
- datarelro_line = @ignore_data_rel_ro ? "" : " #{info[:relro_size].to_s.rjust max_relro_len}"
247
- puts "#{file.ljust maxlen} #{info[:bss_size].to_s.rjust max_bss_len} #{info[:data_size].to_s.rjust max_data_len} #{info[:rel_size].to_s.rjust max_rel_len}#{datarelro_line}"
248
- end
249
- end
250
-
251
- if @total
252
- data_total_real = @data_total > 0 ? ((@data_total/4096) + (@data_total % 4096 ? 1 : 0)) * 4096 : 0
253
- bss_total_real = @bss_total > 0 ? ((@bss_total/4096) + (@bss_total % 4096 ? 1 : 0)) * 4096 : 0
254
- rel_total_real = @rel_total > 0 ? ((@rel_total/4096) + (@rel_total % 4096 ? 1 : 0)) * 4096 : 0
255
- relro_total_real = @relro_total > 0 ? ((@relro_total/4096) + (@relro_total % 4096 ? 1 : 0)) * 4096 : 0
256
-
257
- puts "Totals:"
258
- puts " #{@bss_total} (#{bss_total_real} \"real\") bytes of non-initialised variables."
259
- puts " #{@data_total} (#{data_total_real} \"real\") bytes of writable variables."
260
- puts " #{@rel_total} (#{rel_total_real} \"real\") bytes of variables needing runtime relocation."
261
- puts " #{@relro_total} (#{relro_total_real} \"real\") bytes of constants needing runtime relocation." unless @no_datalrero
262
- puts " Total #{@data_total+@bss_total+@rel_total+@relro_total} (#{data_total_real+bss_total_real+rel_total_real+relro_total_real} \"real\") bytes of variables in copy-on-write sections"
263
- end
264
- end
265
- end
266
- end