|
@@ -32,3 +32,38 @@ class CachedType:
|
|
|
if hasattr(gdb, 'events') and hasattr(gdb.events, 'new_objfile'):
|
|
|
gdb.events.new_objfile.connect(self._new_objfile_handler)
|
|
|
return self._type
|
|
|
+
|
|
|
+
|
|
|
+long_type = CachedType("long")
|
|
|
+
|
|
|
+
|
|
|
+def get_long_type():
|
|
|
+ global long_type
|
|
|
+ return long_type.get_type()
|
|
|
+
|
|
|
+
|
|
|
+def offset_of(typeobj, field):
|
|
|
+ element = gdb.Value(0).cast(typeobj)
|
|
|
+ return int(str(element[field].address).split()[0], 16)
|
|
|
+
|
|
|
+
|
|
|
+def container_of(ptr, typeobj, member):
|
|
|
+ return (ptr.cast(get_long_type()) -
|
|
|
+ offset_of(typeobj, member)).cast(typeobj)
|
|
|
+
|
|
|
+
|
|
|
+class ContainerOf(gdb.Function):
|
|
|
+ """Return pointer to containing data structure.
|
|
|
+
|
|
|
+$container_of(PTR, "TYPE", "ELEMENT"): Given PTR, return a pointer to the
|
|
|
+data structure of the type TYPE in which PTR is the address of ELEMENT.
|
|
|
+Note that TYPE and ELEMENT have to be quoted as strings."""
|
|
|
+
|
|
|
+ def __init__(self):
|
|
|
+ super(ContainerOf, self).__init__("container_of")
|
|
|
+
|
|
|
+ def invoke(self, ptr, typename, elementname):
|
|
|
+ return container_of(ptr, gdb.lookup_type(typename.string()).pointer(),
|
|
|
+ elementname.string())
|
|
|
+
|
|
|
+ContainerOf()
|