ruby-elf 1.0.0 → 1.0.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.
- data/bin/elfgrep +32 -31
- data/bin/rbelf-size +32 -10
- data/lib/elf.rb +1 -8
- data/lib/elf/file.rb +3 -2
- data/lib/elf/symbol.rb +7 -3
- data/lib/elf/tools.rb +13 -17
- data/manpages/cowstats.1.xml +234 -0
- data/manpages/elfgrep.1 +5 -15
- data/manpages/elfgrep.1.xml +370 -0
- data/manpages/missingstatic.1.xml +290 -0
- data/manpages/rbelf-size.1 +5 -0
- data/manpages/rbelf-size.1.xml +334 -0
- data/manpages/verify-lfs.1.xml +136 -0
- data/tools/readelf-d.rb +5 -2
- metadata +9 -4
data/bin/elfgrep
CHANGED
@@ -74,16 +74,6 @@ def self.no_filename_cb
|
|
74
74
|
@print_filename = false
|
75
75
|
end
|
76
76
|
|
77
|
-
# we make this a method so that we don't have to worry about deciding
|
78
|
-
# on the base of how many targets we have; we have to do this
|
79
|
-
# because we cannot know, in after_options, whether the user passed
|
80
|
-
# @-file lists.
|
81
|
-
def self.print_filename
|
82
|
-
@print_filename = !@single_target if @print_filename.nil?
|
83
|
-
|
84
|
-
@print_filename
|
85
|
-
end
|
86
|
-
|
87
77
|
def self.regexp_cb(pattern)
|
88
78
|
@patterns << pattern
|
89
79
|
end
|
@@ -99,11 +89,6 @@ def self.before_options
|
|
99
89
|
end
|
100
90
|
|
101
91
|
def self.after_options
|
102
|
-
if @patterns.size ==0
|
103
|
-
puterror "you need to provide at least expression"
|
104
|
-
exit -1
|
105
|
-
end
|
106
|
-
|
107
92
|
if @no_match_undefined and @no_match_defined
|
108
93
|
puterror "you need to match at least defined or undefined symbols"
|
109
94
|
exit -1
|
@@ -112,27 +97,43 @@ def self.after_options
|
|
112
97
|
@match_undefined = !@no_match_undefined
|
113
98
|
@match_defined = !@no_match_defined
|
114
99
|
|
100
|
+
# if we don't have listed patterns yet (i.e. no -e option), let's
|
101
|
+
# check whether we have at least one argument and if that argument
|
102
|
+
# doesn't start with '@'. If we have no arguments, the targets are
|
103
|
+
# to be given by stdin, and that won't include the actual pattern,
|
104
|
+
# if we have an @-prefixed argument, that's a list of targets and
|
105
|
+
# can't include the pattern either.
|
106
|
+
if (@patterns.size == 0 and
|
107
|
+
ARGV.size >= 1 and
|
108
|
+
ARGV[0] !~ /^@/)
|
109
|
+
|
110
|
+
@patterns << ARGV.delete_at(0)
|
111
|
+
end
|
112
|
+
|
113
|
+
if @patterns.size == 0
|
114
|
+
puterror "you need to provide at least expression"
|
115
|
+
exit -1
|
116
|
+
end
|
117
|
+
|
118
|
+
@print_filename = true if @print_filename.nil? and not single_target?
|
119
|
+
@file_prefix_fmt = @print_filename ? "%s#{@null ? "\0" : ":"} " : ""
|
120
|
+
@file_list_fmt = "%s#{@null ? "\0" : "\n"}"
|
121
|
+
|
115
122
|
regexp_options = @ignore_case ? Regexp::IGNORECASE : 0
|
116
123
|
@regexp = Regexp.union(@patterns.collect { |pattern|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
124
|
+
if @match == :fixed_strings
|
125
|
+
pattern.split(/\r?\n/).collect { |string|
|
126
|
+
Regexp.new(Regexp.escape(string), regexp_options)
|
127
|
+
}
|
128
|
+
else
|
129
|
+
Regexp.new(pattern, regexp_options)
|
130
|
+
end
|
131
|
+
}.flatten)
|
123
132
|
end
|
124
133
|
|
125
134
|
def self.analysis(file)
|
126
|
-
|
127
|
-
|
128
|
-
else
|
129
|
-
file_prefix = sprintf("%s%s ",
|
130
|
-
file,
|
131
|
-
@null ? "\0" : ":")
|
132
|
-
end
|
133
|
-
file_list = sprintf("%s%s",
|
134
|
-
file,
|
135
|
-
@null ? "\0" : "\n")
|
135
|
+
file_prefix = sprintf(@file_prefix_fmt, file)
|
136
|
+
file_list = sprintf(@file_list_fmt, file)
|
136
137
|
|
137
138
|
Elf::File.open(file) do |elf|
|
138
139
|
table = [".dynsym", ".symtab"].find do |table|
|
data/bin/rbelf-size
CHANGED
@@ -43,12 +43,18 @@ def self.analysis(file)
|
|
43
43
|
:rodata => 0,
|
44
44
|
:relro => 0,
|
45
45
|
:bss => 0,
|
46
|
+
:overhead => 0,
|
46
47
|
:total => 0
|
47
48
|
}
|
48
49
|
|
49
50
|
# Get the size of each section, and then, depending on its type,
|
50
51
|
# flags and eventually name, decide what to sum it to.
|
51
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
|
+
|
52
58
|
case
|
53
59
|
# When the section is NoBits, it is not allocated in the file,
|
54
60
|
# and is only allocated in ram, this is the case of .bss and
|
@@ -65,9 +71,7 @@ def self.analysis(file)
|
|
65
71
|
#
|
66
72
|
# We check further though since we might want to count it
|
67
73
|
# separately.
|
68
|
-
when
|
69
|
-
section.flags.include?(Elf::Section::Flags::Alloc))
|
70
|
-
|
74
|
+
when section.flags.include?(Elf::Section::Flags::Write)
|
71
75
|
# This makes it GCC-specific but that's just because I
|
72
76
|
# cannot find anything in ELF specs that gives an easy way
|
73
77
|
# to deal with this.
|
@@ -76,7 +80,21 @@ def self.analysis(file)
|
|
76
80
|
# the exception of prelinking, where this area can then
|
77
81
|
# become mostly read-only and thus not creating dirty pages.
|
78
82
|
sectype = (section.name =~ /^\.data\.rel\.ro(\..+)?/) ? :relro : :data
|
79
|
-
|
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
|
97
|
+
else
|
80
98
|
sectype = :rodata
|
81
99
|
end
|
82
100
|
|
@@ -111,13 +129,17 @@ end
|
|
111
129
|
|
112
130
|
def self.standard_size(results, file)
|
113
131
|
if @header
|
114
|
-
puts " exec data rodata relro bss total filename"
|
132
|
+
puts " exec data rodata relro bss overhead total filename"
|
115
133
|
@header = false
|
116
134
|
end
|
117
135
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
136
|
+
printf("% 9d % 9d % 9d % 9d % 9d % 9d % 9d %s\n",
|
137
|
+
results[:exec],
|
138
|
+
results[:data],
|
139
|
+
results[:rodata],
|
140
|
+
results[:relro],
|
141
|
+
results[:bss],
|
142
|
+
results[:overhead],
|
143
|
+
results[:total],
|
144
|
+
file)
|
123
145
|
end
|
data/lib/elf.rb
CHANGED
@@ -28,15 +28,8 @@ require 'elf/symbol'
|
|
28
28
|
require 'elf/file'
|
29
29
|
require 'elf/section'
|
30
30
|
|
31
|
-
# We need this quite e lot
|
32
|
-
class Integer
|
33
|
-
def hex
|
34
|
-
sprintf "%x", self
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
31
|
module Elf
|
39
|
-
VERSION = "1.0.
|
32
|
+
VERSION = "1.0.1"
|
40
33
|
|
41
34
|
MagicString = "\177ELF"
|
42
35
|
|
data/lib/elf/file.rb
CHANGED
@@ -230,7 +230,8 @@ module Elf
|
|
230
230
|
# When the section header string table index is set to zero,
|
231
231
|
# there is not going to be a string table in the file, this
|
232
232
|
# happens usually when the file is a static ELF file built
|
233
|
-
# directly with an assembler
|
233
|
+
# directly with an assembler, or when it was passed through
|
234
|
+
# the elfkickers' sstrip utility.
|
234
235
|
#
|
235
236
|
# To handle this specific case, set the @string_table attribute
|
236
237
|
# to false, that is distinct from nil, and raise
|
@@ -316,7 +317,7 @@ module Elf
|
|
316
317
|
def has_section?(sect_idx_or_name)
|
317
318
|
|
318
319
|
if sect_idx_or_name.is_a? String and not @string_table.is_a? Elf::Section
|
319
|
-
|
320
|
+
raise MissingStringTable.new(sect_idx_or_name) if @string_table == false
|
320
321
|
raise StringTableNotLoaded.new(sect_idx_or_name) if @string_table.nil?
|
321
322
|
end
|
322
323
|
|
data/lib/elf/symbol.rb
CHANGED
@@ -133,14 +133,18 @@ module Elf
|
|
133
133
|
end
|
134
134
|
|
135
135
|
rescue Elf::Value::OutOfBound => e
|
136
|
-
e.append_message("While processing symbol
|
136
|
+
e.append_message(sprintf("While processing symbol %d. Symbol 'info' value: 0x%x",
|
137
|
+
@idx,
|
138
|
+
info))
|
137
139
|
raise e
|
138
140
|
end
|
139
141
|
|
140
142
|
begin
|
141
143
|
@visibility = Visibility[@other & 0x03]
|
142
144
|
rescue Elf::Value::OutOfBound => e
|
143
|
-
e.append_message("While procesing symbol
|
145
|
+
e.append_message(sprintf("While procesing symbol %d. Symbol 'other' value: 0x%x",
|
146
|
+
@idx,
|
147
|
+
other))
|
144
148
|
raise e
|
145
149
|
end
|
146
150
|
|
@@ -223,7 +227,7 @@ module Elf
|
|
223
227
|
section = if symbol.section.nil?
|
224
228
|
nil
|
225
229
|
elsif symbol.section.is_a?(Integer)
|
226
|
-
symbol.section
|
230
|
+
sprintf("%x", symbol.section)
|
227
231
|
else
|
228
232
|
symbol.section.name
|
229
233
|
end
|
data/lib/elf/tools.rb
CHANGED
@@ -67,14 +67,9 @@ def self.parse_arguments
|
|
67
67
|
if opt == "--help"
|
68
68
|
# check if we're executing from a tarball or the git repository,
|
69
69
|
# if so we can't use the system man page.
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
if localman.exist?
|
74
|
-
exec("man #{localman.to_s}")
|
75
|
-
else
|
76
|
-
exec("man #{to_s}")
|
77
|
-
end
|
70
|
+
manpage = File.expand_path("../../../manpages/#{to_s}.1", __FILE__)
|
71
|
+
manpage = to_s unless File.exist?(manpage)
|
72
|
+
exec("man #{manpage}")
|
78
73
|
end
|
79
74
|
|
80
75
|
attrname = opt.gsub(/^--/, "").gsub("-", "_")
|
@@ -99,6 +94,16 @@ def self.parse_arguments
|
|
99
94
|
raise ArgumentError("wrong number of arguments in callback (#{cb.arity} for #{arg.size})")
|
100
95
|
end
|
101
96
|
end
|
97
|
+
|
98
|
+
@parsed_options = true
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.single_target?
|
102
|
+
raise Exception.new("You can't call this until options are parsed") unless @parsed_options
|
103
|
+
|
104
|
+
# We consider having a single target means that we're given exactly
|
105
|
+
# one argument, and that argument is not a targets' list itself.
|
106
|
+
return (ARGV.size == 1 and ARGV[0] !~ /^@/)
|
102
107
|
end
|
103
108
|
|
104
109
|
def execute(filename)
|
@@ -178,8 +183,6 @@ end
|
|
178
183
|
|
179
184
|
# Execute the analysis function on all the lines of a file
|
180
185
|
def self.execute_on_file(file)
|
181
|
-
@single_target = false
|
182
|
-
|
183
186
|
file = $stdin if file == "-"
|
184
187
|
file = File.new(file) if file.class == String
|
185
188
|
|
@@ -197,13 +200,6 @@ def self.main
|
|
197
200
|
parse_arguments
|
198
201
|
after_options if respond_to? :after_options
|
199
202
|
|
200
|
-
# We set the @single_target attribute to true if we're given a
|
201
|
-
# single filename as a target, so that tools like elfgrep can
|
202
|
-
# avoid printing again the filename on the output. Since we could
|
203
|
-
# be given a single @-prefixed file to use as a list, we'll reset
|
204
|
-
# @single_target in self.execute_on_file
|
205
|
-
@single_target = (ARGV.size == 1)
|
206
|
-
|
207
203
|
if ARGV.size == 0
|
208
204
|
execute_on_file($stdin)
|
209
205
|
else
|
@@ -0,0 +1,234 @@
|
|
1
|
+
<?xml version='1.0'?>
|
2
|
+
<!--
|
3
|
+
Copyright © 2008-2011, Diego "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
|
+
<article xmlns="http://docbook.org/ns/docbook"
|
20
|
+
xmlns:xl="http://www.w3.org/1999/xlink"
|
21
|
+
xmlns:xi="http://www.w3.org/2001/XInclude"
|
22
|
+
version="5.0" xml:lang="en">
|
23
|
+
<info>
|
24
|
+
<title>cowstats</title>
|
25
|
+
|
26
|
+
<xi:include parse="xml" href="author.xmli" />
|
27
|
+
</info>
|
28
|
+
|
29
|
+
<section>
|
30
|
+
<title>Reference</title>
|
31
|
+
|
32
|
+
<refentry>
|
33
|
+
<info>
|
34
|
+
<date>October 2008</date>
|
35
|
+
<productname>ruby-elf</productname>
|
36
|
+
</info>
|
37
|
+
<refmeta>
|
38
|
+
<refentrytitle>cowstats</refentrytitle>
|
39
|
+
<manvolnum>1</manvolnum>
|
40
|
+
</refmeta>
|
41
|
+
<refnamediv>
|
42
|
+
<refname>cowstats</refname>
|
43
|
+
<refpurpose>ELF Copy-on-Write analyzer</refpurpose>
|
44
|
+
</refnamediv>
|
45
|
+
<refsynopsisdiv>
|
46
|
+
<cmdsynopsis>
|
47
|
+
<command>cowstats</command>
|
48
|
+
<arg choice="opt"><option>--statistics</option></arg>
|
49
|
+
<arg choice="opt"><option>--total</option></arg>
|
50
|
+
<arg choice="opt"><option>--ignore-cxx</option></arg>
|
51
|
+
<arg choice="opt"><option>--ignore-profiling</option></arg>
|
52
|
+
<arg choice="opt"><option>--ignore-data-rel-ro</option></arg>
|
53
|
+
<arg choice="opt">
|
54
|
+
<option>--sort-by</option>
|
55
|
+
<replaceable>section-column</replaceable>
|
56
|
+
</arg>
|
57
|
+
|
58
|
+
<xi:include href="common.xmli" xpointer="xpointer(id('filelist.synopsis')/*)" />
|
59
|
+
</cmdsynopsis>
|
60
|
+
</refsynopsisdiv>
|
61
|
+
|
62
|
+
<refsect1>
|
63
|
+
<title>Description</title>
|
64
|
+
<para>
|
65
|
+
<command>cowstats</command> is a script that analyses ELF object files, results of
|
66
|
+
compilation of C, C++ or other languages on an Unix system, and reports about the
|
67
|
+
variables that enter Copy-on-Write sections.
|
68
|
+
</para>
|
69
|
+
|
70
|
+
<para>
|
71
|
+
Static variables (initialised and not) and constant pointers on PIC or PIE enabled object
|
72
|
+
files are emitted in the so-called Copy-on-Write sections, which require copying over
|
73
|
+
pages from the original ELF executable file to a private resident area of memory at
|
74
|
+
runtime.
|
75
|
+
</para>
|
76
|
+
|
77
|
+
<para>
|
78
|
+
<command>cowstats</command> reports the possible symbols that were emitted in
|
79
|
+
Copy-on-Write sections so that they can be looked after to see if they can be made
|
80
|
+
constant and/or removed or reworked.
|
81
|
+
</para>
|
82
|
+
</refsect1>
|
83
|
+
|
84
|
+
<refsect1>
|
85
|
+
<title>Options</title>
|
86
|
+
|
87
|
+
<variablelist>
|
88
|
+
<varlistentry>
|
89
|
+
<term><option>-s</option></term>
|
90
|
+
<term><option>--statistics</option></term>
|
91
|
+
<listitem>
|
92
|
+
<para>
|
93
|
+
Instead of reporting all the variables found in Copy-on-Write sections, only
|
94
|
+
generate a table showing the sie of data in Copy-on-Write sections per each file,
|
95
|
+
divided into <constant>.data</constant>, <constant>.bss</constant> and
|
96
|
+
<constant>.data.rel</constant> (for variables, uninitialised variables, and
|
97
|
+
relocated variables and constants).
|
98
|
+
</para>
|
99
|
+
</listitem>
|
100
|
+
</varlistentry>
|
101
|
+
|
102
|
+
<varlistentry>
|
103
|
+
<term><option>-t</option></term>
|
104
|
+
<term><option>--total</option></term>
|
105
|
+
<listitem>
|
106
|
+
<para>
|
107
|
+
Shows some rough totals for the amount of data in Copy-on-Write sections for the
|
108
|
+
program, assuming all the object files given are linked in the same executable. This
|
109
|
+
will also show a rough page-based total, which bases itself on 4K-sized pages.
|
110
|
+
</para>
|
111
|
+
</listitem>
|
112
|
+
</varlistentry>
|
113
|
+
|
114
|
+
<varlistentry>
|
115
|
+
<term><option>-x</option></term>
|
116
|
+
<term><option>--ignore-cxx</option></term>
|
117
|
+
<listitem>
|
118
|
+
<para>
|
119
|
+
Ignore some C++ entries that could be considered false positives. C++ object files
|
120
|
+
will report as CoW data the vtables and typeinfo objects for C++ classes, since they
|
121
|
+
are actually emitted in Copy-on-Write sections. Since they cannot be moved from
|
122
|
+
thre, this option hides them on the output, to reduce clutter and noise.
|
123
|
+
</para>
|
124
|
+
</listitem>
|
125
|
+
</varlistentry>
|
126
|
+
|
127
|
+
<varlistentry>
|
128
|
+
<term><option>-p</option></term>
|
129
|
+
<term><option>--ignore-profiling</option></term>
|
130
|
+
<listitem>
|
131
|
+
<para>
|
132
|
+
Similarly to C++, also profiling (with <command>gcov</command>) will add some
|
133
|
+
symbols that would be identified as CoW data. Use this option to avoid reporting
|
134
|
+
those symbols.
|
135
|
+
</para>
|
136
|
+
</listitem>
|
137
|
+
</varlistentry>
|
138
|
+
|
139
|
+
<varlistentry>
|
140
|
+
<term><option>-r</option></term>
|
141
|
+
<term><option>--ignore-data-rel-ro</option></term>
|
142
|
+
<listitem>
|
143
|
+
<para>
|
144
|
+
Don't report constants found in the .data.rel.ro section, and consider it as
|
145
|
+
non-relocated. This is helpful to reduce the noise when looking for writable data
|
146
|
+
symbols, or when analysing non-PIC builds.
|
147
|
+
</para>
|
148
|
+
</listitem>
|
149
|
+
</varlistentry>
|
150
|
+
|
151
|
+
<varlistentry>
|
152
|
+
<term>
|
153
|
+
<option>-S</option>
|
154
|
+
<replaceable>section-column</replaceable>
|
155
|
+
</term>
|
156
|
+
<term>
|
157
|
+
<option>--sort-by</option>
|
158
|
+
<replaceable>section-column</replaceable>
|
159
|
+
</term>
|
160
|
+
|
161
|
+
<listitem>
|
162
|
+
<para>
|
163
|
+
Sort the output of <option>--statistics</option> by the given column. Useful when
|
164
|
+
looking for which objects have the most hit for one particular CoW problem. The
|
165
|
+
column can be one of the following section names:
|
166
|
+
</para>
|
167
|
+
|
168
|
+
<itemizedlist>
|
169
|
+
<listitem><para>.bss</para></listitem>
|
170
|
+
<listitem><para>.data</para></listitem>
|
171
|
+
<listitem><para>.data.rel</para></listitem>
|
172
|
+
<listitem><para>.data.rel.ro</para></listitem>
|
173
|
+
</itemizedlist>
|
174
|
+
</listitem>
|
175
|
+
</varlistentry>
|
176
|
+
|
177
|
+
<xi:include href="common.xmli" xpointer="xpointer(id('filelist.option')/*)" />
|
178
|
+
|
179
|
+
</variablelist>
|
180
|
+
</refsect1>
|
181
|
+
|
182
|
+
<refsect1>
|
183
|
+
<title>Bugs</title>
|
184
|
+
|
185
|
+
<para>
|
186
|
+
<command>cowstats</command> is still an experiment, and is
|
187
|
+
not yet entirely complete, there are thus a number of bugs
|
188
|
+
that haven't been discovered or well tested yet.
|
189
|
+
</para>
|
190
|
+
|
191
|
+
<para>
|
192
|
+
A known "bug" or misbehaviour is that <command>cowstats</command> cannot know whether
|
193
|
+
multple object files will be linked together in the same module (executable or shared
|
194
|
+
object) or not. For this reason the output of <option>--total</option> might not be
|
195
|
+
consistent with the runtime behaviour of the module itself.
|
196
|
+
</para>
|
197
|
+
|
198
|
+
<xi:include href="common.xmli" xpointer="xpointer(id('filelist.bugpara')/*)" />
|
199
|
+
</refsect1>
|
200
|
+
|
201
|
+
<refsect1>
|
202
|
+
<title>See Also</title>
|
203
|
+
<para>
|
204
|
+
<citation xl:href="http://blog.flameeyes.eu/">Flameeyes's Weblog</citation>
|
205
|
+
http://blog.flameeyes.eu/
|
206
|
+
</para>
|
207
|
+
|
208
|
+
<para>
|
209
|
+
Related tools:
|
210
|
+
|
211
|
+
<citerefentry>
|
212
|
+
<refentrytitle>rbelf-size</refentrytitle>
|
213
|
+
<manvolnum>1</manvolnum>
|
214
|
+
</citerefentry>,
|
215
|
+
|
216
|
+
<citerefentry>
|
217
|
+
<refentrytitle>objdump</refentrytitle>
|
218
|
+
<manvolnum>1</manvolnum>
|
219
|
+
</citerefentry>.
|
220
|
+
</para>
|
221
|
+
</refsect1>
|
222
|
+
</refentry>
|
223
|
+
</section>
|
224
|
+
</article>
|
225
|
+
<!--
|
226
|
+
Local Variables:
|
227
|
+
mode: nxml
|
228
|
+
mode: auto-fill
|
229
|
+
mode: flyspell
|
230
|
+
ispell-local-dictionary: "english"
|
231
|
+
fill-column: 100
|
232
|
+
indent-tabs-mode: nil
|
233
|
+
End:
|
234
|
+
-->
|