linux: Add kernel_symbol object extension

This commit is contained in:
Gustavo Moreira
2025-02-01 17:54:55 +11:00
parent 88b32b0803
commit 0e0daffc45
2 changed files with 62 additions and 0 deletions
@@ -88,6 +88,7 @@ class LinuxKernelIntermedSymbols(intermed.IntermediateSymbolTable):
self.optional_set_type_class("maple_tree", extensions.maple_tree)
self.optional_set_type_class("latch_tree_root", extensions.latch_tree_root)
self.optional_set_type_class("kernel_symbol", extensions.kernel_symbol)
class LinuxUtilities(interfaces.configuration.VersionableInterface):
@@ -3100,3 +3100,64 @@ class latch_tree_root(objects.StructType):
return None
class kernel_symbol(objects.StructType):
def _offset_to_ptr(self, off) -> int:
layer = self._context.layers[self.vol.layer_name]
long_mask = (1 << layer.bits_per_register) - 1
return (self.vol.offset + off) & long_mask
@property
def name(self) -> str:
if self.has_member("name_offset"):
# kernel >= 4.19 and CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y
# See 7290d58095712a89f845e1bca05334796dd49ed2
name_offset = self._offset_to_ptr(self.name_offset)
elif self.has_member("name"):
# kernel < 4.19 or CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=n
name_offset = self.member("name")
else:
raise AttributeError("Unsupported kernel_symbol type implementation")
layer = self._context.layers[self.vol.layer_name]
name_bytes = layer.read(name_offset, linux_constants.KSYM_NAME_LEN)
idx = name_bytes.find(b"\x00")
if idx != -1:
name_bytes = name_bytes[:idx]
return name_bytes.decode("utf-8", errors="ignore")
@property
def value(self) -> int:
if self.has_member("value_offset"):
# kernel >= 4.19 and CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y
# See 7290d58095712a89f845e1bca05334796dd49ed2
return self._offset_to_ptr(self.value_offset)
elif self.has_member("value"):
# kernel < 4.19 or CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=n
return self.member("value")
raise AttributeError("Unsupported kernel_symbol type implementation")
@property
def namespace(self) -> str:
if self.has_member("namespace_offset"):
# kernel >= 4.19 and CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=y
# See 7290d58095712a89f845e1bca05334796dd49ed2
namespace_offset = self._offset_to_ptr(self.namespace_offset)
elif self.has_member("namespace"):
# kernel < 4.19 or CONFIG_HAVE_ARCH_PREL32_RELOCATIONS=n
namespace_offset = self.member("namespace")
else:
raise AttributeError("Unsupported kernel_symbol type implementation")
layer = self._context.layers[self.vol.layer_name]
namespace_bytes = layer.read(namespace_offset, linux_constants.KSYM_NAME_LEN)
idx = namespace_bytes.find(b"\x00")
if idx != -1:
namespace_bytes = namespace_bytes[:idx]
return namespace_bytes.decode("utf-8", errors="ignore")