Enhance eh_frame validity checker/differ
This commit is contained in:
parent
681153b954
commit
fc8c9c45d6
71
csmith/check_generated_eh_frame.py
Normal file → Executable file
71
csmith/check_generated_eh_frame.py
Normal file → Executable file
|
@ -5,6 +5,13 @@ class NotFDE(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def func_name(infos, symtb):
|
||||||
|
for sym in symtb:
|
||||||
|
if infos["beg"] == symtb[sym][0]:
|
||||||
|
return sym
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def parse_fde_head(line):
|
def parse_fde_head(line):
|
||||||
spl = line.strip().split()
|
spl = line.strip().split()
|
||||||
assert len(spl) >= 2
|
assert len(spl) >= 2
|
||||||
|
@ -59,7 +66,7 @@ def parse_fde(lines):
|
||||||
return {"beg": pc_beg, "end": pc_end, "rows": clean_rows(rows)}
|
return {"beg": pc_beg, "end": pc_end, "rows": clean_rows(rows)}
|
||||||
|
|
||||||
|
|
||||||
def parse_eh_frame(handle):
|
def parse_eh_frame(handle, symtb):
|
||||||
output = []
|
output = []
|
||||||
cur_lines = []
|
cur_lines = []
|
||||||
for line in handle:
|
for line in handle:
|
||||||
|
@ -72,7 +79,10 @@ def parse_eh_frame(handle):
|
||||||
if cur_lines != []:
|
if cur_lines != []:
|
||||||
infos = parse_fde(cur_lines)
|
infos = parse_fde(cur_lines)
|
||||||
if infos:
|
if infos:
|
||||||
output.append(infos)
|
symname = func_name(infos, symtb)
|
||||||
|
if symname not in ["_start", "__libc_csu_init"]:
|
||||||
|
# These functions have weird instructions
|
||||||
|
output.append(infos)
|
||||||
cur_lines = []
|
cur_lines = []
|
||||||
else:
|
else:
|
||||||
cur_lines.append(line)
|
cur_lines.append(line)
|
||||||
|
@ -94,13 +104,15 @@ def match_segments(orig_eh, synth_eh):
|
||||||
matches[1][synth_id] = True # PLT -- fake match
|
matches[1][synth_id] = True # PLT -- fake match
|
||||||
continue
|
continue
|
||||||
if matches[1][synth_id]:
|
if matches[1][synth_id]:
|
||||||
print("Multiple matches (synth)")
|
# print("Multiple matches (synth)")
|
||||||
|
pass
|
||||||
if matches[0][orig_id]:
|
if matches[0][orig_id]:
|
||||||
print(
|
pass
|
||||||
"Multiple matches (orig) {}--{}".format(
|
# print(
|
||||||
hex(orig_fde["beg"]), hex(orig_fde["end"])
|
# "Multiple matches (orig) {}--{}".format(
|
||||||
)
|
# hex(orig_fde["beg"]), hex(orig_fde["end"])
|
||||||
)
|
# )
|
||||||
|
# )
|
||||||
else:
|
else:
|
||||||
matches[0][orig_id] = True
|
matches[0][orig_id] = True
|
||||||
matches[1][synth_id] = True
|
matches[1][synth_id] = True
|
||||||
|
@ -157,27 +169,52 @@ def match_fde(orig, synth):
|
||||||
):
|
):
|
||||||
continue
|
continue
|
||||||
if cur_val[0] != cur_val[1]:
|
if cur_val[0] != cur_val[1]:
|
||||||
print("Mis {} ; {}".format(cur_val[0], cur_val[1]))
|
# print("Mis {} ; {}".format(cur_val[0], cur_val[1]))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def parse_sym_table(handle):
|
||||||
|
out_map = {}
|
||||||
|
for line in handle:
|
||||||
|
line = line.strip()
|
||||||
|
if line == "===":
|
||||||
|
break
|
||||||
|
|
||||||
|
spl = list(map(lambda x: x.strip(), line.split()))
|
||||||
|
loc = int(spl[1], 16)
|
||||||
|
size = int(spl[2])
|
||||||
|
name = spl[7]
|
||||||
|
out_map[name] = (loc, size)
|
||||||
|
return out_map
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
orig_eh = parse_eh_frame(sys.stdin)
|
if len(sys.argv) < 2:
|
||||||
synth_eh = parse_eh_frame(sys.stdin)
|
print("Missing argument: test_name", file=sys.stderr)
|
||||||
|
test_name = sys.argv[1]
|
||||||
|
symtb = parse_sym_table(sys.stdin)
|
||||||
|
orig_eh = parse_eh_frame(sys.stdin, symtb)
|
||||||
|
synth_eh = parse_eh_frame(sys.stdin, symtb)
|
||||||
matched, unmatched_orig, unmatched_synth = match_segments(orig_eh, synth_eh)
|
matched, unmatched_orig, unmatched_synth = match_segments(orig_eh, synth_eh)
|
||||||
print(len(matched), len(unmatched_orig), len(unmatched_synth))
|
# dump_light_fdes(unmatched_orig)
|
||||||
dump_light_fdes(unmatched_orig)
|
# dump_light_fdes(unmatched_synth)
|
||||||
print("==")
|
|
||||||
dump_light_fdes(unmatched_synth)
|
|
||||||
|
|
||||||
mismatches = 0
|
mismatches = 0
|
||||||
for (orig, synth) in matched:
|
for (orig, synth) in matched:
|
||||||
if not match_fde(orig, synth):
|
if not match_fde(orig, synth):
|
||||||
print("MISMATCH: {} ; {}".format(fde_pos(orig), fde_pos(synth)))
|
|
||||||
mismatches += 1
|
mismatches += 1
|
||||||
print("TOTAL: {}/{}".format(mismatches, len(matched)))
|
reports = []
|
||||||
|
if mismatches > 0:
|
||||||
|
reports.append("{} mismatches".format(mismatches))
|
||||||
|
if unmatched_orig:
|
||||||
|
reports.append("{} unmatched (orig)".format(len(unmatched_orig)))
|
||||||
|
if unmatched_synth:
|
||||||
|
reports.append("{} unmatched (synth)".format(len(unmatched_synth)))
|
||||||
|
|
||||||
|
if reports:
|
||||||
|
print("{}: {}".format(test_name, "; ".join(reports)))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
25
csmith/check_generated_eh_frame.sh
Executable file
25
csmith/check_generated_eh_frame.sh
Executable file
|
@ -0,0 +1,25 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
USAGE="$0 base_path\nThe base path of eg. 01/01.eh.bin is 01/01"
|
||||||
|
|
||||||
|
if [ "$#" -lt 1 ] ; then
|
||||||
|
>&2 echo -e "Missing argument(s). Usage:\n$USAGE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
base_path="$1"
|
||||||
|
orig_path="$1.orig.bin"
|
||||||
|
eh_path="$1.eh.bin"
|
||||||
|
|
||||||
|
py_checker="$(dirname "$0")/$(basename "$0" ".sh").py"
|
||||||
|
|
||||||
|
if ! [ -x "$orig_path" ] || ! [ -x "$eh_path" ]; then
|
||||||
|
>&2 echo -e "$orig_path or $eh_path does not exist or is not executable"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
( ( readelf --syms "$orig_path" | grep "FUNC" ) ; \
|
||||||
|
echo "===" ; \
|
||||||
|
readelf -wF "$orig_path" ; \
|
||||||
|
echo "===" ; \
|
||||||
|
readelf -wF "$eh_path") | python $py_checker "$base_path"
|
Loading…
Reference in a new issue