ruby-elf 1.0.3 → 1.0.4
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.
- data/bin/cowstats +217 -215
- data/bin/elfgrep +165 -144
- data/bin/missingstatic +74 -73
- data/bin/rbelf-read +111 -0
- data/bin/rbelf-size +144 -107
- data/bin/verify-lfs +92 -87
- data/lib/elf.rb +1 -1
- data/lib/elf/dynamic.rb +1 -1
- data/lib/elf/file.rb +30 -3
- data/lib/elf/gnu.rb +3 -3
- data/lib/elf/section.rb +85 -40
- data/lib/elf/symbol.rb +19 -13
- data/lib/elf/symboltable.rb +1 -1
- data/lib/elf/tools.rb +198 -164
- data/manpages/cowstats.1 +1 -4
- data/manpages/elfgrep.1 +10 -9
- data/manpages/elfgrep.1.xml +9 -7
- data/manpages/missingstatic.1 +1 -4
- data/manpages/rbelf-size.1 +13 -15
- data/manpages/rbelf-size.1.xml +25 -14
- data/manpages/verify-lfs.1 +1 -4
- data/tools/link-collisions/harvest.rb +262 -297
- data/tools/link-collisions/multimplementations +17 -3
- data/tools/link-collisions/suppressions +30 -26
- metadata +6 -6
- data/tools/link-collisions/analyse.rb +0 -57
- data/tools/readelf-d.rb +0 -79
data/bin/rbelf-read
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- mode: ruby; coding: utf-8 -*-
|
3
|
+
# Copyright © 2008-2011 Diego E. "Flameeyes" Pettenò <flameeyes@gmail.com>
|
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
|
+
# proof-of-concept reimplementation of readelf(1)
|
20
|
+
|
21
|
+
require 'elf/tools'
|
22
|
+
|
23
|
+
module Elf::Tools
|
24
|
+
class ReadElf < Elf::Tool
|
25
|
+
def self.initialize
|
26
|
+
super
|
27
|
+
@options |= [
|
28
|
+
["--all", "-a", GetoptLong::NO_ARGUMENT],
|
29
|
+
["--section-headers", "-S", GetoptLong::NO_ARGUMENT],
|
30
|
+
["--dynamic", "-d", GetoptLong::NO_ARGUMENT],
|
31
|
+
]
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.all_cb
|
35
|
+
@section_headers = true
|
36
|
+
@dynamic = true
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.after_options
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.analysis(file)
|
43
|
+
elf = Elf::File.open(file)
|
44
|
+
|
45
|
+
@addrsize = (elf.elf_class == Elf::Class::Elf32 ? 8 : 16)
|
46
|
+
|
47
|
+
@output_mutex.synchronize {
|
48
|
+
printf("\nFile: %s\n", file) if @targets.size != 1
|
49
|
+
read_sections(elf) if @section_headers
|
50
|
+
read_dynamic(elf) if @dynamic
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.read_sections(elf)
|
55
|
+
printf("There are %d section headers, starting at offset 0x%x:\n\nSection Headers:\n",
|
56
|
+
elf.sections, elf.shoff)
|
57
|
+
|
58
|
+
printf("[Nr] Name Type Addr Off Size ES Flags Lk Inf Al\n")
|
59
|
+
|
60
|
+
elf.each_section do |section|
|
61
|
+
printf("[%2d] %s %s %0#{@addrsize}x %08x %08x %2d %s %2d %3d %2d\n",
|
62
|
+
section.index,
|
63
|
+
section.name.ljust(20),
|
64
|
+
section.type.mnemonic.upcase.ljust(13),
|
65
|
+
section.addr, section.offset, section.size, section.entsize,
|
66
|
+
section.flags_s.ljust(5), section.link.to_i, section.info, section.addralign)
|
67
|
+
end
|
68
|
+
|
69
|
+
printf("\n")
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.read_dynamic(elf)
|
73
|
+
dynsection = elf[".dynamic"]
|
74
|
+
|
75
|
+
if dynsection.nil?
|
76
|
+
printf("\nThere is no dynamic section in this file.\n")
|
77
|
+
return
|
78
|
+
end
|
79
|
+
|
80
|
+
printf("\nDynamic section at offset 0x%x contains %d entries:\n",
|
81
|
+
dynsection.offset, dynsection.size)
|
82
|
+
printf(" Tag Type Name/Value\n")
|
83
|
+
|
84
|
+
dynsection.each_entry do |entry|
|
85
|
+
case entry.type
|
86
|
+
when Elf::Dynamic::Type::Needed
|
87
|
+
val = "Shared library: [#{entry.parsed}]"
|
88
|
+
when Elf::Dynamic::Type::Auxiliary
|
89
|
+
val = "Auxiliary library: [#{entry.parsed}]"
|
90
|
+
when Elf::Dynamic::Type::SoName
|
91
|
+
val = "Library soname: [#{entry.parsed}]"
|
92
|
+
when Elf::Dynamic::Type::StrSz, Elf::Dynamic::Type::SymEnt,
|
93
|
+
Elf::Dynamic::Type::PltRelSz, Elf::Dynamic::Type::RelASz,
|
94
|
+
Elf::Dynamic::Type::RelAEnt
|
95
|
+
|
96
|
+
val = "#{entry.value} (bytes)"
|
97
|
+
when Elf::Dynamic::Type::VerDefNum, Elf::Dynamic::Type::VerNeedNum, Elf::Dynamic::Type::RelACount
|
98
|
+
val = entry.value
|
99
|
+
when Elf::Dynamic::Type::GNUPrelinked
|
100
|
+
val = entry.parsed.getutc.strftime('%Y-%m-%dT%H:%M:%S')
|
101
|
+
else
|
102
|
+
val = sprintf("0x%x", entry.value)
|
103
|
+
end
|
104
|
+
|
105
|
+
printf(" 0x%016x %-20s %s\n", entry.type.to_i, "(#{entry.type.to_s})", val)
|
106
|
+
|
107
|
+
break if entry.type == Elf::Dynamic::Type::Null
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
data/bin/rbelf-size
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# -*- mode: ruby; coding: utf-8 -*-
|
3
|
-
# Copyright © 2008-
|
3
|
+
# Copyright © 2008-2011 Diego E. "Flameeyes" Pettenò <flameeyes@gmail.com>
|
4
4
|
#
|
5
5
|
# This program is free software; you can redistribute it and/or modify
|
6
6
|
# it under the terms of the GNU General Public License as published by
|
@@ -20,126 +20,163 @@
|
|
20
20
|
|
21
21
|
require 'elf/tools'
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
23
|
+
module Elf::Tools
|
24
|
+
class Size < Elf::Tool
|
25
|
+
def self.initialize
|
26
|
+
super
|
27
|
+
@options |= [
|
28
|
+
# Give relocation data for shared object assesment
|
29
|
+
["--relocation-stats", "-r", GetoptLong::NO_ARGUMENT],
|
30
|
+
# Use deciBel scale for the shared-to-relocated ratio
|
31
|
+
["--decibel", "-d", GetoptLong::NO_ARGUMENT],
|
32
|
+
# Show differences between the first parameter and
|
33
|
+
# the following.
|
34
|
+
["--differential", "-D", GetoptLong::NO_ARGUMENT],
|
35
|
+
]
|
36
|
+
|
37
|
+
@relocation_stats = false
|
38
|
+
end
|
29
39
|
|
30
|
-
def self.
|
31
|
-
|
32
|
-
|
40
|
+
def self.after_options
|
41
|
+
# to properly handle the differential size count, we have to
|
42
|
+
# process all the files in sequence; this means that we cannot
|
43
|
+
# use multithreaded scan here.
|
44
|
+
@execution_threads = nil if @differential
|
33
45
|
|
34
|
-
|
35
|
-
@header = true
|
36
|
-
end
|
46
|
+
@processing = []
|
37
47
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
:relro => 0,
|
45
|
-
:bss => 0,
|
46
|
-
:overhead => 0,
|
47
|
-
:total => 0
|
48
|
-
}
|
49
|
-
|
50
|
-
# Get the size of each section, and then, depending on its type,
|
51
|
-
# flags and eventually name, decide what to sum it to.
|
52
|
-
elf.each_section do |section|
|
53
|
-
# This tool only interests itself with size of sections that are
|
54
|
-
# loaded into memory at runtime, and not those that only impact
|
55
|
-
# the size of the on-disk file.
|
56
|
-
next unless section.flags.include?(Elf::Section::Flags::Alloc)
|
57
|
-
|
58
|
-
case
|
59
|
-
# When the section is NoBits, it is not allocated in the file,
|
60
|
-
# and is only allocated in ram, this is the case of .bss and
|
61
|
-
# .tbss sections.
|
62
|
-
when section.type == Elf::Section::Type::NoBits
|
63
|
-
sectype = :bss
|
64
|
-
# If the section contains executable code, count it separately;
|
65
|
-
# size(1) will count it all as text, but we don't need to do
|
66
|
-
# that.
|
67
|
-
when section.flags.include?(Elf::Section::Flags::ExecInstr)
|
68
|
-
sectype = :exec
|
69
|
-
# If the section is going to be allocated and writeable at
|
70
|
-
# runtime, it is usually a data section, of some kind.
|
71
|
-
#
|
72
|
-
# We check further though since we might want to count it
|
73
|
-
# separately.
|
74
|
-
when section.flags.include?(Elf::Section::Flags::Write)
|
75
|
-
# This makes it GCC-specific but that's just because I
|
76
|
-
# cannot find anything in ELF specs that gives an easy way
|
77
|
-
# to deal with this.
|
78
|
-
#
|
79
|
-
# By all means, .data.rel.ro is just the same as .data, with
|
80
|
-
# the exception of prelinking, where this area can then
|
81
|
-
# become mostly read-only and thus not creating dirty pages.
|
82
|
-
sectype = (section.name =~ /^\.data\.rel\.ro(\..+)?/) ? :relro : :data
|
83
|
-
# A number of sections are loaded into memory on the image but
|
84
|
-
# are not really used for anything beside providing metadata for
|
85
|
-
# link editor and loader; these section are an object's
|
86
|
-
# "overhead" and can usually be reduced by reducing the amount
|
87
|
-
# of symbols exposed by the object itself.
|
88
|
-
when (section.class == Elf::StringTable or
|
89
|
-
section.class == Elf::SymbolTable or
|
90
|
-
section.type == Elf::Section::Type::Dynamic or
|
91
|
-
section.type == Elf::Section::Type::GNU::VerDef or
|
92
|
-
section.type == Elf::Section::Type::GNU::VerNeed or
|
93
|
-
section.type == Elf::Section::Type::GNU::VerSym or
|
94
|
-
section.type == Elf::Section::Type::Hash or
|
95
|
-
section.type == Elf::Section::Type::GNU::Hash)
|
96
|
-
sectype = :overhead
|
48
|
+
results_formats = {:filename => " %s\n"}
|
49
|
+
|
50
|
+
if @relocation_stats
|
51
|
+
@processing << :relocation_stats
|
52
|
+
@processing << :convert_ratio if @decibel
|
53
|
+
@results_fields = [ :shared, :private, :relocated, :ratio, :filename ]
|
97
54
|
else
|
98
|
-
|
55
|
+
@processing << :count_allocated
|
56
|
+
@results_fields = [ :exec, :data, :rodata, :relro, :bss, :overhead, :allocated, :filename ]
|
99
57
|
end
|
100
58
|
|
101
|
-
|
59
|
+
@processing << :apply_differential if @differential
|
60
|
+
@processing << :print_results
|
61
|
+
@processing << :differential_format if @differential
|
62
|
+
|
63
|
+
printf( (@results_fields.collect { |field| results_formats[field] || "% 12s" }).join(" "),
|
64
|
+
*@results_fields)
|
65
|
+
|
66
|
+
results_formats[:ratio] = "%12.2f" # special format only for printing
|
67
|
+
|
68
|
+
@format = (@results_fields.collect { |field| results_formats[field] || "% 12d" }).join(" ")
|
102
69
|
end
|
103
70
|
|
104
|
-
|
71
|
+
def self.analysis(file)
|
72
|
+
Elf::File.open(file) do |elf|
|
73
|
+
results = {
|
74
|
+
:exec => 0,
|
75
|
+
:data => 0,
|
76
|
+
:rodata => 0,
|
77
|
+
:relro => 0,
|
78
|
+
:bss => 0,
|
79
|
+
:overhead => 0,
|
80
|
+
:allocated => 0
|
81
|
+
}
|
82
|
+
|
83
|
+
# Get the size of each section, and then, depending on its type,
|
84
|
+
# flags and eventually name, decide what to sum it to.
|
85
|
+
elf.each_section do |section|
|
86
|
+
# This tool only interests itself with size of sections that are
|
87
|
+
# loaded into memory at runtime, and not those that only impact
|
88
|
+
# the size of the on-disk file.
|
89
|
+
next unless section.flags.include?(Elf::Section::Flags::Alloc)
|
90
|
+
|
91
|
+
case
|
92
|
+
# When the section is NoBits, it is not allocated in the file,
|
93
|
+
# and is only allocated in ram, this is the case of .bss and
|
94
|
+
# .tbss sections.
|
95
|
+
when section.type == Elf::Section::Type::NoBits
|
96
|
+
sectype = :bss
|
97
|
+
# If the section contains executable code, count it separately;
|
98
|
+
# size(1) will count it all as text, but we don't need to do
|
99
|
+
# that.
|
100
|
+
when section.flags.include?(Elf::Section::Flags::ExecInstr)
|
101
|
+
sectype = :exec
|
102
|
+
# If the section is going to be allocated and writeable at
|
103
|
+
# runtime, it is usually a data section, of some kind.
|
104
|
+
#
|
105
|
+
# We check further though since we might want to count it
|
106
|
+
# separately.
|
107
|
+
when section.flags.include?(Elf::Section::Flags::Write)
|
108
|
+
# This makes it GCC-specific but that's just because I
|
109
|
+
# cannot find anything in ELF specs that gives an easy way
|
110
|
+
# to deal with this.
|
111
|
+
#
|
112
|
+
# By all means, .data.rel.ro is just the same as .data, with
|
113
|
+
# the exception of prelinking, where this area can then
|
114
|
+
# become mostly read-only and thus not creating dirty pages.
|
115
|
+
sectype = (section.name =~ /^\.data\.rel\.ro(\..+)?/) ? :relro : :data
|
116
|
+
# A number of sections are loaded into memory on the image but
|
117
|
+
# are not really used for anything beside providing metadata for
|
118
|
+
# link editor and loader; these section are an object's
|
119
|
+
# "overhead" and can usually be reduced by reducing the amount
|
120
|
+
# of symbols exposed by the object itself.
|
121
|
+
when (section.class == Elf::StringTable or
|
122
|
+
section.class == Elf::SymbolTable or
|
123
|
+
section.type == Elf::Section::Type::Dynamic or
|
124
|
+
section.type == Elf::Section::Type::GNU::VerDef or
|
125
|
+
section.type == Elf::Section::Type::GNU::VerNeed or
|
126
|
+
section.type == Elf::Section::Type::GNU::VerSym or
|
127
|
+
section.type == Elf::Section::Type::Hash or
|
128
|
+
section.type == Elf::Section::Type::GNU::Hash)
|
129
|
+
sectype = :overhead
|
130
|
+
else
|
131
|
+
sectype = :rodata
|
132
|
+
end
|
133
|
+
|
134
|
+
results[sectype] += section.size unless sectype.nil?
|
135
|
+
end
|
136
|
+
|
137
|
+
results[:filename] = file
|
138
|
+
|
139
|
+
@processing.each do |process|
|
140
|
+
method(process).call(results)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
105
144
|
|
106
|
-
|
107
|
-
|
108
|
-
else
|
109
|
-
standard_size(results, file)
|
145
|
+
def self.count_allocated(results)
|
146
|
+
results[:allocated] = results.values.inject { |sum, val| sum += val rescue sum}
|
110
147
|
end
|
111
|
-
end
|
112
|
-
end
|
113
148
|
|
114
|
-
def self.
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
149
|
+
def self.apply_differential(results)
|
150
|
+
if @first_results.nil?
|
151
|
+
(@first_results = results.dup).delete(:filename)
|
152
|
+
return
|
153
|
+
end
|
119
154
|
|
120
|
-
|
121
|
-
|
122
|
-
|
155
|
+
@results_fields.each do |field|
|
156
|
+
results[field] = results[field] - @first_results[field] rescue nil
|
157
|
+
end
|
158
|
+
end
|
123
159
|
|
124
|
-
|
125
|
-
|
160
|
+
def self.differential_format(results)
|
161
|
+
@format.gsub!(/%( [0-9]+d)/, '%+\1')
|
162
|
+
@processing.delete(:differential_format)
|
163
|
+
end
|
126
164
|
|
127
|
-
|
128
|
-
|
165
|
+
def self.relocation_stats(results)
|
166
|
+
results[:shared] = results[:exec] + results[:rodata]
|
167
|
+
results[:private] = results[:data] + results[:bss]
|
168
|
+
results[:relocated] = results[:relro]
|
129
169
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
170
|
+
results[:ratio] = results[:shared].to_f/results[:relocated]
|
171
|
+
end
|
172
|
+
|
173
|
+
def self.convert_ratio(results)
|
174
|
+
results[:ratio] = 10 * Math::log10(results[:ratio])
|
175
|
+
end
|
135
176
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
results[:bss],
|
142
|
-
results[:overhead],
|
143
|
-
results[:total],
|
144
|
-
file)
|
177
|
+
def self.print_results(results)
|
178
|
+
printf(@format,
|
179
|
+
*(@results_fields.collect { |field| results[field] }))
|
180
|
+
end
|
181
|
+
end
|
145
182
|
end
|
data/bin/verify-lfs
CHANGED
@@ -21,100 +21,105 @@
|
|
21
21
|
|
22
22
|
require 'elf/tools'
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
24
|
+
module Elf::Tools
|
25
|
+
class VerifyLFS < Elf::Tool
|
26
|
+
SymbolNamesList = [
|
27
|
+
"__[fl]?xstat",
|
28
|
+
"statv?fs",
|
29
|
+
"(|_IO_)f[gs]etpos",
|
30
|
+
"(read|scan)dir",
|
31
|
+
"getdirentries",
|
32
|
+
"mko?stemp",
|
33
|
+
"(|__)p(read|write)",
|
34
|
+
"p(read|write)v",
|
35
|
+
"(send|tmp)file",
|
36
|
+
"[gs]etrlimit",
|
37
|
+
"versionsort",
|
38
|
+
"f?truncate",
|
39
|
+
"(|f(|re))open",
|
40
|
+
"openat",
|
41
|
+
"fseeko",
|
42
|
+
"ftello",
|
43
|
+
"lseek",
|
44
|
+
"glob(|free)",
|
45
|
+
"ftw",
|
46
|
+
"lockf"
|
47
|
+
]
|
48
|
+
|
49
|
+
SymbolRegex32 = Regexp.union(SymbolNamesList.collect { |sym| /^#{sym}$/ })
|
50
|
+
SymbolRegex64 = Regexp.union(SymbolNamesList.collect { |sym| /^#{sym}64$/ })
|
51
|
+
|
52
|
+
def self.initialize
|
53
|
+
super
|
54
|
+
@options |= [
|
55
|
+
# Scan only object files (rather than non-object files)
|
56
|
+
["--objects", "-o", GetoptLong::NO_ARGUMENT]
|
50
57
|
]
|
51
|
-
|
52
|
-
SymbolNames = "(#{SymbolNamesList.join("|")})"
|
53
|
-
|
54
|
-
def self.before_options
|
55
|
-
end
|
56
|
-
|
57
|
-
def self.after_options
|
58
|
-
@files_mixing = []
|
59
|
-
@files_nolfs = []
|
60
|
-
|
61
|
-
if @objects
|
62
|
-
@elftypes = [ Elf::File::Type::Rel ]
|
63
|
-
@elfdescr = "a relocatable object file"
|
64
|
-
@elftable = ".symtab"
|
65
|
-
else
|
66
|
-
@elftypes = [ Elf::File::Type::Exec, Elf::File::Type::Dyn ]
|
67
|
-
@elfdescr = "an executable or dynamic file"
|
68
|
-
@elftable = ".dynsym"
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def self.analysis(file)
|
73
|
-
Elf::File.open(file) do |elf|
|
74
|
-
unless @elftypes.include? elf.type
|
75
|
-
putnotice "#{file}: not #{@elfdescr}"
|
76
|
-
next
|
77
|
-
end
|
78
|
-
|
79
|
-
if not elf.has_section?(@elftable) or elf[@elftable].class != Elf::SymbolTable
|
80
|
-
putnotice "#{file}: not a dynamically linked file"
|
81
|
-
next
|
82
58
|
end
|
83
59
|
|
84
|
-
|
85
|
-
|
86
|
-
|
60
|
+
def self.after_options
|
61
|
+
@files_mixing = []
|
62
|
+
@files_nolfs = []
|
63
|
+
|
64
|
+
if @objects
|
65
|
+
@elftypes = [ Elf::File::Type::Rel ]
|
66
|
+
@elfdescr = "a relocatable object file"
|
67
|
+
@elftable = ".symtab"
|
68
|
+
else
|
69
|
+
@elftypes = [ Elf::File::Type::Exec, Elf::File::Type::Dyn ]
|
70
|
+
@elfdescr = "an executable or dynamic file"
|
71
|
+
@elftable = ".dynsym"
|
72
|
+
end
|
87
73
|
end
|
88
74
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
75
|
+
def self.analysis(file)
|
76
|
+
Elf::File.open(file) do |elf|
|
77
|
+
unless @elftypes.include? elf.type
|
78
|
+
putnotice "#{file}: not #{@elfdescr}"
|
79
|
+
next
|
80
|
+
end
|
81
|
+
|
82
|
+
if not elf.has_section?(@elftable) or elf[@elftable].class != Elf::SymbolTable
|
83
|
+
putnotice "#{file}: not a dynamically linked file"
|
84
|
+
next
|
85
|
+
end
|
86
|
+
|
87
|
+
if elf.elf_class == Elf::Class::Elf64
|
88
|
+
putnotice "#{file}: testing 64-bit ELF files is meaningless"
|
89
|
+
next
|
90
|
+
end
|
91
|
+
|
92
|
+
use_stat32 = false
|
93
|
+
use_stat64 = false
|
94
|
+
|
95
|
+
elf[@elftable].each do |symbol|
|
96
|
+
next unless symbol.section == Elf::Section::Undef
|
97
|
+
|
98
|
+
use_stat32 ||= (symbol.to_s =~ SymbolRegex32)
|
99
|
+
use_stat64 ||= (symbol.to_s =~ SymbolRegex64)
|
100
|
+
|
101
|
+
# avoid running the whole list if we hit both as we cannot hit
|
102
|
+
# _more_
|
103
|
+
break if use_stat32 and use_stat64
|
104
|
+
end
|
105
|
+
|
106
|
+
if use_stat32 and use_stat64
|
107
|
+
@files_mixing << file
|
108
|
+
elsif use_stat32 and not use_stat64
|
109
|
+
@files_nolfs << file
|
110
|
+
end
|
111
|
+
end
|
101
112
|
end
|
102
113
|
|
103
|
-
|
104
|
-
@files_mixing
|
105
|
-
|
106
|
-
|
114
|
+
def self.results
|
115
|
+
if @files_mixing.size > 0
|
116
|
+
puts "The following files are mixing LFS and non-LFS library calls:"
|
117
|
+
puts " " + @files_mixing.join("\n ")
|
118
|
+
end
|
119
|
+
if @files_nolfs.size > 0
|
120
|
+
puts "The following files are using non-LFS library calls:"
|
121
|
+
puts " " + @files_nolfs.join("\n ")
|
122
|
+
end
|
107
123
|
end
|
108
124
|
end
|
109
125
|
end
|
110
|
-
|
111
|
-
def self.results
|
112
|
-
if @files_mixing.size > 0
|
113
|
-
puts "The following files are mixing LFS and non-LFS library calls:"
|
114
|
-
puts " " + @files_mixing.join("\n ")
|
115
|
-
end
|
116
|
-
if @files_nolfs.size > 0
|
117
|
-
puts "The following files are using non-LFS library calls:"
|
118
|
-
puts " " + @files_nolfs.join("\n ")
|
119
|
-
end
|
120
|
-
end
|