Ensure a crashing FDE still generates other FDEs
This commit is contained in:
parent
d7c1aaa6b5
commit
719fa27f99
5 changed files with 131 additions and 13 deletions
|
@ -1,7 +1,9 @@
|
||||||
open Std
|
open Std
|
||||||
|
|
||||||
let main outfile proj =
|
let main outfile proj =
|
||||||
let pre_dwarf = Simplest.of_proj proj in
|
let pre_dwarf = proj
|
||||||
|
|> Simplest.of_proj
|
||||||
|
|> Simplest.clean_lost_track_subs in
|
||||||
Format.printf "%a" Frontend.pp_pre_dwarf_readelf pre_dwarf;
|
Format.printf "%a" Frontend.pp_pre_dwarf_readelf pre_dwarf;
|
||||||
let pre_c_dwarf = PreCBinding.convert_pre_c pre_dwarf in
|
let pre_c_dwarf = PreCBinding.convert_pre_c pre_dwarf in
|
||||||
let fd = open_out_bin outfile in
|
let fd = open_out_bin outfile in
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
open Simplest
|
open Simplest
|
||||||
open Std
|
open Std
|
||||||
|
|
||||||
|
exception InvalidPreDwarf of string
|
||||||
|
|
||||||
type pre_c_pre_dwarf_entry = {
|
type pre_c_pre_dwarf_entry = {
|
||||||
location: int64;
|
location: int64;
|
||||||
cfa_offset: int64;
|
cfa_offset: int64;
|
||||||
|
@ -58,7 +60,9 @@ let convert_pre_c_entry loc entry : pre_c_pre_dwarf_entry =
|
||||||
let offset, offset_reg = (match entry with
|
let offset, offset_reg = (match entry with
|
||||||
| RspOffset off -> off, 7
|
| RspOffset off -> off, 7
|
||||||
| RbpOffset off -> off, 6
|
| RbpOffset off -> off, 6
|
||||||
| CfaLostTrack -> assert false (* Should be filtered out beforehand *)
|
| CfaLostTrack ->
|
||||||
|
raise (InvalidPreDwarf
|
||||||
|
("CfaLostTrack should be filtered out beforehand"))
|
||||||
) in
|
) in
|
||||||
{
|
{
|
||||||
location = loc;
|
location = loc;
|
||||||
|
@ -72,22 +76,33 @@ let convert_pre_c_entries entries : pre_c_pre_dwarf_entry array =
|
||||||
(fun loc entry _ -> convert_pre_c_entry loc entry)
|
(fun loc entry _ -> convert_pre_c_entry loc entry)
|
||||||
entries empty_entry
|
entries empty_entry
|
||||||
|
|
||||||
let convert_pre_c_fde name entry id : pre_c_pre_dwarf_fde =
|
let convert_pre_c_fde name entry : pre_c_pre_dwarf_fde option =
|
||||||
{
|
try
|
||||||
|
Some {
|
||||||
num = AddrMap.cardinal entry.cfa_changes_fde;
|
num = AddrMap.cardinal entry.cfa_changes_fde;
|
||||||
initial_location = entry.beg_pos;
|
initial_location = entry.beg_pos;
|
||||||
end_location = entry.end_pos;
|
end_location = entry.end_pos;
|
||||||
name = name;
|
name = name;
|
||||||
entries = convert_pre_c_entries entry.cfa_changes_fde
|
entries = convert_pre_c_entries entry.cfa_changes_fde
|
||||||
}
|
}
|
||||||
|
with InvalidPreDwarf reason -> (
|
||||||
|
Format.eprintf "FAILED subroutine %s: %s@." name reason ;
|
||||||
|
None
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
module StrMapTool = MapTool(StrMap)
|
module StrMapTool = MapTool(StrMap)
|
||||||
let convert_pre_c (cfa_map: subroutine_cfa_map) : pre_c_pre_dwarf =
|
let convert_pre_c (cfa_map: subroutine_cfa_map) : pre_c_pre_dwarf =
|
||||||
(** Converts a `subroutine_cfa_map` to a `pre_c_pre_dwarf` type, in
|
(** Converts a `subroutine_cfa_map` to a `pre_c_pre_dwarf` type, in
|
||||||
preparation for C coversion. *)
|
preparation for C coversion. *)
|
||||||
let num_fde = StrMap.cardinal cfa_map in
|
let num_fde = StrMap.cardinal cfa_map in
|
||||||
let fdes = StrMapTool.fold_map_to_array
|
let fdes_list_with_none = StrMap.fold (fun name entry folded ->
|
||||||
convert_pre_c_fde cfa_map empty_fde in
|
(convert_pre_c_fde name entry) :: folded)
|
||||||
|
cfa_map [] in
|
||||||
|
let fdes_list = List.fold_left (fun folded elt -> match elt with
|
||||||
|
| Some x -> x::folded
|
||||||
|
| None -> folded) [] fdes_list_with_none in
|
||||||
|
let fdes = Array.of_list fdes_list in
|
||||||
{
|
{
|
||||||
num_fde = num_fde ;
|
num_fde = num_fde ;
|
||||||
fdes = fdes
|
fdes = fdes
|
||||||
|
|
|
@ -458,3 +458,13 @@ let of_proj proj : subroutine_cfa_map =
|
||||||
(** Extracts the `cfa_changes` of a project *)
|
(** Extracts the `cfa_changes` of a project *)
|
||||||
let prog = BStd.Project.program proj in
|
let prog = BStd.Project.program proj in
|
||||||
of_prog prog
|
of_prog prog
|
||||||
|
|
||||||
|
let clean_lost_track_subs pre_dwarf : subroutine_cfa_map =
|
||||||
|
(** Removes the subroutines on which we lost track from [pre_dwarf] *)
|
||||||
|
let sub_lost_track sub_name (sub: subroutine_cfa_data) =
|
||||||
|
not @@ AddrMap.exists (fun addr pos -> (match pos with
|
||||||
|
| RspOffset _ | RbpOffset _ -> false
|
||||||
|
| CfaLostTrack -> true))
|
||||||
|
sub.cfa_changes_fde
|
||||||
|
in
|
||||||
|
StrMap.filter sub_lost_track pre_dwarf
|
||||||
|
|
91
csmith/csmith_test_generated.sh
Executable file
91
csmith/csmith_test_generated.sh
Executable file
|
@ -0,0 +1,91 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
USAGE="$0 nb_tests kept_directory"
|
||||||
|
|
||||||
|
if [ "$#" -lt 1 ] ; then
|
||||||
|
>&2 echo -e "Missing argument(s). Usage:\n$USAGE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
NB_TESTS=$1
|
||||||
|
KEPT_DIRECTORY=$2
|
||||||
|
RUN_TIMEOUT=2
|
||||||
|
|
||||||
|
tmpdir="$(mktemp -d)"
|
||||||
|
error_count=0
|
||||||
|
|
||||||
|
function statusline {
|
||||||
|
echo -ne "\r\e[1m[\e[32m$(printf "%03d/%03d" "$1" "$NB_TESTS")\e[39m] >>>\e[0m $2 "
|
||||||
|
}
|
||||||
|
|
||||||
|
function reporterror {
|
||||||
|
echo -e "\n\e[1;31m[$(printf "%03d" $1)] Error: \e[0m $2"
|
||||||
|
}
|
||||||
|
|
||||||
|
function mkpath {
|
||||||
|
echo "$tmpdir/$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
function failed_test {
|
||||||
|
path=$(mkpath $1)
|
||||||
|
cp "$path."* "$KEPT_DIRECTORY"
|
||||||
|
reporterror "$1" "$2"
|
||||||
|
error_count=$((error_count + 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_empty_dwarf {
|
||||||
|
path="$2"
|
||||||
|
statusline $1 "test DWARF emptyness"
|
||||||
|
if [ -z "$(readelf -wF "$path.eh.bin")" ]; then
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_run {
|
||||||
|
path="$2"
|
||||||
|
statusline $1 "running binaries"
|
||||||
|
orig="$(timeout $RUN_TIMEOUT "$path.orig.bin")"
|
||||||
|
orig_status=$?
|
||||||
|
synth="$(timeout $RUN_TIMEOUT "$path.eh.bin")"
|
||||||
|
synth_status=$?
|
||||||
|
|
||||||
|
if [ "$orig_status" -ne "$synth_status" ] || [ "$orig" != "$synth" ] ; then
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
mkdir -p "$KEPT_DIRECTORY"
|
||||||
|
|
||||||
|
statusline "" ""
|
||||||
|
for num in $(seq 1 $NB_TESTS); do
|
||||||
|
## Generation, compilation, synthesis
|
||||||
|
statusline $num "csmith"
|
||||||
|
path=$(mkpath $num)
|
||||||
|
csmith > "$path.c"
|
||||||
|
statusline $num "compiling"
|
||||||
|
gcc -O2 -I/usr/include/csmith-2.3.0/ -w "$path.c" -o "$path.orig.bin"
|
||||||
|
objcopy --remove-section '.eh_frame' --remove-section '.eh_frame_hdr' \
|
||||||
|
"$path.orig.bin" "$path.bin"
|
||||||
|
statusline $num "generating dwarf"
|
||||||
|
../synthesize_dwarf.sh "$path.bin" "$path.eh.bin"
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
if ! test_empty_dwarf "$num" "$path"; then
|
||||||
|
failed_test "$num" "empty generated DWARF"
|
||||||
|
elif ! test_run "$num" "$path"; then
|
||||||
|
failed_test "$num" "different execution behaviour"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
if [ "$error_count" -eq "0" ] ; then
|
||||||
|
echo -e "\n== ALL TESTS PASSED =="
|
||||||
|
else
|
||||||
|
echo -e "\n== FAILED TESTS: $error_count/$NB_TESTS =="
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -rf "$tmpdir"
|
|
@ -35,7 +35,7 @@ function find_ml_dwarf_write {
|
||||||
}
|
}
|
||||||
|
|
||||||
function bap_synth {
|
function bap_synth {
|
||||||
bap "$INPUT_FILE" -p dwarfsynth --dwarfsynth-output "$TMP_DIR/marshal" \
|
bap "$INPUT_FILE" --no-byteweight -p dwarfsynth --dwarfsynth-output "$TMP_DIR/marshal" \
|
||||||
> /dev/null
|
> /dev/null
|
||||||
return $?
|
return $?
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue