Sha256: 9f3ef0fcc5fa4863248dfe9fe255b400e18f5e086cf041e624736a32ce6e98c1

Contents?: true

Size: 1.51 KB

Versions: 9

Compression:

Stored size: 1.51 KB

Contents

require 'elf'
require_relative 'helper'

module Dply
  class Elf

    include Helper

    MAGIC_STRING = "\177ELF"

    def self.elf?(path)
      return false if not File.file? path
      IO.binread(path, 4) == MAGIC_STRING
    end

    attr_reader :path

    def initialize(path)
      @path = Pathname.new(path)
      @elf = ::Elf::File.new(path)
    end

    def external_libs
      return [] if not @elf.has_section? ".dynamic"
      dynamic = dynamic_libs()
      external = dynamic.reject { |i| lib_in_relative_rpath? i }.map { |l| "#{l}#{lib_type}" }
      logger.debug { "[#{@path}]: dynamic:#{dynamic.size} rpath:#{dynamic.size - external.size} ext:#{external.size}" } if logger.debug?
      external
    end

    private

    def dynamic_libs
      @elf[".dynamic"].needed_libraries.keys
    end

    def lib_type
      @lib_type ||= @elf.elf_class.desc == "64-bit" ? "()(64bit)" : ""
    end

    def relative_rpath
      @relative_rpath ||= begin
        # include both rpath and runpaths 
        rpaths = @elf[".dynamic"].rpath + @elf[".dynamic"].runpath
        # expand $ORIGIN
        rpaths = rpaths.map { |i| i.sub("$ORIGIN", "#{@path.dirname}") }
        # convert all paths to realpath
        rpaths = rpaths.map { |i| Pathname.new(i).realpath }
        # select paths which start with cwd or are subpaths to cwd
        cwd = Dir.pwd
        rpaths.select { |i| i.to_s.start_with? cwd }
      end
    end

    def lib_in_relative_rpath?(lib)
      relative_rpath.any? { |i| File.exist? "#{i}/#{lib}" }
    end

  end
end

Version data entries

9 entries across 9 versions & 1 rubygems

Version Path
dply-0.3.8 lib/dply/elf.rb
dply-0.3.7 lib/dply/elf.rb
dply-0.3.6 lib/dply/elf.rb
dply-0.3.5 lib/dply/elf.rb
dply-0.3.4 lib/dply/elf.rb
dply-0.3.3 lib/dply/elf.rb
dply-0.3.2 lib/dply/elf.rb
dply-0.3.1 lib/dply/elf.rb
dply-0.3.0 lib/dply/elf.rb