linux: kallsyms api: Added support for older kernels lacking mod_tree. Enhanced module address search performance by using the new module memory boundaries function

This commit is contained in:
Gustavo Moreira
2025-02-01 20:55:40 +11:00
parent 2af8b95ea4
commit 0ba331f34c
@@ -788,15 +788,27 @@ class Kallsyms(interfaces.configuration.VersionableInterface):
if not self._is_module_ksym_address(address):
return None
module = module or self.get_module_by_address(address)
module = module or self._get_module_by_address(address)
if not module:
# This may occur if the kernel lacks the mod_tree implementation.
for (
cur_module,
minimum_address,
maximum_address,
) in self._module_memory_region:
if minimum_address <= address < maximum_address:
module = cur_module
break
if not module:
# We couldn't find the module
return None
kassymbol = self._find_address_in_module_symbols(module, address)
if not kassymbol:
return None
if kassymbol:
return kassymbol
return kassymbol
return None
def _find_address_in_module_symbols(
self,
@@ -814,6 +826,15 @@ class Kallsyms(interfaces.configuration.VersionableInterface):
Returns:
The matching KASSymbol if found; otherwise, returns None
"""
# Before walking all the symbols, ensure the address belongs to this module
module_boundaries = module.get_module_address_boundaries()
if not module_boundaries:
return None
minimum_address, maximum_address = module_boundaries
if not (minimum_address <= address < maximum_address):
return None
layer = self._context.layers[self._layer_name]
for elf_sym_idx, elf_sym in enumerate(module.get_symbols()):
if not elf_sym.get_name():
@@ -829,6 +850,18 @@ class Kallsyms(interfaces.configuration.VersionableInterface):
return None
@functools.cached_property
def _module_memory_region(
self,
) -> List[Tuple[interfaces.objects.ObjectInterface, int, int]]:
modules_region = []
for module in lsmod.Lsmod.list_modules(self._context, self._module_name):
minimum_address, maximum_address = module.get_module_address_boundaries()
module_region = module, minimum_address, maximum_address
modules_region.append(module_region)
return modules_region
@functools.lru_cache
def _get_modules_memory_boundaries(self) -> Tuple[int, int]:
"""Determine the boundaries of the module allocation area
@@ -870,7 +903,7 @@ class Kallsyms(interfaces.configuration.VersionableInterface):
_address_min, address_max = self._get_modules_memory_boundaries()
return address_max
def get_module_by_address(
def _get_module_by_address(
self, address: int
) -> Optional[interfaces.objects.ObjectInterface]:
"""Searches for the module that contains the given memory address within its range.
@@ -957,12 +990,10 @@ class Kallsyms(interfaces.configuration.VersionableInterface):
)
module_ptr = mod_tree_node.mod
if not module_ptr.is_readable():
vollog.error("Something went wrong")
vollog.warning("Modules latch tree seems corrupt")
return None
return module_ptr.dereference()
else:
raise NotImplementedError("FIXME")
return None