ruby-elf 1.0.7 → 1.0.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -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