module ELFTools::Dynamic

Define common methods for dynamic sections and dynamic segments.

@note

This module can only be included by {ELFTools::Sections::DynamicSection}
and {ELFTools::Segments::DynamicSegment} because methods here assume some
attributes exist.

Public Instance Methods

each_tags(&block) click to toggle source

Iterate all tags.

@note

This method assume the following methods already exist:
  header
  tag_start

@yieldparam [ELFTools::Dynamic::Tag] tag @return [Enumerator<ELFTools::Dynamic::Tag>, Array<ELFTools::Dynamic::Tag>]

If block is not given, an enumerator will be returned.
Otherwise, return array of tags.
# File lib/elftools/dynamic.rb, line 21
def each_tags(&block)
  return enum_for(:each_tags) unless block_given?

  arr = []
  0.step do |i|
    tag = tag_at(i).tap(&block)
    arr << tag
    break if tag.header.d_tag == ELFTools::Constants::DT_NULL
  end
  arr
end
tag_at(n) click to toggle source

Get the n-th tag.

Tags are lazy loaded. @note

This method assume the following methods already exist:
  header
  tag_start

@note

We cannot do bound checking of +n+ here since the only way to get size
of tags is calling +tags.size+.

@param [Integer] n The index. @return [ELFTools::Dynamic::Tag] The desired tag.

# File lib/elftools/dynamic.rb, line 93
def tag_at(n)
  return if n.negative?

  @tag_at_map ||= {}
  return @tag_at_map[n] if @tag_at_map[n]

  dyn = Structs::ELF_Dyn.new(endian: endian)
  dyn.elf_class = header.elf_class
  stream.pos = tag_start + n * dyn.num_bytes
  dyn.offset = stream.pos
  @tag_at_map[n] = Tag.new(dyn.read(stream), stream, method(:str_offset))
end
tag_by_type(type) click to toggle source

Get a tag of specific type. @param [Integer, Symbol, String] type

Constant value, symbol, or string of type
is acceptable. See examples for more information.

@return [ELFTools::Dynamic::Tag] The desired tag. @example

dynamic = elf.segment_by_type(:dynamic)
# type as integer
dynamic.tag_by_type(0) # the null tag
#=>  #<ELFTools::Dynamic::Tag:0x0055b5a5ecad28 @header={:d_tag=>0, :d_val=>0}>
dynamic.tag_by_type(ELFTools::Constants::DT_NULL)
#=>  #<ELFTools::Dynamic::Tag:0x0055b5a5ecad28 @header={:d_tag=>0, :d_val=>0}>

# symbol
dynamic.tag_by_type(:null)
#=>  #<ELFTools::Dynamic::Tag:0x0055b5a5ecad28 @header={:d_tag=>0, :d_val=>0}>
dynamic.tag_by_type(:pltgot)
#=> #<ELFTools::Dynamic::Tag:0x0055d3d2d91b28 @header={:d_tag=>3, :d_val=>6295552}>

# string
dynamic.tag_by_type('null')
#=>  #<ELFTools::Dynamic::Tag:0x0055b5a5ecad28 @header={:d_tag=>0, :d_val=>0}>
dynamic.tag_by_type('DT_PLTGOT')
#=> #<ELFTools::Dynamic::Tag:0x0055d3d2d91b28 @header={:d_tag=>3, :d_val=>6295552}>
# File lib/elftools/dynamic.rb, line 64
def tag_by_type(type)
  type = Util.to_constant(Constants::DT, type)
  each_tags.find { |tag| tag.header.d_tag == type }
end
tags() click to toggle source

Use {#tags} to get all tags. @return [Array<ELFTools::Dynamic::Tag>]

Array of tags.
# File lib/elftools/dynamic.rb, line 36
def tags
  @tags ||= each_tags.to_a
end
tags_by_type(type) click to toggle source

Get tags of specific type. @param [Integer, Symbol, String] type

Constant value, symbol, or string of type
is acceptable. See examples for more information.

@return [Array<ELFTools::Dynamic::Tag>] The desired tags.

@see tag_by_type

# File lib/elftools/dynamic.rb, line 76
def tags_by_type(type)
  type = Util.to_constant(Constants::DT, type)
  each_tags.select { |tag| tag.header.d_tag == type }
end

Private Instance Methods

endian() click to toggle source
# File lib/elftools/dynamic.rb, line 108
def endian
  header.class.self_endian
end
str_offset() click to toggle source

Get the DT_STRTAB's d_val offset related to file.

# File lib/elftools/dynamic.rb, line 113
def str_offset
  # TODO: handle DT_STRTAB not exitsts.
  @str_offset ||= @offset_from_vma.call(tag_by_type(:strtab).header.d_val.to_i)
end