class Elf::Dynamic

Constants

ClassMap

Public Instance Methods

auxiliary_library_path(type) click to toggle source

Returns the auxiliary path specified by the given type

Please never use this function because it does not caches its values, use Dynamic#rpath or Dynamic#runpath instead.

# File lib/elf/dynamic.rb, line 278
def auxiliary_library_path(type)
  retval = Array.new

  each_entry do |entry|
    next unless entry.type == type
    retval.concat entry.parsed.split(":")
  end

  return retval.uniq.collect do |path|
    if path == "$ORIGIN" or path == "${ORIGIN}"
      Pathname.new(@file.path).dirname
    else
      begin
        Pathname.new(path).realpath
      rescue Errno::ENOENT
        path
      end
    end.to_s
  end
end
complete_library_path() click to toggle source

Returns the complete library path for the current ELF file.

Since the ELF loaders have somewhat complex rules to identify the path to load dependencies from, we evalute it on a per-file basis.

# File lib/elf/dynamic.rb, line 304
def complete_library_path
  if @complete_library_path.nil?
    @complete_library_path = Array.new

    # If there is no DT_RUNPATH. RPATH wins over the LD_LIBRARY_PATH
    @complete_library_path.concat rpath unless runpath.empty?

    @complete_library_path.concat Elf::Utilities.environment_library_path

    # If there is a DT_RUNPATH it wins over the system library path
    @complete_library_path.concat runpath

    @complete_library_path.concat Elf::Utilities.system_library_path

    @complete_library_path.uniq!
  end

  return @complete_library_path
end
count() click to toggle source

Return the amount of entries in the .dynamic section.

# File lib/elf/dynamic.rb, line 250
def count
  load unless @entries

  @entries.size
end
each_entry(&block) click to toggle source

Iterate over all the entries in the .dynamic section.

# File lib/elf/dynamic.rb, line 243
def each_entry(&block)
  load unless @entries

  @entries.each(&block)
end
find_library(soname) click to toggle source

Return the ELF library corresponding to the given soname.

This function gets the system library paths and eventually adds the rpaths as expressed by the file itself, then look them up to find the proper library, just like the loader would.

# File lib/elf/dynamic.rb, line 329
def find_library(soname)
  complete_library_path.each do |path|
    # For the ELF linker an empty entry in the library path is the
    # same as "." and means the current working directory, so
    # replace it.
    path = "." if path == ""

    if FileTest.exist? "#{path}/#{soname}"
      begin
        possible_library = Elf::Utilities::FilePool["#{path}/#{soname}"]

        return possible_library if @file.is_compatible(possible_library)
      rescue Errno::ENOENT, Errno::EACCES, Errno::EISDIR, Elf::File::NotAnELF
        # we don't care if the file does not exist and similar.
      end
    end
  end

  return nil
end
load_internal() click to toggle source
# File lib/elf/dynamic.rb, line 224
def load_internal
  elf32 = @file.elf_class == Class::Elf32

  @entries = []

  for i in 1..@numentries
    type = Type[elf32 ? @file.read_sword : @file.read_sxword]

    @entries << if ClassMap.has_key? type
                  ClassMap[type].new(type, @file)
                else
                  Entry.new(type, @file)
                end

    break if type == Type::Null
  end
end
needed_libraries() click to toggle source

Returns an hash representing the dependencies of the ELF file.

This function reads the .dynamic section of the file for DT_NEEDED entries, then looks for them and add them to an hash.

Note that nil values in the hash means that the library couldn’t be found on either the runpath of the file or the system library path.

# File lib/elf/dynamic.rb, line 376
def needed_libraries
  # Make sure to cache the thing, we don't want to have to parse
  # this multiple times since we might access it over and over to
  # check the dependencies.
  if @needed_libraries.nil?
    @needed_libraries = Hash.new

    needed_sonames.each do |soname|
      @needed_libraries[soname] = find_library(soname)
    end
  end

  return @needed_libraries
end
needed_sonames() click to toggle source

Returns an array of needed sonames from .dynamic section

This function reads the .dynamic section of the file for DT_NEEDED entries, and fills an array with them.

# File lib/elf/dynamic.rb, line 354
def needed_sonames
  if @needed_sonames.nil?
    @needed_sonames = Array.new

    each_entry do |entry|
      next unless entry.type == Elf::Dynamic::Type::Needed

      @needed_sonames << entry.parsed
    end
  end

  return @needed_sonames
end
rpath() click to toggle source

Returns the value of DT_RPATH entries in the file

# File lib/elf/dynamic.rb, line 265
def rpath
  @rpath ||= auxiliary_library_path(Type::RPath)
end
runpath() click to toggle source

Returns the value of DT_RUNPATH entries in the file

# File lib/elf/dynamic.rb, line 270
def runpath
  @runpath ||= auxiliary_library_path(Type::RunPath)
end
soname() click to toggle source
# File lib/elf/dynamic.rb, line 256
def soname
  each_entry do |entry|
    return entry.parsed if entry.type == Type::SoName
  end

  return nil
end