aboutsummaryrefslogtreecommitdiff
path: root/scripts/oss-fuzz/minimize_qtest_trace.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/oss-fuzz/minimize_qtest_trace.py')
-rwxr-xr-xscripts/oss-fuzz/minimize_qtest_trace.py29
1 files changed, 20 insertions, 9 deletions
diff --git a/scripts/oss-fuzz/minimize_qtest_trace.py b/scripts/oss-fuzz/minimize_qtest_trace.py
index cacabf2638..af9767f7e4 100755
--- a/scripts/oss-fuzz/minimize_qtest_trace.py
+++ b/scripts/oss-fuzz/minimize_qtest_trace.py
@@ -97,7 +97,7 @@ def minimize_trace(inpath, outpath):
prior = newtrace[i:i+remove_step]
for j in range(i, i+remove_step):
newtrace[j] = ""
- print("Removing {lines} ...".format(lines=prior))
+ print("Removing {lines} ...\n".format(lines=prior))
if check_if_trace_crashes(newtrace, outpath):
i += remove_step
# Double the number of lines to remove for next round
@@ -110,9 +110,11 @@ def minimize_trace(inpath, outpath):
remove_step = 1
continue
newtrace[i] = prior[0] # remove_step = 1
+
# 2.) Try to replace write{bwlq} commands with a write addr, len
# command. Since this can require swapping endianness, try both LE and
# BE options. We do this, so we can "trim" the writes in (3)
+
if (newtrace[i].startswith("write") and not
newtrace[i].startswith("write ")):
suffix = newtrace[i].split()[0][-1]
@@ -133,11 +135,15 @@ def minimize_trace(inpath, outpath):
newtrace[i] = prior[0]
# 3.) If it is a qtest write command: write addr len data, try to split
- # it into two separate write commands. If splitting the write down the
- # middle does not work, try to move the pivot "left" and retry, until
- # there is no space left. The idea is to prune unneccessary bytes from
- # long writes, while accommodating arbitrary MemoryRegion access sizes
- # and alignments.
+ # it into two separate write commands. If splitting the data operand
+ # from length/2^n bytes to the left does not work, try to move the pivot
+ # to the right side, then add one to n, until length/2^n == 0. The idea
+ # is to prune unneccessary bytes from long writes, while accommodating
+ # arbitrary MemoryRegion access sizes and alignments.
+
+ # This algorithm will fail under some rare situations.
+ # e.g., xxxxxxxxxuxxxxxx (u is the unnecessary byte)
+
if newtrace[i].startswith("write "):
addr = int(newtrace[i].split()[1], 16)
length = int(newtrace[i].split()[2], 16)
@@ -146,6 +152,7 @@ def minimize_trace(inpath, outpath):
leftlength = int(length/2)
rightlength = length - leftlength
newtrace.insert(i+1, "")
+ power = 1
while leftlength > 0:
newtrace[i] = "write {addr} {size} 0x{data}\n".format(
addr=hex(addr),
@@ -157,9 +164,13 @@ def minimize_trace(inpath, outpath):
data=data[leftlength*2:])
if check_if_trace_crashes(newtrace, outpath):
break
- else:
- leftlength -= 1
- rightlength += 1
+ # move the pivot to right side
+ if leftlength < rightlength:
+ rightlength, leftlength = leftlength, rightlength
+ continue
+ power += 1
+ leftlength = int(length/pow(2, power))
+ rightlength = length - leftlength
if check_if_trace_crashes(newtrace, outpath):
i -= 1
else: