ruby-elf 1.0.0
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/COPYING +339 -0
- data/DONATING +42 -0
- data/bin/cowstats +264 -0
- data/bin/elfgrep +185 -0
- data/bin/missingstatic +112 -0
- data/bin/rbelf-size +123 -0
- data/bin/verify-lfs +120 -0
- data/extras/README.extras +5 -0
- data/extras/bindings-parsers.rb +157 -0
- data/lib/bytestream-reader.rb +271 -0
- data/lib/elf.rb +248 -0
- data/lib/elf/dynamic.rb +392 -0
- data/lib/elf/file.rb +366 -0
- data/lib/elf/gnu.rb +174 -0
- data/lib/elf/section.rb +321 -0
- data/lib/elf/stringtable.rb +49 -0
- data/lib/elf/sunw.rb +158 -0
- data/lib/elf/symbol.rb +368 -0
- data/lib/elf/symbol/demangler_gcc3.rb +1952 -0
- data/lib/elf/symboltable.rb +90 -0
- data/lib/elf/tools.rb +228 -0
- data/lib/elf/utils/loader.rb +112 -0
- data/lib/elf/utils/pool.rb +37 -0
- data/lib/elf/value.rb +128 -0
- data/manpages/cowstats.1 +180 -0
- data/manpages/elfgrep.1 +188 -0
- data/manpages/missingstatic.1 +176 -0
- data/manpages/rbelf-size.1 +186 -0
- data/manpages/verify-lfs.1 +95 -0
- data/tools/assess_duplicate_save.rb +105 -0
- data/tools/link-collisions/analyse.rb +57 -0
- data/tools/link-collisions/harvest.rb +367 -0
- data/tools/link-collisions/known-broken +165 -0
- data/tools/link-collisions/multimplementations +125 -0
- data/tools/link-collisions/suppress.rb +84 -0
- data/tools/link-collisions/suppressions +279 -0
- data/tools/nm.rb +78 -0
- data/tools/rbelf-lddtree.rb +49 -0
- data/tools/readelf-d.rb +76 -0
- metadata +114 -0
@@ -0,0 +1,49 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# Simple ELF parser for Ruby
|
3
|
+
#
|
4
|
+
# Copyright © 2007-2010 Diego E. "Flameeyes" Pettenò <flameeyes@gmail.com>
|
5
|
+
# Portions inspired by elf.py
|
6
|
+
# Copyright © 2002 Netgraft Corporation
|
7
|
+
# Portions inspired by elf.h
|
8
|
+
# Copyright © 1995-2006 Free Software Foundation, Inc.
|
9
|
+
#
|
10
|
+
# This program is free software; you can redistribute it and/or modify
|
11
|
+
# it under the terms of the GNU General Public License as published by
|
12
|
+
# the Free Software Foundation; either version 2 of the License, or
|
13
|
+
# (at your option) any later version.
|
14
|
+
#
|
15
|
+
# This program is distributed in the hope that it will be useful,
|
16
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
17
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
18
|
+
# GNU General Public License for more details.
|
19
|
+
#
|
20
|
+
# You should have received a copy of the GNU General Public License
|
21
|
+
# along with this generator; if not, write to the Free Software
|
22
|
+
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
23
|
+
|
24
|
+
require 'elf/section'
|
25
|
+
|
26
|
+
module Elf
|
27
|
+
class StringTable < Section
|
28
|
+
def load_internal
|
29
|
+
@rawtable = @file.readexactly(@size)
|
30
|
+
end
|
31
|
+
|
32
|
+
class InvalidIndex < Exception
|
33
|
+
def initialize(idx, max_idx)
|
34
|
+
super("Invalid index #{idx} (maximum index: #{max_idx})")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def [](idx)
|
39
|
+
load unless @rawtable
|
40
|
+
|
41
|
+
raise InvalidIndex.new(idx, @rawtable.size) if
|
42
|
+
idx >= @rawtable.size
|
43
|
+
|
44
|
+
endidx = @rawtable.index("\x00", idx)
|
45
|
+
|
46
|
+
return @rawtable[idx..endidx].chomp("\x00")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/elf/sunw.rb
ADDED
@@ -0,0 +1,158 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# Simple ELF parser for Ruby
|
3
|
+
#
|
4
|
+
# Copyright © 2008-2010 Diego E. "Flameeyes" Pettenò <flameeyes@gmail.com>
|
5
|
+
# Portions inspired by elf.py
|
6
|
+
# Copyright © 2002 Netgraft Corporation
|
7
|
+
# Portions inspired by elf.h
|
8
|
+
# Copyright © 1995-2006 Free Software Foundation, Inc.
|
9
|
+
# Constants derived from OpenSolaris elf.h and documentation
|
10
|
+
# Copyright © 2007 Sun Microsystems, Inc.
|
11
|
+
#
|
12
|
+
# This program is free software; you can redistribute it and/or modify
|
13
|
+
# it under the terms of the GNU General Public License as published by
|
14
|
+
# the Free Software Foundation; either version 2 of the License, or
|
15
|
+
# (at your option) any later version.
|
16
|
+
#
|
17
|
+
# This program is distributed in the hope that it will be useful,
|
18
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
19
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
20
|
+
# GNU General Public License for more details.
|
21
|
+
#
|
22
|
+
# You should have received a copy of the GNU General Public License
|
23
|
+
# along with this generator; if not, write to the Free Software
|
24
|
+
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
25
|
+
|
26
|
+
module Elf
|
27
|
+
# Sun-specific sections parsing
|
28
|
+
module SunW
|
29
|
+
|
30
|
+
class Capabilities < Section
|
31
|
+
class Tag < Value
|
32
|
+
fill(
|
33
|
+
0 => [ :Null, nil ],
|
34
|
+
1 => [ :HW1, "Hardware capabilities" ],
|
35
|
+
2 => [ :SF1, "Software capabilities" ]
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
class Software1 < Value
|
40
|
+
fill(
|
41
|
+
0x0001 => [ :FramePointerKnown, "Frame pointer use is known" ],
|
42
|
+
0x0002 => [ :FramePointerUsed, "Frame pointer is used" ]
|
43
|
+
)
|
44
|
+
|
45
|
+
# Known capabilities mask
|
46
|
+
KnownMask = 0x003
|
47
|
+
end
|
48
|
+
|
49
|
+
module Hardware1
|
50
|
+
class Sparc < Value
|
51
|
+
fill(
|
52
|
+
0x0001 => [ :Mul32, "Uses 32x32-bit smul/umul" ],
|
53
|
+
0x0002 => [ :Div32, "Uses 32x32-bit sdiv/udiv" ],
|
54
|
+
0x0004 => [ :Fsmuld, "Uses fsmuld instruction" ],
|
55
|
+
0x0008 => [ :V8Plus, "Uses V9 intructins in 32-bit apps" ],
|
56
|
+
0x0010 => [ :Popc, "Uses popc instruction" ],
|
57
|
+
0x0020 => [ :Vis, "Uses VIS instruction set" ],
|
58
|
+
0x0040 => [ :Vis2, "Uses VIS2 instruction set" ],
|
59
|
+
0x0080 => [ :AsiBlkInit, nil ],
|
60
|
+
0x0100 => [ :Fmaf, "Uses Fused Multiply-Add" ],
|
61
|
+
0x0200 => [ :FjFmau, "Uses Fujitsu Unfused Multiply-Add" ],
|
62
|
+
0x0400 => [ :Ima, "Uses Integer Multiply-Add" ]
|
63
|
+
)
|
64
|
+
end
|
65
|
+
|
66
|
+
class I386 < Value
|
67
|
+
fill(
|
68
|
+
0x00000001 => [ :FPU, "Uses x87-style floating point" ],
|
69
|
+
0x00000002 => [ :TSC, "Uses rdtsc instruction" ],
|
70
|
+
0x00000004 => [ :CX8, "Uses cmpxchg8b instruction" ],
|
71
|
+
0x00000008 => [ :SEP, "Uses sysenter/sysexit instructions" ],
|
72
|
+
0x00000010 => [ :AmdSycC, "Uses AMD's syscall/sysret instructions" ],
|
73
|
+
0x00000020 => [ :CMov, "Uses conditional move instructions" ],
|
74
|
+
0x00000040 => [ :MMX, "Uses MMX instruction set" ],
|
75
|
+
0x00000080 => [ :AmdMMX, "Uses AMD's MMX instruction set" ],
|
76
|
+
0x00000100 => [ :Amd3DNow, "Uses AMD's 3DNow! instruction set" ],
|
77
|
+
0x00000200 => [ :Amd3DNowX, "Uses AMD's 3DNow! extended instruction set" ],
|
78
|
+
0x00000400 => [ :FXSR, "Uses fxsave/fxrstor instructions" ],
|
79
|
+
0x00000800 => [ :SSE, "Uses SSE instruction set and registers" ],
|
80
|
+
0x00001000 => [ :SSE2, "Uses SSE2 instruction set and registers" ],
|
81
|
+
0x00002000 => [ :Pause, "Uses pause instruction" ],
|
82
|
+
0x00004000 => [ :SSE3, "Uses SSE3 instruction set and registers" ],
|
83
|
+
0x00008000 => [ :Mon, "Uses monitor/mwait instructions" ],
|
84
|
+
0x00010000 => [ :CX16, "Uses cmpxchg16b instruction" ],
|
85
|
+
0x00020000 => [ :AHF, "Uses lahf/sahf instructions" ],
|
86
|
+
0x00040000 => [ :TSCP, "Uses rdtscp instruction" ],
|
87
|
+
0x00080000 => [ :AmdSSE4a, "Uses AMD's SSEA4a instructions" ],
|
88
|
+
0x00100000 => [ :PopCnt, "Uses popcnt instruction" ],
|
89
|
+
0x00200000 => [ :AmdLzcnt, "Uses AMD's lzcnt instructon" ],
|
90
|
+
0x00400000 => [ :SSSE3, "Uses Intel's SSSE3 instruction set" ],
|
91
|
+
0x00800000 => [ :SSE4_1, "Uses Intel's SSE4.1 instruction set" ],
|
92
|
+
0x01000000 => [ :SSE4_2, "uses Intel's SSE4.2 instruction set" ]
|
93
|
+
)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def load_internal
|
98
|
+
elf32 = @file.elf_class == Class::Elf32
|
99
|
+
|
100
|
+
@entries = []
|
101
|
+
loop do
|
102
|
+
entry = {}
|
103
|
+
tag = elf32 ? @file.read_word : @file.read_xword
|
104
|
+
entry[:tag] = Tag[tag]
|
105
|
+
|
106
|
+
# This marks the end of the array.
|
107
|
+
break if entry[:tag] == Tag::Null
|
108
|
+
|
109
|
+
# Right now the only two types used make only use of c_val,
|
110
|
+
# but in the future there might be capabilities using c_ptr,
|
111
|
+
# so prepare for that.
|
112
|
+
case entry[:tag]
|
113
|
+
when Tag::SF1
|
114
|
+
val = elf32 ? @file.read_word : @file.read_xword
|
115
|
+
entry[:flags] = Set.new
|
116
|
+
|
117
|
+
Software1.each do |flag|
|
118
|
+
entry[:flags].add(flag) if (val & flag.val) == flag.val
|
119
|
+
end
|
120
|
+
when Tag::HW1
|
121
|
+
val = elf32 ? @file.read_word : @file.read_xword
|
122
|
+
entry[:flags] = Set.new
|
123
|
+
|
124
|
+
case @file.machine
|
125
|
+
when Machine::Sparc
|
126
|
+
Hardware1::Sparc.each do |flag|
|
127
|
+
entry[:flags].add(flag) if (val & flag.val) == flag.val
|
128
|
+
end
|
129
|
+
when Machine::I386
|
130
|
+
Hardware1::I386.each do |flag|
|
131
|
+
entry[:flags].add(flag) if (val & flag.val) == flag.val
|
132
|
+
end
|
133
|
+
else
|
134
|
+
raise "Sun-specific extensions only support i386/Sparc!"
|
135
|
+
end
|
136
|
+
|
137
|
+
else
|
138
|
+
entry[:ptr] = @file.read_addr
|
139
|
+
end
|
140
|
+
|
141
|
+
@entries << entry
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def size
|
146
|
+
load unless @entries
|
147
|
+
|
148
|
+
@entries.size
|
149
|
+
end
|
150
|
+
|
151
|
+
def [](idx)
|
152
|
+
load unless @entries
|
153
|
+
|
154
|
+
@entries[idx]
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
data/lib/elf/symbol.rb
ADDED
@@ -0,0 +1,368 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# Simple ELF parser for Ruby
|
3
|
+
#
|
4
|
+
# Copyright © 2007-2010 Diego E. "Flameeyes" Pettenò <flameeyes@gmail.com>
|
5
|
+
# Portions inspired by elf.py
|
6
|
+
# Copyright © 2002 Netgraft Corporation
|
7
|
+
# Portions inspired by elf.h
|
8
|
+
# Copyright © 1995-2006 Free Software Foundation, Inc.
|
9
|
+
#
|
10
|
+
# This program is free software; you can redistribute it and/or modify
|
11
|
+
# it under the terms of the GNU General Public License as published by
|
12
|
+
# the Free Software Foundation; either version 2 of the License, or
|
13
|
+
# (at your option) any later version.
|
14
|
+
#
|
15
|
+
# This program is distributed in the hope that it will be useful,
|
16
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
17
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
18
|
+
# GNU General Public License for more details.
|
19
|
+
#
|
20
|
+
# You should have received a copy of the GNU General Public License
|
21
|
+
# along with this generator; if not, write to the Free Software
|
22
|
+
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
23
|
+
|
24
|
+
require 'elf/symbol/demangler_gcc3'
|
25
|
+
|
26
|
+
module Elf
|
27
|
+
class Symbol
|
28
|
+
class Binding < Value
|
29
|
+
fill(
|
30
|
+
0 => [ :Local, 'Local symbol' ],
|
31
|
+
1 => [ :Global, 'Global symbol' ],
|
32
|
+
2 => [ :Weak, 'Weak symbol' ],
|
33
|
+
# This one is inferred out of libpam.so
|
34
|
+
3 => [ :Number, 'Number of defined type' ]
|
35
|
+
)
|
36
|
+
|
37
|
+
class GNU < Value
|
38
|
+
fill(
|
39
|
+
10 => [ :Unique, 'Unique symbol' ]
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
OsSpecific = 10..12
|
44
|
+
ProcSpecific = 13..15
|
45
|
+
|
46
|
+
SpecialRanges = {
|
47
|
+
"STB_LOOS" => OsSpecific,
|
48
|
+
"STB_LOPROC" => ProcSpecific
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
class Type < Value
|
53
|
+
fill(
|
54
|
+
0 => [ :None, 'Unspecified' ],
|
55
|
+
1 => [ :Object, 'Data object' ],
|
56
|
+
2 => [ :Func, 'Code object' ],
|
57
|
+
3 => [ :Section, 'Associated with a section' ],
|
58
|
+
4 => [ :File, 'File name' ],
|
59
|
+
5 => [ :Common, 'Common data object' ],
|
60
|
+
6 => [ :TLS, 'Thread-local data object' ]
|
61
|
+
)
|
62
|
+
|
63
|
+
class GNU < Value
|
64
|
+
fill(
|
65
|
+
10 => [ :IFunc, 'Indirect function' ]
|
66
|
+
)
|
67
|
+
end
|
68
|
+
|
69
|
+
OsSpecific = 10..12
|
70
|
+
ProcSpecific = 13..15
|
71
|
+
SpecialRanges = {
|
72
|
+
"STT_LOOS" => OsSpecific,
|
73
|
+
"STT_LOPROC" => ProcSpecific
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
class Visibility < Value
|
78
|
+
fill(
|
79
|
+
0 => [ :Default, 'Default visibility' ],
|
80
|
+
1 => [ :Internal, 'Processor-specific hidden visibility' ],
|
81
|
+
2 => [ :Hidden, 'Hidden visibility' ],
|
82
|
+
3 => [ :Protected, 'Protected visibility' ],
|
83
|
+
4 => [ :Exported, 'Exported symbol' ],
|
84
|
+
5 => [ :Singleton, 'Singleton symbol' ],
|
85
|
+
6 => [ :Eliminate, 'Symbol to be eliminated' ]
|
86
|
+
)
|
87
|
+
end
|
88
|
+
|
89
|
+
attr_reader :value, :size, :other, :bind, :type, :idx, :visibility, :file
|
90
|
+
|
91
|
+
# Create a new Symbol object reading the symbol structure from the file.
|
92
|
+
# This function assumes that the elf file is aligned ad the
|
93
|
+
# start of a symbol structure, and returns the file moved at the
|
94
|
+
# start of the symbol.
|
95
|
+
def initialize(elf, symsect, idx)
|
96
|
+
@symsect = symsect
|
97
|
+
@idx = idx
|
98
|
+
|
99
|
+
case elf.elf_class
|
100
|
+
when Class::Elf32
|
101
|
+
@name = elf.read_word
|
102
|
+
@value = elf.read_addr
|
103
|
+
@size = elf.read_word
|
104
|
+
info = elf.read_u8
|
105
|
+
@other = elf.read_u8
|
106
|
+
@section = elf.read_section
|
107
|
+
when Class::Elf64
|
108
|
+
@name = elf.read_word
|
109
|
+
info = elf.read_u8
|
110
|
+
@other = elf.read_u8
|
111
|
+
@section = elf.read_section
|
112
|
+
@value = elf.read_addr
|
113
|
+
@size = elf.read_xword
|
114
|
+
end
|
115
|
+
|
116
|
+
begin
|
117
|
+
type_value = info & 0xF
|
118
|
+
@type = case
|
119
|
+
when Type::OsSpecific.include?(type_value)
|
120
|
+
# Assume always GNU for now, but it's wrong
|
121
|
+
Type::GNU[type_value]
|
122
|
+
else
|
123
|
+
Type[type_value]
|
124
|
+
end
|
125
|
+
|
126
|
+
binding_value = info >> 4
|
127
|
+
@bind = case
|
128
|
+
when Binding::OsSpecific.include?(binding_value)
|
129
|
+
# Assume always GNU for now, but it's wrong
|
130
|
+
Binding::GNU[binding_value]
|
131
|
+
else
|
132
|
+
Binding[binding_value]
|
133
|
+
end
|
134
|
+
|
135
|
+
rescue Elf::Value::OutOfBound => e
|
136
|
+
e.append_message("While processing symbol #{@idx}. Symbol info: 0x#{info.hex}")
|
137
|
+
raise e
|
138
|
+
end
|
139
|
+
|
140
|
+
begin
|
141
|
+
@visibility = Visibility[@other & 0x03]
|
142
|
+
rescue Elf::Value::OutOfBound => e
|
143
|
+
e.append_message("While procesing symbol #{@idx}. Symbol other info: 0x#{@other.hex}")
|
144
|
+
raise e
|
145
|
+
end
|
146
|
+
|
147
|
+
@file = elf
|
148
|
+
end
|
149
|
+
|
150
|
+
class InvalidName < Exception
|
151
|
+
def initialize(name_idx, sym, symsect)
|
152
|
+
super("Invalid name index in #{symsect.link.name} #{name_idx} for symbol #{sym.idx}")
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def name
|
157
|
+
# We didn't read the name in form of string yet;
|
158
|
+
if @name.is_a? Integer and @symsect.link
|
159
|
+
begin
|
160
|
+
name = @symsect.link[@name]
|
161
|
+
rescue StringTable::InvalidIndex
|
162
|
+
raise InvalidName.new(@name, self, @symsect)
|
163
|
+
end
|
164
|
+
@name = name if name
|
165
|
+
end
|
166
|
+
|
167
|
+
@name
|
168
|
+
end
|
169
|
+
|
170
|
+
# Alias to_s to name so that using this in a string will report the name
|
171
|
+
alias :to_s :name
|
172
|
+
|
173
|
+
def section
|
174
|
+
# We didn't read the section yet.
|
175
|
+
@section = nil if @section.is_a? Integer and @section == 0
|
176
|
+
|
177
|
+
if @section.is_a? Integer and
|
178
|
+
not Section::Reserved.include?(@section) and
|
179
|
+
@file.has_section?(@section)
|
180
|
+
|
181
|
+
@section = @file[@section]
|
182
|
+
end
|
183
|
+
|
184
|
+
@section
|
185
|
+
end
|
186
|
+
|
187
|
+
def version
|
188
|
+
# bit 15 is meant to say that this symbol is _not_ the default
|
189
|
+
# version to link to; we don't care about that here so we simply
|
190
|
+
# ignore its presence.
|
191
|
+
version_idx = version_index & ~(1 << 15)
|
192
|
+
|
193
|
+
return nil unless version_idx && version_idx >= 1
|
194
|
+
|
195
|
+
return '' if version_idx == 1
|
196
|
+
|
197
|
+
if section.nil? or @file['.gnu.version_d'][version_idx].nil?
|
198
|
+
return @file['.gnu.version_r'][version_idx][:name]
|
199
|
+
else
|
200
|
+
return @file['.gnu.version_d'][version_idx][:names][0]
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
# the default symbol version is the one that the link editor will
|
205
|
+
# use when linking against the library; any symbol is the default
|
206
|
+
# symbol unless bit 15 of its version index is set.
|
207
|
+
#
|
208
|
+
# An undefined symbol cannot be the default symbol
|
209
|
+
def version_default?
|
210
|
+
!section.nil? and (version_index & (1 << 15) == 0)
|
211
|
+
end
|
212
|
+
|
213
|
+
def defined?
|
214
|
+
return false if section.nil?
|
215
|
+
return false if section.is_a?(Integer)
|
216
|
+
return false if bind == Binding::Weak and value == 0
|
217
|
+
return true
|
218
|
+
end
|
219
|
+
|
220
|
+
# Exception raised when the NM code for a given symbol is unknown.
|
221
|
+
class UnknownNMCode < Exception
|
222
|
+
def initialize(symbol)
|
223
|
+
section = if symbol.section.nil?
|
224
|
+
nil
|
225
|
+
elsif symbol.section.is_a?(Integer)
|
226
|
+
symbol.section.hex
|
227
|
+
else
|
228
|
+
symbol.section.name
|
229
|
+
end
|
230
|
+
|
231
|
+
super("Unknown NM code for symbol #{symbol.name} in section #{section}")
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
# Show the letter code as compatible with GNU nm
|
236
|
+
#
|
237
|
+
# This function has been moved inside the library since multiple
|
238
|
+
# tools based on ruby-elf would be using these code to report
|
239
|
+
# symbols, and since the code is complex it's easier to have it
|
240
|
+
# here.
|
241
|
+
#
|
242
|
+
# The resturned value is a one-letter string. The function may
|
243
|
+
# raise an UnknownNMCode exception.
|
244
|
+
def nm_code
|
245
|
+
@nmflag ||= nm_code_internal
|
246
|
+
end
|
247
|
+
|
248
|
+
# Convenience function for the first tile the nm code is requested.
|
249
|
+
def nm_code_internal
|
250
|
+
nmflag = nil
|
251
|
+
|
252
|
+
case
|
253
|
+
when idx == 0
|
254
|
+
return " "
|
255
|
+
|
256
|
+
# When the section is nil, it means it goes into the Undef
|
257
|
+
# section, and the symbol is not defined.
|
258
|
+
when section.nil?
|
259
|
+
nmflag = "U"
|
260
|
+
|
261
|
+
when bind == Binding::Weak
|
262
|
+
nmflag = case type
|
263
|
+
when Type::Object then "V"
|
264
|
+
else "W"
|
265
|
+
end
|
266
|
+
|
267
|
+
nmflag.downcase! if value == 0
|
268
|
+
|
269
|
+
when section.is_a?(Integer)
|
270
|
+
nmflag = case section
|
271
|
+
when Elf::Section::Abs then "A"
|
272
|
+
when Elf::Section::Common then "C"
|
273
|
+
else nil
|
274
|
+
end
|
275
|
+
|
276
|
+
else
|
277
|
+
# Find the nm(1) code for the section.
|
278
|
+
nmflag = section.nm_code
|
279
|
+
end
|
280
|
+
|
281
|
+
# If we haven't found the flag with the above code, we don't
|
282
|
+
# know what to use, so raise exception.
|
283
|
+
raise UnknownNMCode.new(self) if nmflag.nil?
|
284
|
+
|
285
|
+
nmflag = nmflag.dup
|
286
|
+
|
287
|
+
nmflag.downcase! if bind == Binding::Local
|
288
|
+
|
289
|
+
return nmflag
|
290
|
+
end
|
291
|
+
|
292
|
+
# Reports the symbol's address as a string, if any is provided
|
293
|
+
#
|
294
|
+
# Reports a string full of whitespace if the symbols is not
|
295
|
+
# defined (as there is no address)
|
296
|
+
def address_string
|
297
|
+
addrsize = (@file.elf_class == Elf::Class::Elf32 ? 8 : 16)
|
298
|
+
|
299
|
+
if section
|
300
|
+
sprintf("%0#{addrsize}x", value)
|
301
|
+
else
|
302
|
+
' ' * addrsize
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
# Check whether two symbols are the same
|
307
|
+
#
|
308
|
+
# This function compares the name, version and section of two
|
309
|
+
# symbols to tell if they are the same symbol.
|
310
|
+
def ==(other)
|
311
|
+
return false unless other.is_a? Symbol
|
312
|
+
|
313
|
+
return false unless name == other.name
|
314
|
+
return false unless version == other.version
|
315
|
+
|
316
|
+
return false if section == nil and other.section != nil
|
317
|
+
return false if section != nil and other.section == nil
|
318
|
+
|
319
|
+
return true
|
320
|
+
end
|
321
|
+
|
322
|
+
def eql?(other)
|
323
|
+
return self == other
|
324
|
+
end
|
325
|
+
|
326
|
+
# Check whether one symbol is compatible with the other
|
327
|
+
#
|
328
|
+
# This function compares the name and version of two symbols, and
|
329
|
+
# ensures that only one of them is undefined; this allows to
|
330
|
+
# establish whether one symbol might be satisfied by another.
|
331
|
+
def =~(other)
|
332
|
+
return false unless other.is_a? Symbol
|
333
|
+
|
334
|
+
return false unless name == other.name
|
335
|
+
return false unless version == other.version
|
336
|
+
|
337
|
+
return false if section == nil and other.section == nil
|
338
|
+
return false if section != nil and other.section != nil
|
339
|
+
|
340
|
+
return true
|
341
|
+
end
|
342
|
+
|
343
|
+
Demanglers = [ Elf::Symbol::Demangler::GCC3 ]
|
344
|
+
def demangle
|
345
|
+
return @demangled if @demangled
|
346
|
+
|
347
|
+
Demanglers.each do |demangler|
|
348
|
+
break if (@demangled ||= demangler.demangle(name))
|
349
|
+
end
|
350
|
+
|
351
|
+
# We're going to remove top-namespace specifications as we don't
|
352
|
+
# need them, but it's easier for the demangler to still emit
|
353
|
+
# them.
|
354
|
+
@demangled.gsub!(/(^| |\()::/, '\1') if @demangled
|
355
|
+
|
356
|
+
return @demangled ||= name
|
357
|
+
end
|
358
|
+
|
359
|
+
private
|
360
|
+
def version_index
|
361
|
+
return nil if (!@file.has_section?('.gnu.version')) or
|
362
|
+
( section.is_a?(Integer) and section == Elf::Section::Abs ) or
|
363
|
+
( section.is_a? Elf::Section and section.name == ".bss" )
|
364
|
+
|
365
|
+
@file['.gnu.version'][@idx]
|
366
|
+
end
|
367
|
+
end
|
368
|
+
end
|