Module: ELFTools::Dynamic::Symbols
- Included in:
- ELFTools::Dynamic
- Defined in:
- lib/elftools/dynamic/symbols.rb
Overview
This module is included by ELFTools::Dynamic and reads through the methods there, so it cannot be included on its own.
The symbols a file is loaded by, which the tags point at.
Instance Method Summary collapse
-
#each_symbol {|symbol| ... } ⇒ Enumerator<ELFTools::Sections::Symbol>, Array<ELFTools::Sections::Symbol>
(also: #each_symbols)
Iterate all symbols.
-
#num_symbols ⇒ Integer
How many symbols the tags reach.
-
#symbol_at(n) ⇒ ELFTools::Sections::Symbol
Get the +n+-th symbol.
-
#symbol_by_name(name) ⇒ ELFTools::Sections::Symbol?
Get symbol by its name.
-
#symbols ⇒ Array<ELFTools::Sections::Symbol>
The symbols the tags point at, which is where a file that has been stripped of its sections still records them.
Instance Method Details
#each_symbol {|symbol| ... } ⇒ Enumerator<ELFTools::Sections::Symbol>, Array<ELFTools::Sections::Symbol> Also known as: each_symbols
Iterate all symbols.
Symbols are lazy loaded, so #symbol_by_name only creates the symbols it has to look at.
71 72 73 74 75 |
# File 'lib/elftools/dynamic/symbols.rb', line 71 def each_symbol(&block) return enum_for(:each_symbol) unless block_given? Array.new(num_symbols) { |i| symbol_at(i).tap(&block) } end |
#num_symbols ⇒ Integer
How many symbols the tags reach.
Nothing a file is loaded by records how large its symbol table is. The
loader never enumerates it: it looks a name up through a hash table and
jumps straight to an index, so where the table ends is none of its
business. Two things bound it instead, the hash table that indexes the
names a file exports and the relocations that name a symbol by index,
and the answer is how far the further of the two reaches. Only DT_HASH
records the number outright.
This is therefore a lower bound. A symbol that is neither indexed by the hash table nor named by a relocation is invisible to both, and is missing from the count. #symbol_at is exact for any index.
58 59 60 |
# File 'lib/elftools/dynamic/symbols.rb', line 58 def num_symbols @num_symbols ||= (hash_tables.map(&:num_symbols) + [count_from_relocations]).compact.max || 0 end |
#symbol_at(n) ⇒ ELFTools::Sections::Symbol
We cannot do bound checking of n here, because nothing records how
many symbols there are. #num_symbols is a lower bound rather than a
bound, so checking against it would hide symbols this method reads
correctly.
Get the +n+-th symbol.
Symbols are lazy loaded.
28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/elftools/dynamic/symbols.rb', line 28 def symbol_at(n) return if n.negative? @symbol_at_map ||= {} @symbol_at_map[n] ||= begin klass = Structs::ELF_sym[header.elf_class] # An entry takes what its structure takes, which is also what # DT_SYMENT records and what a file has no way of disagreeing with. sym = read_struct(klass, sym_offset + (n * struct(klass).num_bytes)) Sections::Symbol.new(sym, stream, symstr: method(:string_table), machine: @machine) end end |
#symbol_by_name(name) ⇒ ELFTools::Sections::Symbol?
Get symbol by its name.
The hash tables answer first, which is the lookup the loader itself performs and takes no scanning. They do not index every symbol, and a file need not record one at all, so a name they do not lead to is searched for among the symbols #symbols reaches.
103 104 105 106 107 108 109 110 |
# File 'lib/elftools/dynamic/symbols.rb', line 103 def symbol_by_name(name) # Lazily, so that a table is only read when the ones before it have # not led anywhere. index = hash_tables.lazy.filter_map { |table| table.index_of(name) { |i| symbol_at(i).name == name } }.first return symbol_at(index) if index each_symbol.find { |symbol| symbol.name == name } end |
#symbols ⇒ Array<ELFTools::Sections::Symbol>
The symbols the tags point at, which is where a file that has been stripped of its sections still records them.
As many of them as #num_symbols reaches.
88 89 90 |
# File 'lib/elftools/dynamic/symbols.rb', line 88 def symbols each_symbol.to_a end |