Skip to content

Commit 8970220

Browse files
committed
CLI: add stats option to save function info
1 parent 0895290 commit 8970220

File tree

4 files changed

+38
-2
lines changed

4 files changed

+38
-2
lines changed

chb/app/AppResultFunctionMetrics.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@
2828
# ------------------------------------------------------------------------------
2929
import xml.etree.ElementTree as ET
3030

31-
from typing import Dict, List, Optional, TYPE_CHECKING
31+
from typing import Any, Dict, List, Optional, TYPE_CHECKING
32+
33+
from chb.jsoninterface.JSONResult import JSONResult
3234

3335
import chb.util.fileutil as UF
3436

@@ -214,6 +216,20 @@ def name(self) -> str:
214216
def has_name(self) -> bool:
215217
return "name" in self.xnode.attrib
216218

219+
def to_json_result(self) -> JSONResult:
220+
content: Dict[str, Any] = {}
221+
content["faddr"] = self.faddr
222+
if self.has_name():
223+
content["name"] = self.name
224+
content["instrs"] = self.instruction_count
225+
content["blocks"] = self.block_count
226+
content["time"] = self.time
227+
if self.call_count > 0:
228+
content["callcount"] = self.call_count
229+
if self.unresolved_call_count > 0:
230+
content["unrcalls"] = self.unresolved_call_count
231+
return JSONResult("functionmetrics", content, "ok")
232+
217233
def as_dictionary(self) -> Dict[str, str]:
218234
result: Dict[str, str] = {}
219235
result['faddr'] = self.faddr

chb/app/AppResultMetrics.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ def f(fn: AppResultFunctionMetrics) -> None:
401401
self.iter(f)
402402
return names
403403

404-
def to_json_result(self) -> JSONResult:
404+
def to_json_result(self, includefns: bool = False) -> JSONResult:
405405
content: Dict[str, Any] = {}
406406
content["instructions"] = int(self.instruction_count)
407407
content["unknowninstrs"] = int(self.unknown_instructions)
@@ -420,6 +420,10 @@ def to_json_result(self) -> JSONResult:
420420
content["iterations"] = self.run_count
421421
content["analysisdate"] = self.date_time
422422
content["fns-excluded"] = self.fns_excluded
423+
if includefns:
424+
content["functions"] = []
425+
for f in self.get_function_results():
426+
content["functions"].append(f.to_json_result().content)
423427
return JSONResult("analysisstats", content, "ok")
424428

425429
def as_dictionary(self) -> Dict[str, Any]:

chb/cmdline/chkx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,10 @@ def parse() -> argparse.Namespace:
623623
"--opcodes",
624624
help=("json filename (without extension) to save opcode distribution "
625625
+ "stats (for instructions within analyzed functions)"))
626+
resultsstats.add_argument(
627+
"--functionmetrics",
628+
help=("json filename (without extension) to save function metrics in "
629+
+ "json format"))
626630
resultsstats.add_argument(
627631
"--tagfile",
628632
help="name of json file that has function tags")

chb/cmdline/commandutil.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,7 @@ def results_stats(args: argparse.Namespace) -> NoReturn:
619619
sortby: str = args.sortby
620620
timeshare: int = args.timeshare
621621
opcodes: str = args.opcodes
622+
functionmetrics: str = args.functionmetrics
622623
hide: List[str] = args.hide
623624
tagfile: Optional[str] = args.tagfile
624625
loglevel: str = args.loglevel
@@ -696,6 +697,17 @@ def results_stats(args: argparse.Namespace) -> NoReturn:
696697
print("-----------------------")
697698
print("Total".ljust(14) + "{:4.2f}".format(100.0 * toptotal).rjust(6))
698699

700+
if functionmetrics:
701+
filename = functionmetrics + ".json"
702+
content: Dict[str, Any] = {}
703+
content["filename"] = xname
704+
content["functions"] = []
705+
for f in sorted(stats.get_function_results(), key=lambda f: f.faddr):
706+
content["functions"].append(f.to_json_result().content)
707+
jsonok = JU.jsonok("functionmetrics", content)
708+
with open(filename, "w") as fp:
709+
json.dump(jsonok, fp, indent=4)
710+
699711
if opcodes:
700712
filename = opcodes + ".json"
701713
opcstats = app.mnemonic_stats()

0 commit comments

Comments
 (0)