Skip to content

Commit b53e65b

Browse files
committed
wip crash commands
1 parent 51f75d7 commit b53e65b

File tree

2 files changed

+407
-0
lines changed

2 files changed

+407
-0
lines changed

drgn/commands/_builtin/crash/mm.py

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
# Copyright (c) Meta Platforms, Inc. and affiliates.
2+
# SPDX-License-Identifier: LGPL-2.1-or-later
3+
4+
import argparse
5+
from typing import Any
6+
7+
from drgn import Program
8+
from drgn.commands import argument, drgn_argument
9+
from drgn.commands.crash import crash_command
10+
from drgn.helpers.common.format import print_table
11+
from drgn.helpers.linux.mm import follow_phys, page_to_phys, phys_to_page
12+
13+
14+
@crash_command(
15+
description="bytes to page",
16+
long_description="Convert byte numbers (usually physical addresses) to page numbers.",
17+
arguments=(
18+
argument(
19+
"address",
20+
type="hexadecimal",
21+
nargs="+",
22+
help="hexadecimal byte number/physical address",
23+
),
24+
drgn_argument,
25+
),
26+
)
27+
def _crash_cmd_btop(
28+
prog: Program, name: str, args: argparse.Namespace, **kwargs: Any
29+
) -> None:
30+
if args.drgn:
31+
print(
32+
"""\
33+
PHYS_PFN(address)
34+
# or
35+
address >> prog["PAGE_SHIFT"]"""
36+
)
37+
return
38+
39+
PAGE_SHIFT = prog["PAGE_SHIFT"].value_()
40+
for address in args.address:
41+
print(f"{address:x}: {address >> PAGE_SHIFT:x}")
42+
43+
44+
@crash_command(
45+
description="page to bytes",
46+
long_description="Convert page frame numbers to byte numbers (physical addresses).",
47+
arguments=(
48+
argument(
49+
"pfn", type="decimal_or_hexadecimal", nargs="+", help="page frame number"
50+
),
51+
drgn_argument,
52+
),
53+
)
54+
def _crash_cmd_ptob(
55+
prog: Program, name: str, args: argparse.Namespace, **kwargs: Any
56+
) -> None:
57+
if args.drgn:
58+
print(
59+
"""\
60+
PFN_PHYS(address)
61+
# or
62+
address << prog["PAGE_SHIFT"]"""
63+
)
64+
return
65+
66+
PAGE_SHIFT = prog["PAGE_SHIFT"].value_()
67+
for pfn in args.pfn:
68+
print(f"{pfn:x}: {pfn << PAGE_SHIFT:x}")
69+
70+
71+
@crash_command(
72+
description="physical or per-CPU to virtual",
73+
long_description="TODO",
74+
arguments=(
75+
argument(
76+
"address",
77+
metavar="address|offset:cpuspec",
78+
type="hexadecimal",
79+
nargs="+",
80+
help="hexadecimal physical address or hexadecimal per-CPU offset and CPU specifier",
81+
),
82+
drgn_argument,
83+
),
84+
)
85+
def _crash_cmd_ptov(
86+
prog: Program, name: str, args: argparse.Namespace, **kwargs: Any
87+
) -> None:
88+
if args.drgn:
89+
print("phys_to_virt(address)")
90+
return
91+
92+
# TODO
93+
94+
95+
@crash_command(
96+
description="virtual to physical",
97+
long_description="TODO",
98+
arguments=(
99+
# TODO: -c flag
100+
# argument(
101+
# "-c", dest="task", metavar="pid | taskp", help="TODO"
102+
# ),
103+
# TODO: -k, -u flags
104+
argument(
105+
"address", type="hexadecimal", nargs="+", help="hexadecimal virtual address"
106+
),
107+
drgn_argument,
108+
),
109+
)
110+
def _crash_cmd_vtop(
111+
prog: Program, name: str, args: argparse.Namespace, **kwargs: Any
112+
) -> None:
113+
# TODO: --drgn
114+
115+
mm = prog["init_mm"].address_of_()
116+
117+
for i, address in enumerate(args.address):
118+
phys = follow_phys(mm, address)
119+
page = phys_to_page(phys)
120+
121+
if i != 0:
122+
print()
123+
print_table(
124+
(
125+
("VIRTUAL", "PHYSICAL"),
126+
(f"{address:x}", f"{phys.value_():x}"),
127+
)
128+
)
129+
130+
# TODO: page table info
131+
132+
# TODO: crash tries printing VMAs, possibly other things?
133+
134+
print()
135+
# TODO: we justify things differently than crash
136+
print_table(
137+
(
138+
("PAGE", "PHYSICAL", "MAPPING", "INDEX", "CNT", "FLAGS"),
139+
(
140+
f"{page.value_():x}",
141+
f"{page_to_phys(page).value_():x}",
142+
f"{page.mapping.value_():x}",
143+
"TODO", # TODO: not sure what base these are in
144+
"TODO",
145+
f"{page.flags.value_():x}",
146+
),
147+
)
148+
)

0 commit comments

Comments
 (0)