You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
2.0 KiB
Ruby
75 lines
2.0 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
# SPDX-License-Identifier: MIT OR Apache-2.0
|
|
#
|
|
# Copyright (c) 2021-2022 Andre Richter <andre.o.richter@gmail.com>
|
|
|
|
# KernelELF
|
|
class KernelELF
|
|
attr_reader :path
|
|
|
|
def initialize(kernel_elf_path, kernel_symbols_section, num_kernel_symbols)
|
|
@elf = ELFTools::ELFFile.new(File.open(kernel_elf_path))
|
|
@symtab_section = @elf.section_by_name('.symtab')
|
|
|
|
@path = kernel_elf_path
|
|
fetch_values(kernel_symbols_section, num_kernel_symbols)
|
|
end
|
|
|
|
private
|
|
|
|
def fetch_values(kernel_symbols_section, num_kernel_symbols)
|
|
sym = @symtab_section.symbol_by_name(num_kernel_symbols)
|
|
raise "Symbol \"#{num_kernel_symbols}\" not found" if sym.nil?
|
|
|
|
@num_kernel_symbols = sym
|
|
|
|
section = @elf.section_by_name(kernel_symbols_section)
|
|
raise "Section \"#{kernel_symbols_section}\" not found" if section.nil?
|
|
|
|
@kernel_symbols_section = section
|
|
end
|
|
|
|
def num_kernel_symbols_virt_addr
|
|
@num_kernel_symbols.header.st_value
|
|
end
|
|
|
|
def segment_containing_virt_addr(virt_addr)
|
|
@elf.each_segments do |segment|
|
|
return segment if segment.vma_in?(virt_addr)
|
|
end
|
|
end
|
|
|
|
def virt_addr_to_file_offset(virt_addr)
|
|
segment = segment_containing_virt_addr(virt_addr)
|
|
segment.vma_to_offset(virt_addr)
|
|
end
|
|
|
|
public
|
|
|
|
def symbols
|
|
non_zero_symbols = @symtab_section.symbols.reject { |sym| sym.header.st_size.zero? }
|
|
non_zero_symbols.sort_by { |sym| sym.header.st_value }
|
|
end
|
|
|
|
def num_symbols
|
|
symbols.size
|
|
end
|
|
|
|
def kernel_symbols_section_virt_addr
|
|
@kernel_symbols_section.header.sh_addr.to_i
|
|
end
|
|
|
|
def kernel_symbols_section_size
|
|
@kernel_symbols_section.header.sh_size.to_i
|
|
end
|
|
|
|
def kernel_symbols_section_offset_in_file
|
|
virt_addr_to_file_offset(kernel_symbols_section_virt_addr)
|
|
end
|
|
|
|
def num_kernel_symbols_offset_in_file
|
|
virt_addr_to_file_offset(num_kernel_symbols_virt_addr)
|
|
end
|
|
end
|