From 9fca4aade48f109ab4b36c179b7f067e04386f74 Mon Sep 17 00:00:00 2001 From: rina Date: Mon, 1 Jul 2024 16:27:50 +1000 Subject: [PATCH 1/3] dis: add function to extract disasm name --- libASL/dis.ml | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/libASL/dis.ml b/libASL/dis.ml index f7b9ed1b..caea0bfa 100644 --- a/libASL/dis.ml +++ b/libASL/dis.ml @@ -1386,11 +1386,11 @@ let dis_decode_slice (loc: l) (x: decode_slice) (op: Primops.bigint): value rws ) (* Duplicate of eval_decode_case modified to print rather than eval *) -let rec dis_decode_case (loc: AST.l) (x: decode_case) (op: Primops.bigint): unit rws = +let rec dis_decode_case (loc: AST.l) (x: decode_case) (op: Primops.bigint): string rws = let body = dis_decode_case' loc x op in if no_debug() then body - else DisEnv.scope loc "dis_decode_case" (pp_decode_case x) Utils.pp_unit body -and dis_decode_case' (loc: AST.l) (x: decode_case) (op: Primops.bigint): unit rws = + else DisEnv.scope loc "dis_decode_case" (pp_decode_case x) Fun.id body +and dis_decode_case' (loc: AST.l) (x: decode_case) (op: Primops.bigint): string rws = (match x with | DecoderCase_Case (ss, alts, loc) -> let@ vs = DisEnv.traverse (fun s -> dis_decode_slice loc s op) ss in @@ -1399,8 +1399,8 @@ and dis_decode_case' (loc: AST.l) (x: decode_case) (op: Primops.bigint): unit rw | (alt :: alts') -> let@ alt' = dis_decode_alt loc alt vs op in (match alt' with - | true -> DisEnv.unit - | false -> dis alts') + | Some x -> DisEnv.pure x + | None -> dis alts') | [] -> raise (DisInternalError (loc, "unmatched decode pattern")) ) @@ -1409,16 +1409,16 @@ and dis_decode_case' (loc: AST.l) (x: decode_case) (op: Primops.bigint): unit rw ) (* Duplicate of eval_decode_alt modified to print rather than eval *) -and dis_decode_alt (loc: l) (x: decode_alt) (vs: value list) (op: Primops.bigint): bool rws = +and dis_decode_alt (loc: l) (x: decode_alt) (vs: value list) (op: Primops.bigint): string option rws = let body = dis_decode_alt' loc x vs op in if no_debug() then body - else DisEnv.scope loc "dis_decode_alt" (pp_decode_alt x) string_of_bool body -and dis_decode_alt' (loc: AST.l) (DecoderAlt_Alt (ps, b)) (vs: value list) (op: Primops.bigint): bool rws = + else DisEnv.scope loc "dis_decode_alt" (pp_decode_alt x) Option.(fold ~none:"(unmatched)" ~some:Fun.id) body +and dis_decode_alt' (loc: AST.l) (DecoderAlt_Alt (ps, b)) (vs: value list) (op: Primops.bigint): string option rws = if List.for_all2 (Eval.eval_decode_pattern loc) ps vs then (match b with | DecoderBody_UNPRED loc -> raise (Throw (loc, Exc_Unpredictable)) | DecoderBody_UNALLOC loc -> raise (Throw (loc, Exc_Undefined)) - | DecoderBody_NOP loc -> DisEnv.pure true + | DecoderBody_NOP loc -> DisEnv.pure (Some "(NOP)") | DecoderBody_Encoding (inst, l) -> let@ (enc, opost, cond, exec) = DisEnv.reads (fun env -> Eval.Env.getInstruction loc env inst) in let@ enc_match = dis_encoding enc op in @@ -1450,9 +1450,9 @@ and dis_decode_alt' (loc: AST.l) (DecoderAlt_Alt (ps, b)) (vs: value list) (op: end; let@ () = DisEnv.write stmts in - DisEnv.pure true + DisEnv.pure (Some (pprint_ident inst)) end else begin - DisEnv.pure false + DisEnv.pure None end | DecoderBody_Decoder (fs, c, loc) -> let@ () = DisEnv.modify (LocalEnv.addLevel) in @@ -1462,12 +1462,12 @@ and dis_decode_alt' (loc: AST.l) (DecoderAlt_Alt (ps, b)) (vs: value list) (op: declare_assign_var loc (val_type v) f (Val v) ) fs in - let@ () = dis_decode_case loc c op in + let@ result = dis_decode_case loc c op in let@ () = DisEnv.modify (LocalEnv.popLevel) in - DisEnv.pure true + DisEnv.pure (Some result) ) else - DisEnv.pure false + DisEnv.pure None type env = (LocalEnv.t * IdentSet.t) @@ -1480,9 +1480,9 @@ let enum_types env i = | Some l -> Some (Z.log2up (Z.of_int (List.length l))) | _ -> None -let dis_decode_entry (env: Eval.Env.t) ((lenv,globals): env) (decode: decode_case) (op: Primops.bigint): stmt list = +let dis_decode_entry_with_inst (env: Eval.Env.t) ((lenv,globals): env) (decode: decode_case) (op: Primops.bigint): string * stmt list = let DecoderCase_Case (_,_,loc) = decode in - let ((),lenv',stmts) = (dis_decode_case loc decode op) env lenv in + let (inst,lenv',stmts) = (dis_decode_case loc decode op) env lenv in let varentries = List.(concat @@ map (fun vars -> StringMap.(bindings (map fst vars))) lenv.locals) in let bindings = Asl_utils.Bindings.of_seq @@ List.to_seq @@ List.map (fun (x,y) -> (Ident x,y)) varentries in (* List.iter (fun (v,t) -> Printf.printf ("%s:%s\n") v (pp_type t)) varentries; *) @@ -1505,7 +1505,10 @@ let dis_decode_entry (env: Eval.Env.t) ((lenv,globals): env) (decode: decode_cas List.iter (fun s -> Printf.printf "%s\n" (pp_stmt s)) stmts'; Printf.printf "===========\n"; end; - stmts' + inst, stmts' + +let dis_decode_entry (env: Eval.Env.t) ((lenv,globals): env) (decode: decode_case) (op: Primops.bigint): stmt list = + snd @@ dis_decode_entry_with_inst env (lenv, globals) decode op let build_env (env: Eval.Env.t): env = let env = Eval.Env.freeze env in From 8ce869fd877130f61ebb8679705dc78b77e74e58 Mon Sep 17 00:00:00 2001 From: rina Date: Mon, 1 Jul 2024 16:34:33 +1000 Subject: [PATCH 2/3] server: return 'encoding' field to store the instruction encoding name --- bin/server.ml | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/bin/server.ml b/bin/server.ml index 77a14ba3..ae8e2509 100644 --- a/bin/server.ml +++ b/bin/server.ml @@ -17,24 +17,28 @@ open Lwt let persistent_env = lazy (Option.get (Arm_env.aarch64_evaluation_environment ())) -let eval_instr (opcode: string) : string = +let eval_instr (opcode: string) : string * string = let pp_raw stmt : string = Utils.to_string (Asl_parser_pp.pp_raw_stmt stmt) |> String.trim in - let address = None in - let env' = Lazy.force persistent_env in - let stmts : Asl_ast.stmt list = Dis.retrieveDisassembly ?address env' (Dis.build_env env') opcode in - let stmts' = List.map pp_raw stmts in - String.concat "\n" stmts' + let _address = None in + + let env' = Lazy.force persistent_env in + let lenv = Dis.build_env env' in + let decoder = Eval.Env.getDecoder env' (Ident "A64") in + let (enc, stmts) = Dis.dis_decode_entry_with_inst env' lenv decoder (Z.of_string opcode) in + + let stmts' = List.map pp_raw stmts in + enc, String.concat "\n" stmts' let get_reply (jsonin: string) : Cohttp.Code.status_code * string = (*let json = Yojson.Safe.from_string jsonin in *) let make_reply code tail = - (code, Yojson.Safe.to_string (`Assoc [("instruction", `String jsonin); tail])) in + (code, Yojson.Safe.to_string (`Assoc (["instruction", `String jsonin] @ tail))) in Printf.printf "Disassembling '%s'\n" jsonin; flush stdout; match (eval_instr jsonin) with - | exception e -> make_reply `Internal_server_error ("error", `String (Printexc.to_string e)) - | x -> make_reply `OK ("semantics", `String x) + | exception e -> make_reply `Internal_server_error ["error", `String (Printexc.to_string e)] + | enc, x -> make_reply `OK [ "encoding", `String enc; "semantics", `String x; ] let unsupp_method_resp : Cohttp.Code.status_code * string = From 2a4bb833b022a85db81f04423f4a744667b90fad Mon Sep 17 00:00:00 2001 From: rina Date: Tue, 2 Jul 2024 10:43:03 +1000 Subject: [PATCH 3/3] aslp-cpp: also return encoding name --- aslp-cpp/include/aslp-cpp/aslp-cpp.hpp | 7 +++++-- aslp-cpp/source/aslp-cpp.cpp | 9 ++++++--- aslp-cpp/test/source/aslp-cpp_test.cpp | 3 ++- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/aslp-cpp/include/aslp-cpp/aslp-cpp.hpp b/aslp-cpp/include/aslp-cpp/aslp-cpp.hpp index 08feb239..485e334a 100644 --- a/aslp-cpp/include/aslp-cpp/aslp-cpp.hpp +++ b/aslp-cpp/include/aslp-cpp/aslp-cpp.hpp @@ -7,6 +7,9 @@ namespace httplib { class Client; } // namespace httplib; +// tuple of encoding and semantics +using aslp_opcode_result_t = std::tuple; + class aslp_connection { std::unique_ptr client {nullptr}; @@ -14,7 +17,7 @@ class aslp_connection public: aslp_connection(const std::string& server_addr, int server_port); aslp_connection(aslp_connection&&) noexcept; - auto get_opcode(uint32_t opcode) -> std::string; + auto get_opcode(uint32_t opcode) -> aslp_opcode_result_t; void wait_active(); ~aslp_connection(); }; @@ -54,7 +57,7 @@ class aslp_client { auto static start(const std::string& addr, int server_port) -> std::unique_ptr; /** Returns the semantics for the given opcode, as a newline-separated string. */ - auto get_opcode(uint32_t opcode) -> std::string; + auto get_opcode(uint32_t opcode) -> aslp_opcode_result_t; /** Destroys the aslp_client and terminates the managed server as well. */ virtual ~aslp_client() { diff --git a/aslp-cpp/source/aslp-cpp.cpp b/aslp-cpp/source/aslp-cpp.cpp index 57cf5e75..598d504f 100644 --- a/aslp-cpp/source/aslp-cpp.cpp +++ b/aslp-cpp/source/aslp-cpp.cpp @@ -147,7 +147,7 @@ void aslp_connection::wait_active() std::cout << "\n"; } -std::string aslp_connection::get_opcode(uint32_t opcode) +aslp_opcode_result_t aslp_connection::get_opcode(uint32_t opcode) { auto codestr = std::format("{:#x}", opcode); std::cout << codestr << "\n"; @@ -167,7 +167,10 @@ std::string aslp_connection::get_opcode(uint32_t opcode) if (!result.contains("semantics")) { throw std::runtime_error("semantics missing"); } - return result["semantics"]; + if (!result.contains("encoding")) { + throw std::runtime_error("encoding name missing"); + } + return {result["encoding"], result["semantics"]}; } aslp_connection::aslp_connection(const std::string& server_addr, @@ -179,7 +182,7 @@ aslp_connection::aslp_connection(const std::string& server_addr, aslp_connection::aslp_connection(aslp_connection&&) noexcept = default; aslp_connection::~aslp_connection() = default; -std::string aslp_client::get_opcode(uint32_t opcode) +aslp_opcode_result_t aslp_client::get_opcode(uint32_t opcode) { aslp_connection conn {server_addr, server_port}; conn.wait_active(); diff --git a/aslp-cpp/test/source/aslp-cpp_test.cpp b/aslp-cpp/test/source/aslp-cpp_test.cpp index ed1e825f..2bf68775 100644 --- a/aslp-cpp/test/source/aslp-cpp_test.cpp +++ b/aslp-cpp/test/source/aslp-cpp_test.cpp @@ -8,7 +8,8 @@ auto main() -> int auto s = aslp_client::start(); try { - auto c = s->get_opcode(0xFD430091); + std::string c; + std::tie(std::ignore, c) = s->get_opcode(0xFD430091); std::cout << c << "\n"; } catch (std::runtime_error &e) { std::cout << " error " << e.what() << "\n";