@@ -991,6 +991,30 @@ def perc(v: float) -> str:
991991 exit (0 )
992992
993993
994+ def write_json_result (xfilename : Optional [str ],
995+ jresult : JSONResult ,
996+ schema_name : str ,
997+ ) -> None :
998+ if jresult .is_ok :
999+ okresult = JU .jsonok (schema_name , jresult .content )
1000+ if xfilename is not None :
1001+ filename = xfilename + ".json"
1002+ with open (filename , "w" ) as fp :
1003+ json .dump (okresult , fp , indent = 2 )
1004+ chklogger .logger .info ("JSON output written to " + filename )
1005+ else :
1006+ print (json .dumps (okresult ))
1007+ else :
1008+ failresult = JU .jsonfail (jresult .reason )
1009+ if xfilename is not None :
1010+ filename = xfilename + ".json"
1011+ with open (filename , "w" ) as fp :
1012+ json .dump (failresult , fp , indent = 2 )
1013+ chklogger .logger .warning (
1014+ "JSON failure output written to " + filename )
1015+ else :
1016+ print (json .dumps (failresult ))
1017+
9941018def report_buffer_bounds (args : argparse .Namespace ) -> NoReturn :
9951019
9961020 # arguments
@@ -1024,49 +1048,27 @@ def report_buffer_bounds(args: argparse.Namespace) -> NoReturn:
10241048 if calltgt .is_so_target :
10251049 libcalls .add_library_callsite (faddr , baddr , instr )
10261050
1027- def write_json_result (
1028- xfilename : Optional [str ], jresult : JSONResult ) -> None :
1029- if jresult .is_ok :
1030- okresult = JU .jsonok ("bufferboundsassessment" , jresult .content )
1031- if xfilename is not None :
1032- filename = xfilename + ".json"
1033- with open (filename , "w" ) as fp :
1034- json .dump (okresult , fp , indent = 2 )
1035- chklogger .logger .info ("JSON output written to " + filename )
1036- else :
1037- print (json .dumps (okresult ))
1038- else :
1039- failresult = JU .jsonfail (jresult .reason )
1040- if xfilename is not None :
1041- filename = xfilename + ".json"
1042- with open (filename , "w" ) as fp :
1043- json .dump (failresult , fp , indent = 2 )
1044- chklogger .logger .warning (
1045- "JSON failure output written to " + filename )
1046- else :
1047- print (json .dumps (failresult ))
1048-
10491051 if xjson :
10501052 content : Dict [str , Any ] = {}
10511053 xinfodata = xinfo .to_json_result ()
10521054 if xinfodata .is_ok :
10531055 content ["identification" ] = xinfodata .content
10541056 else :
1055- write_json_result (xoutput , xinfodata )
1057+ write_json_result (xoutput , xinfodata , "bufferboundsassessment" )
10561058 analysisstats = app .result_metrics .to_json_result ()
10571059 if analysisstats .is_ok :
10581060 content ["analysis" ] = analysisstats .content
10591061 else :
1060- write_json_result (xoutput , analysisstats )
1062+ write_json_result (xoutput , analysisstats , "bufferboundsassessment" )
10611063
10621064 libcallsresult = libcalls .to_json_result ()
10631065 if libcallsresult .is_ok :
10641066 content ["bounds" ] = libcallsresult .content
10651067 else :
1066- write_json_result (xoutput , libcallsresult )
1068+ write_json_result (xoutput , libcallsresult , "bufferboundsassessment" )
10671069
10681070 write_json_result (xoutput , JSONResult (
1069- "libcboundsanalysis" , content , "ok" ))
1071+ "libcboundsanalysis" , content , "ok" ), "bufferboundsassessment" )
10701072
10711073 if not xverbose :
10721074 exit (0 )
@@ -1181,50 +1183,55 @@ def include_target(target: 'CallTarget') -> bool:
11811183 return target .name in xtargets
11821184
11831185 for (faddr , blocks ) in app .call_instructions ().items ():
1184- fn = app .function (faddr )
1185-
11861186 for (baddr , instrs ) in blocks .items ():
11871187 for instr in instrs :
11881188 n_calls += 1
11891189 calltgt = instr .call_target
11901190 if calltgt .is_so_target and include_target (calltgt ):
11911191 libcalls .add_library_callsite (faddr , baddr , instr )
11921192
1193- print ("Number of calls: " + str ( n_calls ) )
1193+ chklogger . logger . debug ("Number of calls: %s" , n_calls )
11941194
11951195 patchcallsites = libcalls .patch_callsites ()
11961196
1197+ content : Dict [str , Any ] = {}
1198+ if xjson :
1199+ xinfodata = xinfo .to_json_result ()
1200+ if xinfodata .is_ok :
1201+ content ["identification" ] = xinfodata .content
1202+ else :
1203+ write_json_result (xoutput , xinfodata , "patchcandidates" )
1204+
1205+ patch_records = []
1206+
11971207 for pc in sorted (patchcallsites , key = lambda pc :pc .faddr ):
1198- instr = pc .instr
1199- dstarg = pc .dstarg
1200- if dstarg is None :
1201- chklogger .logger .warning (
1202- "No expression found for destination argument: %s" ,
1203- str (instr ))
1204- continue
1205- dstoffset = dstarg .stack_address_offset ()
1206- fn = app .function (pc .faddr )
1207- stackframe = fn .stackframe
1208- stackbuffer = stackframe .get_stack_buffer (dstoffset )
1209- if stackbuffer is None :
1210- chklogger .logger .warning (
1211- "No stackbuffer found for %s at offset %s" ,
1212- str (instr ), str (dstoffset ))
1208+ jresult = pc .to_json_result (app )
1209+ if not jresult .is_ok :
1210+ chklogger .logger .warning ("Couldn't process patch callsite %s" , pc )
12131211 continue
1214- buffersize = stackbuffer .size
1215- basicblock = fn .block (pc .baddr )
1216- spare = find_spare_instruction (basicblock , instr .iaddr )
1217-
1218- print (" " + pc .instr .iaddr + " " + pc .instr .annotation )
1219- print (" - faddr: " + pc .faddr )
1220- print (" - iaddr: " + pc .instr .iaddr )
1221- print (" - target function: " + str (pc .summary .name ))
1222- print (" - stack offset: " + str (dstoffset ))
1223- print (" - length argument: " + str (pc .lenarg ))
1224- print (" - buffersize: " + str (buffersize ))
1225- print (" - spare: " + str (spare ))
1212+
1213+ patch_records .append (jresult .content )
1214+
1215+ content ["patch-records" ] = patch_records
1216+ chklogger .logger .debug ("Number of patch callsites: %s" , len (content ['patch-records' ]))
1217+
1218+ if xjson :
1219+ jcontent = JSONResult ("patchcandidates" , content , "ok" )
1220+ write_json_result (xoutput , jcontent , "patchcandidates" )
1221+ exit (0 )
1222+
1223+ for patch_record in content ["patch-records" ]:
1224+ print (" " + patch_record ['iaddr' ] + " " + patch_record ['annotation' ])
1225+ print (" - faddr: %s" % patch_record ['faddr' ])
1226+ print (" - iaddr: %s" % patch_record ['iaddr' ])
1227+ print (" - target function: %s" % patch_record ['target-function' ])
1228+ print (" - stack offset: %s" % patch_record ['stack-offset' ])
1229+ print (" - length argument: %s" % patch_record ['length-argument' ])
1230+ print (" - buffersize: %s" % patch_record ['buffersize' ])
1231+ print (" - spare: %s" % patch_record ['spare' ])
12261232 print ("" )
12271233
1228- print ("Number of patch callsites: " + str (len (patchcallsites )))
1234+ print ("Generated %d patch records from %d library calls" %
1235+ (len (content ['patch-records' ]), n_calls ))
12291236
12301237 exit (0 )
0 commit comments