@@ -989,6 +989,30 @@ def perc(v: float) -> str:
989989 exit (0 )
990990
991991
992+ def write_json_result (xfilename : Optional [str ],
993+ jresult : JSONResult ,
994+ schema_name : str ,
995+ ) -> None :
996+ if jresult .is_ok :
997+ okresult = JU .jsonok (schema_name , jresult .content )
998+ if xfilename is not None :
999+ filename = xfilename + ".json"
1000+ with open (filename , "w" ) as fp :
1001+ json .dump (okresult , fp , indent = 2 )
1002+ chklogger .logger .info ("JSON output written to " + filename )
1003+ else :
1004+ print (json .dumps (okresult ))
1005+ else :
1006+ failresult = JU .jsonfail (jresult .reason )
1007+ if xfilename is not None :
1008+ filename = xfilename + ".json"
1009+ with open (filename , "w" ) as fp :
1010+ json .dump (failresult , fp , indent = 2 )
1011+ chklogger .logger .warning (
1012+ "JSON failure output written to " + filename )
1013+ else :
1014+ print (json .dumps (failresult ))
1015+
9921016def report_buffer_bounds (args : argparse .Namespace ) -> NoReturn :
9931017
9941018 # arguments
@@ -1022,49 +1046,27 @@ def report_buffer_bounds(args: argparse.Namespace) -> NoReturn:
10221046 if calltgt .is_so_target :
10231047 libcalls .add_library_callsite (faddr , instr )
10241048
1025- def write_json_result (
1026- xfilename : Optional [str ], jresult : JSONResult ) -> None :
1027- if jresult .is_ok :
1028- okresult = JU .jsonok ("bufferboundsassessment" , jresult .content )
1029- if xfilename is not None :
1030- filename = xfilename + ".json"
1031- with open (filename , "w" ) as fp :
1032- json .dump (okresult , fp , indent = 2 )
1033- chklogger .logger .info ("JSON output written to " + filename )
1034- else :
1035- print (json .dumps (okresult ))
1036- else :
1037- failresult = JU .jsonfail (jresult .reason )
1038- if xfilename is not None :
1039- filename = xfilename + ".json"
1040- with open (filename , "w" ) as fp :
1041- json .dump (failresult , fp , indent = 2 )
1042- chklogger .logger .warning (
1043- "JSON failure output written to " + filename )
1044- else :
1045- print (json .dumps (failresult ))
1046-
10471049 if xjson :
10481050 content : Dict [str , Any ] = {}
10491051 xinfodata = xinfo .to_json_result ()
10501052 if xinfodata .is_ok :
10511053 content ["identification" ] = xinfodata .content
10521054 else :
1053- write_json_result (xoutput , xinfodata )
1055+ write_json_result (xoutput , xinfodata , "bufferboundsassessment" )
10541056 analysisstats = app .result_metrics .to_json_result ()
10551057 if analysisstats .is_ok :
10561058 content ["analysis" ] = analysisstats .content
10571059 else :
1058- write_json_result (xoutput , analysisstats )
1060+ write_json_result (xoutput , analysisstats , "bufferboundsassessment" )
10591061
10601062 libcallsresult = libcalls .to_json_result ()
10611063 if libcallsresult .is_ok :
10621064 content ["bounds" ] = libcallsresult .content
10631065 else :
1064- write_json_result (xoutput , libcallsresult )
1066+ write_json_result (xoutput , libcallsresult , "bufferboundsassessment" )
10651067
10661068 write_json_result (xoutput , JSONResult (
1067- "libcboundsanalysis" , content , "ok" ))
1069+ "libcboundsanalysis" , content , "ok" ), "bufferboundsassessment" )
10681070
10691071 if not xverbose :
10701072 exit (0 )
@@ -1174,38 +1176,47 @@ def include_target(target: 'CallTarget') -> bool:
11741176 if calltgt .is_so_target and include_target (calltgt ):
11751177 libcalls .add_library_callsite (faddr , instr )
11761178
1177- print ("Number of calls: " + str ( n_calls ) )
1179+ chklogger . logger . debug ("Number of calls: %s" , n_calls )
11781180
11791181 patchcallsites = libcalls .patch_callsites ()
11801182
1183+ content : Dict [str , Any ] = {}
1184+ if xjson :
1185+ xinfodata = xinfo .to_json_result ()
1186+ if xinfodata .is_ok :
1187+ content ["identification" ] = xinfodata .content
1188+ else :
1189+ write_json_result (xoutput , xinfodata , "patchcandidates" )
1190+
1191+ patch_records = []
1192+
11811193 for pc in sorted (patchcallsites , key = lambda pc :pc .faddr ):
1182- instr = pc .instr
1183- dstarg = pc .dstarg
1184- if dstarg is None :
1185- chklogger .logger .warning (
1186- "No expression found for destination argument: %s" ,
1187- str (instr ))
1188- continue
1189- dstoffset = dstarg .stack_address_offset ()
1190- fn = instr .function
1191- stackframe = fn .stackframe
1192- stackbuffer = stackframe .get_stack_buffer (dstoffset )
1193- if stackbuffer is None :
1194- chklogger .logger .warning (
1195- "No stackbuffer found for %s at offset %s" ,
1196- str (instr ), str (dstoffset ))
1194+ jresult = pc .to_json_result ()
1195+ if not jresult .is_ok :
1196+ chklogger .logger .warning ("Couldn't process patch callsite %s" , pc )
11971197 continue
1198- buffersize = stackbuffer .size
1199-
1200- print (" " + pc .instr .iaddr + " " + pc .instr .annotation )
1201- print (" - faddr: " + pc .faddr )
1202- print (" - iaddr: " + pc .instr .iaddr )
1203- print (" - target function: " + str (pc .summary .name ))
1204- print (" - stack offset: " + str (dstoffset ))
1205- print (" - length argument: " + str (pc .lenarg ))
1206- print (" - buffersize: " + str (buffersize ))
1198+
1199+ patch_records .append (jresult .content )
1200+
1201+ content ["patch-records" ] = patch_records
1202+ chklogger .logger .debug ("Number of patch callsites: %s" , len (content ['patch-records' ]))
1203+
1204+ if xjson :
1205+ jcontent = JSONResult ("patchcandidates" , content , "ok" )
1206+ write_json_result (xoutput , jcontent , "patchcandidates" )
1207+ exit (0 )
1208+
1209+ for patch_record in content ["patch-records" ]:
1210+ print (" " + patch_record ['iaddr' ] + " " + patch_record ['annotation' ])
1211+ print (" - faddr: %s" % patch_record ['faddr' ])
1212+ print (" - iaddr: %s" % patch_record ['iaddr' ])
1213+ print (" - target function: %s" % patch_record ['target-function' ])
1214+ print (" - stack offset: %s" % patch_record ['stack-offset' ])
1215+ print (" - length argument: %s" % patch_record ['length-argument' ])
1216+ print (" - buffersize: %s" % patch_record ['buffersize' ])
12071217 print ("" )
12081218
1209- print ("Number of patch callsites: " + str (len (patchcallsites )))
1219+ print ("Generated %d patch records from %d library calls" %
1220+ (len (content ['patch-records' ]), n_calls ))
12101221
12111222 exit (0 )
0 commit comments