linux: Add support for module symbol types

This commit is contained in:
Gustavo Moreira
2025-02-01 17:54:41 +11:00
parent 18a69b9417
commit dba90ac217
@@ -176,37 +176,43 @@ class module(generic.GenericIntelProcess):
"""Get the name of the module as a string"""
return utility.array_to_string(self.name)
def _get_sect_count(self, grp):
def _get_sect_count(self, grp) -> int:
"""Try to determine the number of valid sections"""
symbol_table_name = self.get_symbol_table_name()
arr = self._context.object(
self.get_symbol_table_name() + constants.BANG + "array",
symbol_table_name + constants.BANG + "array",
layer_name=self.vol.layer_name,
offset=grp.attrs,
subtype=self._context.symbol_space.get_type(
self.get_symbol_table_name() + constants.BANG + "pointer"
symbol_table_name + constants.BANG + "pointer"
),
count=25,
)
idx = 0
while arr[idx]:
while arr[idx] and arr[idx].is_readable():
idx = idx + 1
return idx
def get_sections(self):
"""Get sections of the module"""
@functools.cached_property
def number_of_sections(self) -> int:
if self.sect_attrs.has_member("nsections"):
num_sects = self.sect_attrs.nsections
else:
num_sects = self._get_sect_count(self.sect_attrs.grp)
return self.sect_attrs.nsections
return self._get_sect_count(self.sect_attrs.grp)
def get_sections(self) -> Iterable[interfaces.objects.ObjectInterface]:
"""Get a list of section attributes for the given module."""
symbol_table_name = self.get_symbol_table_name()
arr = self._context.object(
self.get_symbol_table_name() + constants.BANG + "array",
symbol_table_name + constants.BANG + "array",
layer_name=self.vol.layer_name,
offset=self.sect_attrs.attrs.vol.offset,
subtype=self._context.symbol_space.get_type(
self.get_symbol_table_name() + constants.BANG + "module_sect_attr"
symbol_table_name + constants.BANG + "module_sect_attr"
),
count=num_sects,
count=self.number_of_sections,
)
yield from arr
@@ -309,6 +315,27 @@ class module(generic.GenericIntelProcess):
raise AttributeError("Unable to get strtab")
@property
def section_typetab(self):
if self.has_member("kallsyms") and self.kallsyms.has_member("typetab"):
# kernels >= 4.5 8244062ef1e54502ef55f54cced659913f244c3e: kallsyms was added
# kernels >= 5.2 1c7651f43777cdd59c1aaa82c87324d3e7438c7b: types have its own array
return self.kallsyms.typetab
raise AttributeError("Unable to get typetab section, it needs a kernel >= 5.2")
def get_symbol_type(self, symbol, symbol_index):
if self.has_member("kallsyms") and self.kallsyms.has_member("typetab"):
# kernels >= 5.2 1c7651f43777cdd59c1aaa82c87324d3e7438c7b types have its own array
layer = self._context.layers[self.vol.layer_name]
sym_type = layer.read(self.section_typetab + symbol_index, 1)
sym_type = sym_type.decode("utf-8", errors="ignore")
else:
# kernels < 5.2 the type was stored in the st_info
sym_type = chr(symbol.st_info)
return sym_type
class task_struct(generic.GenericIntelProcess):
def is_valid(self) -> bool: