class ELFTools::Structs::ELFStruct

The base structure to define common methods.

Constants

CHOICE_SIZE_T

DRY. Many fields have different type in different arch.

Attributes

elf_class[RW]
offset[RW]

Public Class Methods

new(*args) click to toggle source

Hooks the constructor.

BinData::Record doesn't allow us to override #initialize, so we hack new here.

Calls superclass method
# File lib/elftools/structs.rb, line 31
def new(*args)
  # XXX: The better implementation is +new(*args, **kwargs)+, but we can't do this unless bindata changed
  # lib/bindata/dsl.rb#override_new_in_class to invoke +new+ with both +args+ and +kwargs+.
  kwargs = args.last.is_a?(Hash) ? args.last : {}
  offset = kwargs.delete(:offset)
  super.tap do |obj|
    obj.offset = offset
    obj.field_names.each do |f|
      m = "#{f}=".to_sym
      old_method = obj.singleton_method(m)
      obj.singleton_class.send(:undef_method, m)
      obj.define_singleton_method(m) do |val|
        org = obj.send(f)
        obj.patches[org.abs_offset] = ELFStruct.pack(val, org.num_bytes)
        old_method.call(val)
      end
    end
  end
end
pack(val, bytes) click to toggle source

Packs an integer to string. @param [Integer] val @param [Integer] bytes @return [String]

# File lib/elftools/structs.rb, line 61
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() click to toggle source

Gets the endianness of current class. @return [:little, :big] The endianness.

# File lib/elftools/structs.rb, line 53
def self_endian
  bindata_name[-2..-1] == 'be' ? :big : :little
end

Public Instance Methods

patches() click to toggle source

Records which fields have been patched. @return [Hash{Integer => Integer}] Patches.

# File lib/elftools/structs.rb, line 23
def patches
  @patches ||= {}
end