From e0e640fd07927822674f5df5a33a713bbfa87ba9 Mon Sep 17 00:00:00 2001 From: Mitchel Humpherys <mitchelh@codeaurora.org> Date: Fri, 4 Apr 2014 17:34:39 -0700 Subject: [PATCH] lrdp-v2: add container_of and sibling_field_addr convenience functions Some common operations include getting the parent structure of some embedded field as well as getting "sibling" fields within the parent structure. Add some convenience methods to the gdbmi module (as well as wrappers in the RamDump class) for this. Change-Id: Ic65d7e60b930af8c73384a30b6b0dd84fb55f09c --- linux-ramdump-parser-v2/gdbmi.py | 27 ++++++++++++++++++++++++++- linux-ramdump-parser-v2/ramdump.py | 12 ++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/linux-ramdump-parser-v2/gdbmi.py b/linux-ramdump-parser-v2/gdbmi.py index cdccdd0..e7cec10 100644 --- a/linux-ramdump-parser-v2/gdbmi.py +++ b/linux-ramdump-parser-v2/gdbmi.py @@ -1,4 +1,4 @@ -# Copyright (c) 2013, The Linux Foundation. All rights reserved. +# Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 and @@ -158,6 +158,31 @@ class GdbMI(object): result = self._run_for_one(cmd) return gdb_hex_to_dec(result) + def container_of(self, ptr, the_type, member): + return ptr - self.field_offset(the_type, member) + + def sibling_field_addr(self, ptr, parent_type, member, sibling): + """Returns the address of a sibling field within the parent + structure. + + Example: + + Given: + struct pizza { + int price; + int *qty; + }; + + int quanitity = 42; + struct pizza mypizza = {.price = 10, .qty = &quanitity}; + + qtyp = dump.addr_lookup('quantity') + price = dump.read_int(gdbmi.sibling_field_addr(qtyp, 'struct pizza', 'qty', 'price')) + + """ + return self.container_of(ptr, parent_type, member) + \ + self.field_offset(parent_type, sibling) + def sizeof(self, the_type): """Returns the size of the type specified by `the_type'.""" result = self._run_for_one('print /x sizeof({0})'.format(the_type)) diff --git a/linux-ramdump-parser-v2/ramdump.py b/linux-ramdump-parser-v2/ramdump.py index 71d89b9..3e2a0f5 100644 --- a/linux-ramdump-parser-v2/ramdump.py +++ b/linux-ramdump-parser-v2/ramdump.py @@ -869,6 +869,18 @@ class RamDump(): except gdbmi.GdbMIException: pass + def container_of(self, ptr, the_type, member): + try: + return self.gdbmi.container_of(ptr, the_type, member) + except gdbmi.GdbMIException: + pass + + def sibling_field_addr(self, ptr, parent_type, member, sibling): + try: + return self.gdbmi.sibling_field_addr(ptr, parent_type, member, sibling) + except gdbmi.GdbMIException: + pass + def unwind_lookup(self, addr, symbol_size=0): if (addr is None): return ('(Invalid address)', 0x0) -- GitLab