BFD 1.3.3
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/ChangeLog +2 -0
- data/LICENSE +674 -0
- data/LICENSE.README +8 -0
- data/README +48 -0
- data/examples/bfd_info.rb +30 -0
- data/examples/list_sections.rb +25 -0
- data/examples/list_symbols.rb +25 -0
- data/lib/BFD.rb +468 -0
- data/module/BFD.c +388 -0
- data/module/BFD.h +68 -0
- data/module/extconf.rb +14 -0
- data/module/rdoc_input/BFD.rb +266 -0
- data/module/ruby_compat.c +17 -0
- data/module/ruby_compat.h +28 -0
- data/tests/ut_bfd.rb +597 -0
- metadata +70 -0
data/LICENSE.README
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
The BFD Ruby extension is released under the GNU Public License version 3.0,
|
|
2
|
+
distributed in this package as LICENSE.
|
|
3
|
+
|
|
4
|
+
The intent of this license choice is not to restrict distribution, but for
|
|
5
|
+
compatibility with the distribution terms of opdis and GNU binutils.
|
|
6
|
+
|
|
7
|
+
Contact community@thoughtgang.org for alternative licensing arrangements if
|
|
8
|
+
the GPLv3 is too restrictive.
|
data/README
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
|
|
2
|
+
BFD (Binary File Descriptor)
|
|
3
|
+
|
|
4
|
+
A Ruby C extension (and gem) for the GNU Binutils libbfd library.
|
|
5
|
+
|
|
6
|
+
Note: this is not a complete implementation of the BFD API; it is only
|
|
7
|
+
intended for use with the Opcodes or Opdis Ruby extensions.
|
|
8
|
+
|
|
9
|
+
BUILD
|
|
10
|
+
-----
|
|
11
|
+
|
|
12
|
+
The standard C extension build process is used:
|
|
13
|
+
|
|
14
|
+
bash# ruby extconf.rb
|
|
15
|
+
bash# make
|
|
16
|
+
|
|
17
|
+
Note that the Ruby headers must be installed. On Ubuntu, these are in the
|
|
18
|
+
ruby-dev or ruby1.9-dev package.
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
The gem is built using the standard gem build command:
|
|
22
|
+
|
|
23
|
+
bash# gem build Opcodes.gemspec
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
The top-level Makefile supports each of these builds with the commands
|
|
27
|
+
'make' and 'make gem'.
|
|
28
|
+
|
|
29
|
+
bash# make
|
|
30
|
+
# builds C extension
|
|
31
|
+
bash# make gem
|
|
32
|
+
# builds the gem
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
EXAMPLES
|
|
37
|
+
|
|
38
|
+
Extended examples are provided in the 'examples' directory. The following
|
|
39
|
+
code snippets give a brief overview of using the BFD extension.
|
|
40
|
+
|
|
41
|
+
require 'BFD'
|
|
42
|
+
|
|
43
|
+
t = Bfd::Target.new('/tmp/a.out')
|
|
44
|
+
t.symbols.values.each { |sym| puts sym }
|
|
45
|
+
|
|
46
|
+
Bfd::Target.new('/tmp/a.out') do |tgt|
|
|
47
|
+
tgt.sections.each { |name, sec| puts sec }
|
|
48
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# Show BFD Info
|
|
3
|
+
# Copyright 2010 Thoughtgang <http://www.thoughtgang.org>
|
|
4
|
+
|
|
5
|
+
require 'BFD'
|
|
6
|
+
|
|
7
|
+
def display_info(filename)
|
|
8
|
+
Bfd::Target.new(filename) do |tgt|
|
|
9
|
+
puts "#{tgt.id}: #{tgt.filename}"
|
|
10
|
+
|
|
11
|
+
puts "#{tgt.flavour} #{tgt.format}: #{tgt.format_flags.join(',')}"
|
|
12
|
+
|
|
13
|
+
puts "#{tgt.type}: #{tgt.type_flags.join(',')}"
|
|
14
|
+
|
|
15
|
+
puts "#{tgt.sections.length} Sections #{tgt.symbols.length} Symbols"
|
|
16
|
+
|
|
17
|
+
puts "Info:"
|
|
18
|
+
info = tgt.arch_info
|
|
19
|
+
info[:endian] = tgt.endian
|
|
20
|
+
info[:entry] = "0x%X" % (tgt.start_address) if tgt.start_address
|
|
21
|
+
info.keys.sort.each {|k| puts "\t#{k}: #{info[k]}" }
|
|
22
|
+
|
|
23
|
+
puts
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
if __FILE__ == $0
|
|
28
|
+
raise "Usage: #{$0} FILE [FILE...]" if ARGV.length == 0
|
|
29
|
+
ARGV.each { |f| display_info(f) }
|
|
30
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# List BFD Sections
|
|
3
|
+
# Copyright 2010 Thoughtgang <http://www.thoughtgang.org>
|
|
4
|
+
|
|
5
|
+
require 'BFD'
|
|
6
|
+
|
|
7
|
+
def display_section(sec)
|
|
8
|
+
puts "#{sec.id}: #{sec.name}"
|
|
9
|
+
puts "\tFlags: #{sec.flags.join(',')}"
|
|
10
|
+
puts "\tFile Pos: 0x%X VMA: 0x%X LMA: 0x%X" % [sec.file_pos, sec.vma, sec.lma]
|
|
11
|
+
puts "\tSize: #{sec.size} Alignment: #{2**sec.alignment_power}"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def list_secs(filename)
|
|
15
|
+
Bfd::Target.new(filename) do |tgt
|
|
16
|
+
puts "#{tgt.id}: #{tgt.filename}"
|
|
17
|
+
tgt.sections.values.sort_by { |s| s.index }.each { |s| display_section s }
|
|
18
|
+
puts
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
if __FILE__ == $0
|
|
23
|
+
raise "Usage: #{$0} FILE [FILE...]" if ARGV.length == 0
|
|
24
|
+
ARGV.each { |f| list_secs(f) }
|
|
25
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# List BFD Symbols
|
|
3
|
+
# Copyright 2010 Thoughtgang <http://www.thoughtgang.org>
|
|
4
|
+
|
|
5
|
+
require 'BFD'
|
|
6
|
+
|
|
7
|
+
def display_symbol(sym)
|
|
8
|
+
puts "%s : 0x%X" % [sym.name, sym.value]
|
|
9
|
+
puts "\t#{sym.binding}"
|
|
10
|
+
puts "\t#{sym.section}"
|
|
11
|
+
puts "\tFlags: #{sym.flags.join(',')}"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def list_syms(filename)
|
|
15
|
+
Bfd::Target.new(filename) do |tgt|
|
|
16
|
+
puts "#{tgt.id}: #{tgt.filename}"
|
|
17
|
+
tgt.symbols.keys.sort.each { |name| display_symbol tgt.symbols[name] }
|
|
18
|
+
puts
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
if __FILE__ == $0
|
|
23
|
+
raise "Usage: #{$0} FILE [FILE...]" if ARGV.length == 0
|
|
24
|
+
ARGV.each { |f| list_syms(f) }
|
|
25
|
+
end
|
data/lib/BFD.rb
ADDED
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# Copyright 2010 Thoughtgang <http://www.thoughtgang.org>
|
|
3
|
+
# Ruby additions to BFD module
|
|
4
|
+
|
|
5
|
+
require 'BFDext' # Load C extension wrapping libbfd.so
|
|
6
|
+
require 'tempfile' # For buffer target
|
|
7
|
+
|
|
8
|
+
# TODO: Support reloc, line no, debug
|
|
9
|
+
module Bfd
|
|
10
|
+
|
|
11
|
+
class Target
|
|
12
|
+
|
|
13
|
+
=begin rdoc
|
|
14
|
+
core dump
|
|
15
|
+
=end
|
|
16
|
+
FORMAT_CORE = 'core'
|
|
17
|
+
=begin rdoc
|
|
18
|
+
linkable (executable, shared library) or relocatable object file
|
|
19
|
+
=end
|
|
20
|
+
FORMAT_OBJECT = 'object'
|
|
21
|
+
=begin rdoc
|
|
22
|
+
library archive (.ar)
|
|
23
|
+
=end
|
|
24
|
+
FORMAT_ARCHIVE = 'archive'
|
|
25
|
+
=begin rdoc
|
|
26
|
+
unrecognized/unsupported file
|
|
27
|
+
=end
|
|
28
|
+
FORMAT_UNKNOWN = 'unknown'
|
|
29
|
+
=begin rdoc
|
|
30
|
+
BFD object type
|
|
31
|
+
=end
|
|
32
|
+
FORMATS = [ FORMAT_UNKNOWN, FORMAT_CORE, FORMAT_OBJECT, FORMAT_ARCHIVE ]
|
|
33
|
+
|
|
34
|
+
=begin rdoc
|
|
35
|
+
BFD file format.
|
|
36
|
+
Defined in /usr/include/bfd.h : enum bfd_flavour
|
|
37
|
+
=end
|
|
38
|
+
FLAVOURS = %w{ unknown aout coff ecoff xcoff elf ieee nlm oasys tekhex srec
|
|
39
|
+
verilog ihex som os0k versados msdos ovax evax mmo mach_o
|
|
40
|
+
pef pef_xlib sym }
|
|
41
|
+
|
|
42
|
+
=begin rdoc
|
|
43
|
+
Byte order.
|
|
44
|
+
Defined in /usr/include/bfd.h : enum bfd_endian
|
|
45
|
+
=end
|
|
46
|
+
ENDIAN = %w{ big little unknown }
|
|
47
|
+
|
|
48
|
+
# Note: other interesting flags such as HAS_RELOC, HAS_DEBUG will be handled
|
|
49
|
+
# by methods returning (empty?) collections of relocs/linenos/debug-syms.
|
|
50
|
+
=begin rdoc
|
|
51
|
+
=end
|
|
52
|
+
FLAG_EXEC = 'EXEC_P'
|
|
53
|
+
=begin rdoc
|
|
54
|
+
=end
|
|
55
|
+
FLAG_DYNAMIC = 'DYNAMIC'
|
|
56
|
+
|
|
57
|
+
=begin rdoc
|
|
58
|
+
File Format Flags.
|
|
59
|
+
Defined in /usr/include/bfd.h : struct bfd
|
|
60
|
+
=end
|
|
61
|
+
FLAGS = { 0x0001 => 'HAS_RELOC',
|
|
62
|
+
0x0002 => FLAG_EXEC,
|
|
63
|
+
0x0004 => 'LINEN',
|
|
64
|
+
0x0008 => 'DEBUG',
|
|
65
|
+
0x0010 => 'SYMS',
|
|
66
|
+
0x0020 => 'LOCALS',
|
|
67
|
+
0x0040 => FLAG_DYNAMIC,
|
|
68
|
+
0x0080 => 'WP_TEXT',
|
|
69
|
+
0x0100 => 'D_PAGED',
|
|
70
|
+
0x0200 => 'IS_RELAXABLE',
|
|
71
|
+
0x0400 => 'TRADITIONAL_FORMAT',
|
|
72
|
+
0x0800 => 'IN_MEMORY',
|
|
73
|
+
0x1000 => 'HAS_LOAD_PAGE',
|
|
74
|
+
0x2000 => 'LINKER_CREATED',
|
|
75
|
+
0x4000 => 'DETERMINISTIC_OUTPUT' }
|
|
76
|
+
|
|
77
|
+
=begin rdoc
|
|
78
|
+
Temporary file used if Target is instantiated from a buffer. BFD does not
|
|
79
|
+
operate on memory locations and requires a file descriptor; a temporary
|
|
80
|
+
file is therefore created on the filesystem when Target.from_buffer is
|
|
81
|
+
called. The temp file is deleted when Target.close is called.
|
|
82
|
+
=end
|
|
83
|
+
attr_accessor :temp_file
|
|
84
|
+
|
|
85
|
+
=begin rdoc
|
|
86
|
+
Create a new Target from a path or IO object. This just wraps for ext_new
|
|
87
|
+
and provides a default value for args.
|
|
88
|
+
NOTE: target should either be the path to a file or an IO object with a valid
|
|
89
|
+
read-only (i.e. opened with 'rb' flags) file descriptor returned by fileno().
|
|
90
|
+
File descriptors opened for write ('wb') will be rejected by libbfd.
|
|
91
|
+
=end
|
|
92
|
+
def self.new(target, args={})
|
|
93
|
+
bfd = ext_new(target, args)
|
|
94
|
+
yield bfd if (bfd and block_given?)
|
|
95
|
+
return bfd
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
=begin rdoc
|
|
99
|
+
Instantiate target from a buffer instead of from a file. Note: this creates
|
|
100
|
+
a temp_file which MUST be freed by calling Target.close, or by passing a
|
|
101
|
+
block to this method.
|
|
102
|
+
=end
|
|
103
|
+
def self.from_buffer(buf, args={})
|
|
104
|
+
|
|
105
|
+
f = Tempfile.new( 'bfd_target' )
|
|
106
|
+
f.write(buf)
|
|
107
|
+
|
|
108
|
+
bfd = ext_new(f.path, args)
|
|
109
|
+
raise "Unable to construct BFD" if not bfd
|
|
110
|
+
|
|
111
|
+
if not block_given?
|
|
112
|
+
@temp_file = f
|
|
113
|
+
return bfd
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# yield bfd object, then close temp file
|
|
117
|
+
yield bfd
|
|
118
|
+
f.close
|
|
119
|
+
nil
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
=begin rdoc
|
|
123
|
+
Free any resources used by BFD Target
|
|
124
|
+
=end
|
|
125
|
+
def close
|
|
126
|
+
if @temp_file
|
|
127
|
+
@temp_file.close
|
|
128
|
+
@temp_file = nil
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
=begin rdoc
|
|
133
|
+
Return an array of the names of the file format flags that are set.
|
|
134
|
+
See raw_format_flags and type_flags.
|
|
135
|
+
=end
|
|
136
|
+
def format_flags
|
|
137
|
+
flag_strings(@raw_format_flags)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
=begin rdoc
|
|
141
|
+
Is Target a valid BFD object (i.e. did BFD successfully parse it)
|
|
142
|
+
=end
|
|
143
|
+
def valid?
|
|
144
|
+
@format != FORMAT_UNKNOWN
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
=begin rdoc
|
|
148
|
+
Is target a standalone executable
|
|
149
|
+
=end
|
|
150
|
+
def is_executable?
|
|
151
|
+
@format == FORMAT_OBJECT and format_flags.include? FLAG_EXEC
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
=begin rdoc
|
|
155
|
+
Is target a shared library file (.so)
|
|
156
|
+
=end
|
|
157
|
+
def is_shared_object?
|
|
158
|
+
@format == FORMAT_OBJECT and format_flags.include? FLAG_DYNAMIC and
|
|
159
|
+
(not format_flags.include? FLAG_EXEC)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
=begin rdoc
|
|
163
|
+
Is target a relocatable object (not an executable or .so)
|
|
164
|
+
=end
|
|
165
|
+
def is_relocatable_object?
|
|
166
|
+
@format == FORMAT_OBJECT and (not format_flags.include? FLAG_DYNAMIC) and
|
|
167
|
+
(not format_flags.include? FLAG_EXEC)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
=begin rdoc
|
|
171
|
+
Return an array of the names of the target type flags that are set.
|
|
172
|
+
Note: These are the 'backend' flags for the BFD target type, and seem
|
|
173
|
+
to be a list of the flags *available* for the target type, not the list
|
|
174
|
+
of flags which are *set*. The format_flags field should always be used to
|
|
175
|
+
determine the flags which are set for a BFD target.
|
|
176
|
+
See raw_type_flags and format_flags.
|
|
177
|
+
=end
|
|
178
|
+
def type_flags()
|
|
179
|
+
flag_strings(@raw_type_flags)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
=begin rdoc
|
|
183
|
+
Return the target file format.
|
|
184
|
+
See raw_flavour.
|
|
185
|
+
=end
|
|
186
|
+
def flavour
|
|
187
|
+
FLAVOURS[@raw_flavour]
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
=begin rdoc
|
|
191
|
+
Return the byte order of the target.
|
|
192
|
+
See raw_endian.
|
|
193
|
+
=end
|
|
194
|
+
def endian
|
|
195
|
+
ENDIAN[@raw_endian]
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
=begin rdoc
|
|
200
|
+
Return the Bfd::Section in the target that contains <i>vma</i>, or <i>nil</i>.
|
|
201
|
+
=end
|
|
202
|
+
def section_for_vma(vma)
|
|
203
|
+
@sections.values.each do |s|
|
|
204
|
+
return s if (vma >= s.vma and vma < (s.vma + s.size))
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
return nil
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def to_s
|
|
211
|
+
"[#{@id}] #{@filename}"
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def inspect
|
|
215
|
+
"#{self.to_s} : #{self.flavour} #{@format} (#{@type} #{endian}-endian)"
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
private
|
|
219
|
+
=begin rdoc
|
|
220
|
+
Return an array of the names of bit-flags that are set.
|
|
221
|
+
=end
|
|
222
|
+
def flag_strings(flags)
|
|
223
|
+
f = []
|
|
224
|
+
FLAGS.each { |k,v| f << v if (flags & k > 0) }
|
|
225
|
+
return f
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
class Section
|
|
231
|
+
|
|
232
|
+
=begin rdoc
|
|
233
|
+
From bfd.h:
|
|
234
|
+
'Tells the OS to allocate space for this section when loading.
|
|
235
|
+
This is clear for a section containing debug information only.'
|
|
236
|
+
=end
|
|
237
|
+
FLAG_ALLOC = 'ALLOC'
|
|
238
|
+
=begin rdoc
|
|
239
|
+
From bfd.h:
|
|
240
|
+
'Tells the OS to load the section from the file when loading.
|
|
241
|
+
This is clear for a .bss section.'
|
|
242
|
+
=end
|
|
243
|
+
FLAG_LOAD = 'LOAD'
|
|
244
|
+
=begin rdoc
|
|
245
|
+
From bfd.h:
|
|
246
|
+
'The section contains data still to be relocated, so there is
|
|
247
|
+
some relocation information too.'
|
|
248
|
+
=end
|
|
249
|
+
FLAG_RELOC = 'RELOC'
|
|
250
|
+
=begin rdoc
|
|
251
|
+
From bfd.h:
|
|
252
|
+
'A signal to the OS that the section contains read only data.'
|
|
253
|
+
=end
|
|
254
|
+
FLAG_RO = 'READONLY'
|
|
255
|
+
=begin rdoc
|
|
256
|
+
From bfd.h:
|
|
257
|
+
'The section contains code only.'
|
|
258
|
+
=end
|
|
259
|
+
FLAG_CODE = 'CODE'
|
|
260
|
+
=begin rdoc
|
|
261
|
+
From bfd.h:
|
|
262
|
+
'The section contains data only.'
|
|
263
|
+
=end
|
|
264
|
+
FLAG_DATA = 'DATA'
|
|
265
|
+
=begin rdoc
|
|
266
|
+
From bfd.h:
|
|
267
|
+
'The section contains constructor information. This section
|
|
268
|
+
type is used by the linker to create lists of constructors and
|
|
269
|
+
destructors used by <<g++>>. When a back end sees a symbol
|
|
270
|
+
which should be used in a constructor list, it creates a new
|
|
271
|
+
section for the type of name (e.g., <<__CTOR_LIST__>>), attaches
|
|
272
|
+
the symbol to it, and builds a relocation. To build the lists
|
|
273
|
+
of constructors, all the linker has to do is catenate all the
|
|
274
|
+
sections called <<__CTOR_LIST__>> and relocate the data
|
|
275
|
+
contained within - exactly the operations it would peform on
|
|
276
|
+
standard data.'
|
|
277
|
+
=end
|
|
278
|
+
FLAG_CTOR = 'CONSTRUCTOR'
|
|
279
|
+
=begin rdoc
|
|
280
|
+
From bfd.h:
|
|
281
|
+
'The section contains thread local data.'
|
|
282
|
+
=end
|
|
283
|
+
FLAG_LOCAL = 'THREAD_LOCAL'
|
|
284
|
+
|
|
285
|
+
=begin rdoc
|
|
286
|
+
Section flags.
|
|
287
|
+
Defined in /usr/include/bfd.h : typedef struct bfd_section
|
|
288
|
+
=end
|
|
289
|
+
FLAGS={ 0x00000001 => FLAG_ALLOC,
|
|
290
|
+
0x00000002 => FLAG_LOAD,
|
|
291
|
+
0x00000004 => FLAG_RELOC,
|
|
292
|
+
0x00000008 => FLAG_RO,
|
|
293
|
+
0x00000010 => FLAG_CODE,
|
|
294
|
+
0x00000020 => FLAG_DATA,
|
|
295
|
+
0x00000040 => 'ROM',
|
|
296
|
+
0x00000080 => FLAG_CTOR,
|
|
297
|
+
0x00000100 => 'HAS_CONTENTS',
|
|
298
|
+
0x00000200 => 'NEVER_LOAD',
|
|
299
|
+
0x00000400 => FLAG_LOCAL,
|
|
300
|
+
0x00000800 => 'HAS_GOT_REF',
|
|
301
|
+
0x00001000 => 'IS_COMMON',
|
|
302
|
+
0x00002000 => 'DEBUGGING',
|
|
303
|
+
0x00004000 => 'IN_MEMORY',
|
|
304
|
+
0x00008000 => 'EXCLUDE',
|
|
305
|
+
0x00010000 => 'SORT_ENTRIES',
|
|
306
|
+
0x00020000 => 'LINK_ONCE',
|
|
307
|
+
0x00040000 => 'LINK_DUPLICATES_ONE_ONLY',
|
|
308
|
+
0x00080000 => 'LINK_DUPLICATES_SAME_SIZE',
|
|
309
|
+
0x00100000 => 'LINKER_CREATED',
|
|
310
|
+
0x00200000 => 'KEEP',
|
|
311
|
+
0x00400000 => 'SMALL_DATA',
|
|
312
|
+
0x00800000 => 'MERGE',
|
|
313
|
+
0x01000000 => 'STRINGS',
|
|
314
|
+
0x02000000 => 'GROUP',
|
|
315
|
+
0x04000000 => 'COFF_SHARED_LIBRARY',
|
|
316
|
+
0x08000000 => 'COFF_SHARED',
|
|
317
|
+
0x10000000 => 'TIC54X_BLOCK',
|
|
318
|
+
0x20000000 => 'TIC54X_CLINK',
|
|
319
|
+
0x40000000 => 'COFF_NOREAD'
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
=begin rdoc
|
|
323
|
+
Return an array of the names of the bit-flags that are set in Section.
|
|
324
|
+
See raw_flags.
|
|
325
|
+
=end
|
|
326
|
+
def flags()
|
|
327
|
+
f = []
|
|
328
|
+
FLAGS.each { |k,v| f << v if (@raw_flags & k > 0) }
|
|
329
|
+
return f
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
def to_s
|
|
333
|
+
@name
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
def inspect
|
|
337
|
+
spec = "%X (%X), %X" % [ @vma, @file_pos, @size ]
|
|
338
|
+
"[#{@id}] #{@name} #{spec}, #{flags.join('|')}"
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
class Symbol
|
|
343
|
+
|
|
344
|
+
=begin rdoc
|
|
345
|
+
From bfd.h:
|
|
346
|
+
'The symbol has local scope; <<static>> in <<C>>. The value
|
|
347
|
+
is the offset into the section of the data.'
|
|
348
|
+
=end
|
|
349
|
+
FLAG_LOCAL = 'LOCAL'
|
|
350
|
+
=begin rdoc
|
|
351
|
+
From bfd.h:
|
|
352
|
+
'The symbol has global scope; initialized data in <<C>>. The
|
|
353
|
+
value is the offset into the section of the data.'
|
|
354
|
+
=end
|
|
355
|
+
FLAG_GLOBAL = 'GLOBAL'
|
|
356
|
+
=begin rdoc
|
|
357
|
+
From bfd.h:
|
|
358
|
+
'The symbol is a debugging record. The value has an arbitrary
|
|
359
|
+
meaning, unless BSF_DEBUGGING_RELOC is also set.'
|
|
360
|
+
=end
|
|
361
|
+
FLAG_DEBUG = 'DEBUGGING'
|
|
362
|
+
=begin rdoc
|
|
363
|
+
From bfd.h:
|
|
364
|
+
'The symbol denotes a function entry point. Used in ELF,
|
|
365
|
+
perhaps others someday.'
|
|
366
|
+
=end
|
|
367
|
+
FLAG_FUNC = 'FUNCTION'
|
|
368
|
+
=begin rdoc
|
|
369
|
+
From bfd.h:
|
|
370
|
+
'A weak global symbol, overridable without warnings by
|
|
371
|
+
a regular global symbol of the same name.'
|
|
372
|
+
=end
|
|
373
|
+
FLAG_WEAK = 'WEAK'
|
|
374
|
+
=begin rdoc
|
|
375
|
+
From bfd.h:
|
|
376
|
+
'This symbol was created to point to a section, e.g. ELF's
|
|
377
|
+
STT_SECTION symbols.'
|
|
378
|
+
=end
|
|
379
|
+
FLAG_SEC = 'SECTION_SYM'
|
|
380
|
+
=begin rdoc
|
|
381
|
+
From bfd.h:
|
|
382
|
+
'Signal that the symbol is the label of constructor section.'
|
|
383
|
+
=end
|
|
384
|
+
FLAG_CTOR = 'CONSTRUCTOR'
|
|
385
|
+
=begin rdoc
|
|
386
|
+
From bfd.h:
|
|
387
|
+
'Signal that the symbol is indirect. This symbol is an indirect
|
|
388
|
+
pointer to the symbol with the same name as the next symbol.'
|
|
389
|
+
=end
|
|
390
|
+
FLAG_INDIRECT = 'INDIRECT'
|
|
391
|
+
=begin rdoc
|
|
392
|
+
From bfd.h:
|
|
393
|
+
'BSF_FILE marks symbols that contain a file name. This is used
|
|
394
|
+
for ELF STT_FILE symbols.'
|
|
395
|
+
=end
|
|
396
|
+
FLAG_FILE = 'FILE'
|
|
397
|
+
=begin rdoc
|
|
398
|
+
From bfd.h:
|
|
399
|
+
'Symbol is from dynamic linking information.'
|
|
400
|
+
=end
|
|
401
|
+
FLAG_DYNAMIC = 'DYNAMIC'
|
|
402
|
+
=begin rdoc
|
|
403
|
+
From bfd.h:
|
|
404
|
+
'The symbol denotes a data object. Used in ELF, and perhaps
|
|
405
|
+
others someday.'
|
|
406
|
+
=end
|
|
407
|
+
FLAG_OBJ = 'OBJECT'
|
|
408
|
+
=begin rdoc
|
|
409
|
+
From bfd.h:
|
|
410
|
+
'This symbol is thread local. Used in ELF.'
|
|
411
|
+
=end
|
|
412
|
+
FLAG_THREAD = 'THREAD_LOCAL'
|
|
413
|
+
|
|
414
|
+
=begin rdoc
|
|
415
|
+
Symbol flags.
|
|
416
|
+
Defined in /usr/include/bfd.h : typedef struct bfd_symbol.
|
|
417
|
+
From bfd.h:
|
|
418
|
+
'A normal C symbol would be one of:
|
|
419
|
+
<<BSF_LOCAL>>, <<BSF_COMMON>>, <<BSF_UNDEFINED>> or
|
|
420
|
+
<<BSF_GLOBAL>>.'
|
|
421
|
+
=end
|
|
422
|
+
FLAGS={ 0x000001 => FLAG_LOCAL,
|
|
423
|
+
0x000002 => FLAG_GLOBAL,
|
|
424
|
+
0x000004 => FLAG_DEBUG,
|
|
425
|
+
0x000008 => FLAG_FUNC,
|
|
426
|
+
0x000020 => 'KEEP',
|
|
427
|
+
0x000040 => 'KEEP_G',
|
|
428
|
+
0x000080 => FLAG_WEAK,
|
|
429
|
+
0x000100 => FLAG_SEC,
|
|
430
|
+
0x000200 => 'OLD_COMMON',
|
|
431
|
+
0x000400 => 'NOT_AT_END',
|
|
432
|
+
0x000800 => FLAG_CTOR,
|
|
433
|
+
0x001000 => 'WARNING',
|
|
434
|
+
0x002000 => FLAG_INDIRECT,
|
|
435
|
+
0x004000 => FLAG_FILE,
|
|
436
|
+
0x008000 => FLAG_DYNAMIC,
|
|
437
|
+
0x010000 => FLAG_OBJ,
|
|
438
|
+
0x020000 => 'DEBUGGING_RELOC',
|
|
439
|
+
0x040000 => FLAG_THREAD,
|
|
440
|
+
0x080000 => 'RELC',
|
|
441
|
+
0x100000 => 'SRELC',
|
|
442
|
+
0x200000 => 'SYNTHETIC',
|
|
443
|
+
0x400000 => 'GNU_INDIRECT_FUNCTION',
|
|
444
|
+
0x800000 => 'GNU_UNIQUE'
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
=begin rdoc
|
|
448
|
+
Return an array of the names of the bit-flags that are set in Symbol.
|
|
449
|
+
See raw_flags.
|
|
450
|
+
=end
|
|
451
|
+
def flags()
|
|
452
|
+
f = []
|
|
453
|
+
FLAGS.each { |k,v| f << v if (@raw_flags & k > 0) }
|
|
454
|
+
return f
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
def to_s
|
|
458
|
+
"#{@name} (#{@binding})"
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
def inspect
|
|
462
|
+
"%s 0x%X %s" % [@name, @value, flags.join('|')]
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
end
|
|
468
|
+
|