mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-05-25 22:14:34 +00:00
chore(kernel): add custom pretty printer for std::string
This commit is contained in:
parent
2791a602b5
commit
527ad803d3
@ -9,5 +9,9 @@ insert_final_newline = true
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
[*.py]
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
|
@ -1,91 +0,0 @@
|
||||
# Usage: add-symbol-file-all <filename> [<offset>]
|
||||
# remove-symbol-file-all <filename> [<offset>]
|
||||
#
|
||||
# Credit: https://stackoverflow.com/a/33087762/9352057
|
||||
# CC BY-SA 4.0
|
||||
|
||||
python
|
||||
import subprocess
|
||||
import re
|
||||
|
||||
def relocatesections(filename, addr):
|
||||
p = subprocess.Popen(["readelf", "-S", filename], stdout = subprocess.PIPE)
|
||||
|
||||
sections = []
|
||||
textaddr = '0'
|
||||
for line in p.stdout.readlines():
|
||||
line = line.decode("utf-8").strip()
|
||||
if not line.startswith('[') or line.startswith('[Nr]'):
|
||||
continue
|
||||
|
||||
line = re.sub(r' +', ' ', line)
|
||||
line = re.sub(r'\[ *(\d+)\]', '\g<1>', line)
|
||||
fieldsvalue = line.split(' ')
|
||||
fieldsname = ['number', 'name', 'type', 'addr', 'offset', 'size', 'entsize', 'flags', 'link', 'info', 'addralign']
|
||||
sec = dict(zip(fieldsname, fieldsvalue))
|
||||
|
||||
if sec['number'] == '0':
|
||||
continue
|
||||
|
||||
sections.append(sec)
|
||||
|
||||
if sec['name'] == '.text':
|
||||
textaddr = sec['addr']
|
||||
|
||||
return (textaddr, sections)
|
||||
|
||||
|
||||
class AddSymbolFileAll(gdb.Command):
|
||||
"""The right version for add-symbol-file"""
|
||||
|
||||
def __init__(self):
|
||||
super(AddSymbolFileAll, self).__init__("add-symbol-file-all", gdb.COMMAND_USER)
|
||||
self.dont_repeat()
|
||||
|
||||
def invoke(self, arg, from_tty):
|
||||
argv = gdb.string_to_argv(arg)
|
||||
filename = argv[0]
|
||||
|
||||
if len(argv) > 1:
|
||||
offset = int(str(gdb.parse_and_eval(argv[1])), 0)
|
||||
else:
|
||||
offset = 0
|
||||
|
||||
(textaddr, sections) = relocatesections(filename, offset)
|
||||
|
||||
cmd = "add-symbol-file %s 0x%08x" % (filename, int(textaddr, 16) + offset)
|
||||
|
||||
for s in sections:
|
||||
addr = int(s['addr'], 16)
|
||||
if s['name'] == '.text' or addr == 0:
|
||||
continue
|
||||
|
||||
cmd += " -s %s 0x%08x" % (s['name'], addr + offset)
|
||||
|
||||
gdb.execute(cmd)
|
||||
|
||||
class RemoveSymbolFileAll(gdb.Command):
|
||||
"""The right version for remove-symbol-file"""
|
||||
|
||||
def __init__(self):
|
||||
super(RemoveSymbolFileAll, self).__init__("remove-symbol-file-all", gdb.COMMAND_USER)
|
||||
self.dont_repeat()
|
||||
|
||||
def invoke(self, arg, from_tty):
|
||||
argv = gdb.string_to_argv(arg)
|
||||
filename = argv[0]
|
||||
|
||||
if len(argv) > 1:
|
||||
offset = int(str(gdb.parse_and_eval(argv[1])), 0)
|
||||
else:
|
||||
offset = 0
|
||||
|
||||
(textaddr, _) = relocatesections(filename, offset)
|
||||
|
||||
cmd = "remove-symbol-file -a 0x%08x" % (int(textaddr, 16) + offset)
|
||||
gdb.execute(cmd)
|
||||
|
||||
|
||||
AddSymbolFileAll()
|
||||
RemoveSymbolFileAll()
|
||||
end
|
51
Kernel/gdb_printers.py
Normal file
51
Kernel/gdb_printers.py
Normal file
@ -0,0 +1,51 @@
|
||||
import gdb
|
||||
|
||||
class BasicStringPrinter:
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def to_string(self):
|
||||
try:
|
||||
data = self.val['_data']
|
||||
size = int(self.val['_size'])
|
||||
capacity = int(self.val['_capacity'])
|
||||
if int(data) == 0:
|
||||
return '<null>'
|
||||
content = data.string(length=size)
|
||||
return f"'{content}' (size={size}, cap={capacity})"
|
||||
except gdb.error:
|
||||
return '<invalid string>'
|
||||
|
||||
def children(self):
|
||||
try:
|
||||
data = self.val['_data']
|
||||
size = int(self.val['_size'])
|
||||
if int(data) == 0:
|
||||
return
|
||||
for i in range(size):
|
||||
yield (f'[{i}]', (data + i).dereference())
|
||||
except gdb.error:
|
||||
return
|
||||
|
||||
def display_hint(self):
|
||||
return 'array'
|
||||
|
||||
def lookup_fennix_string(val):
|
||||
try:
|
||||
typename = str(val.type.strip_typedefs())
|
||||
fields = val.type.fields()
|
||||
field_names = [f.name for f in fields]
|
||||
if '_data' in field_names and '_size' in field_names and '_capacity' in field_names:
|
||||
return BasicStringPrinter(val)
|
||||
except:
|
||||
pass
|
||||
return None
|
||||
|
||||
gdb.pretty_printers.append(lookup_fennix_string)
|
||||
|
||||
def build_pretty_printers():
|
||||
pp = gdb.printing.RegexpCollectionPrettyPrinter("fennix")
|
||||
pp.add_printer('std::string', '^std::string$', BasicStringPrinter)
|
||||
return pp
|
||||
|
||||
gdb.printing.register_pretty_printer(None, build_pretty_printers(), replace=True)
|
Loading…
x
Reference in New Issue
Block a user