
class KMod_Load_Info
  attr_accessor :name, :file, :mtime, :version, :persistent, :sections

  def initialize(name)
    @name = name
    @sections = {}
    @persistent = []
  end

  def add_section(name, address, length)
    @sections[name] = [address, length]
  end

  def get_section(name)
    @sections[name]
  end

  def section_addr(name)
    get_section(name)[0]
  end

  def section_size(name)
    get_section(name)[1]
  end
end

class Proc_Ksyms_Reader
  # man insmod
  @@regexp_mod_objectfile =
        Regexp.new(/^__insmod_(.+)_O(.+)_M([0-9a-fA-F]+)_V(-?[0-9]+)$/)
  @@regexp_mod_sectionname = Regexp.new(/^__insmod_(.+)_S(.+)_L([0-9]+)$/)
  @@regexp_mod_persistent = Regexp.new(/^__insmod_(.+)_P(.+)$/)

  def Proc_Ksyms_Reader.All_KMod_Load_Info(file)
    kmod_load = {}
    proc_ksyms = IO.readlines((file == nil) ? "/proc/ksyms" : file)

    proc_ksyms.each do |line|
      asist_sym = line.split[1]
      address = line.split[0].hex
      if res = @@regexp_mod_objectfile.match(asist_sym)
	name = res[1]
	kmod_load[name] = KMod_Load_Info.new(name) if !kmod_load[name]
	kmod_load[name].file = res[2]
	kmod_load[name].mtime = res[3].hex
	kmod_load[name].version = res[4]
      elsif res = @@regexp_mod_sectionname.match(asist_sym)
	name = res[1]
	kmod_load[name] = KMod_Load_Info.new(name) if !kmod_load[name]
	kmod_load[name].add_section(res[2], address, res[3].to_i)
      elsif res = @@regexp_mod_persistent.match(asist_sym)
	name = res[1]
	kmod_load[name] = KMod_Load_Info.new(name) if !kmod_load[name]
	kmod_load[name].persistent.push(res[2])
      end
    end
    return kmod_load
  end
end

