Class: ELFTools::Structs::ELFStruct
- Inherits:
-
BinData::Record
- Object
- BinData::Record
- ELFTools::Structs::ELFStruct
- Defined in:
- lib/elftools/structs.rb
Overview
The base structure to define common methods.
Direct Known Subclasses
ELF32_Phdr, ELF32_sym, ELF64_Phdr, ELF64_sym, ELF_Dyn, ELF_Ehdr, ELF_GnuHash, ELF_Hash, ELF_Nhdr, ELF_Rel, ELF_Rela, ELF_Shdr, ELF_Verdaux, ELF_Verdef, ELF_Vernaux, ELF_Verneed
Constant Summary collapse
- CHOICE_SIZE_T =
DRY. Many fields have different type in different arch.
proc do |t = 'uint'| { selection: :elf_class, choices: { 32 => :"#{t}32", 64 => :"#{t}64" }, copy_on_change: true } end
Instance Attribute Summary collapse
-
#elf_class ⇒ Integer
32 or 64.
-
#offset ⇒ Integer
The file offset of this header.
Class Method Summary collapse
-
.new(*args) ⇒ Object
Hooks the constructor.
-
.pack(val, bytes) ⇒ String
deprecated
Deprecated.
Nothing here packs a patch by hand anymore, see #patches. This is kept for anyone who called it and goes in the next major.
-
.self_endian ⇒ :little, :big
Gets the endianness of current class.
Instance Method Summary collapse
-
#patches ⇒ Hash{Integer => String}
Which bytes of this structure have been changed since it was read.
-
#read(io) ⇒ ELFTools::Structs::ELFStruct
Reads the structure, remembering the bytes it was read from.
Instance Attribute Details
#elf_class ⇒ Integer
Returns 32 or 64.
18 19 20 |
# File 'lib/elftools/structs.rb', line 18 def elf_class @elf_class end |
#offset ⇒ Integer
Returns The file offset of this header.
19 20 21 |
# File 'lib/elftools/structs.rb', line 19 def offset @offset end |
Class Method Details
.new(*args) ⇒ Object
Hooks the constructor.
BinData::Record doesn't allow us to override #initialize, so we hack new here.
Keyword arguments have to be taken as a trailing Hash instead of **kwargs: bindata
defines new on each record class taking *args only, then re-dispatches it to the
endian-specific subclass this method actually runs on, which collapses the caller's
keywords into a positional Hash on the way. See override_new_in_class in
https://github.com/dmendel/bindata/blob/master/lib/bindata/dsl.rb, which is the same in
2.5.1, 3.0.0, and master.
99 100 101 102 103 |
# File 'lib/elftools/structs.rb', line 99 def new(*args) kwargs = args.last.is_a?(Hash) ? args.last : {} offset = kwargs.delete(:offset) super.tap { |obj| obj.offset = offset } end |
.pack(val, bytes) ⇒ String
Nothing here packs a patch by hand anymore, see #patches. This is kept for anyone who called it and goes in the next major.
Packs an integer to string.
119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/elftools/structs.rb', line 119 def pack(val, bytes) raise ArgumentError, "Not supported assign type #{val.class}" unless val.is_a?(Integer) number = val & ((1 << (8 * bytes)) - 1) out = [] bytes.times do out << (number & 0xff) number >>= 8 end out = out.pack('C*') self_endian == :little ? out : out.reverse end |
.self_endian ⇒ :little, :big
Gets the endianness of current class.
107 108 109 |
# File 'lib/elftools/structs.rb', line 107 def self_endian bindata_name[-2..] == 'be' ? :big : :little end |
Instance Method Details
#patches ⇒ Hash{Integer => String}
Which bytes of this structure have been changed since it was read.
Every field answers alike, however deeply it is nested, because what is compared is the bytes the structure occupies rather than the assignments that were made to it. A field assigned the value it already held leaves nothing behind.
45 46 47 48 49 |
# File 'lib/elftools/structs.rb', line 45 def patches return {} if @source.nil? changed_runs(@source, to_binary_s) end |
#read(io) ⇒ ELFTools::Structs::ELFStruct
Reads the structure, remembering the bytes it was read from.
They are taken back off the stream. A stream that cannot be seeked is serialized instead.
27 28 29 30 |
# File 'lib/elftools/structs.rb', line 27 def read(io) start = io.pos if io.respond_to?(:pos) super.tap { @source = start.nil? ? to_binary_s : bytes_read(io, start) } end |