package jasmin

  1. Overview
  2. Docs
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Source file asm_utils.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
open Arch_decl
open PrintCommon
open Prog
open Utils
open PrintASM

let global_datas_label = "glob_data"

let pp_syscall (o : _ Syscall_t.syscall_t) =
  match o with
  | Syscall_t.RandomBytes _ -> "__jasmin_syscall_randombytes__"

let string_of_label name p = Format.asprintf "L%s$%d" (escape name) (Conv.int_of_pos p)

let pp_remote_label (fn, lbl) =
  string_of_label fn.fn_name lbl

let mangle x = Format.asprintf "_%s" x

let string_of_glob occurrences x =
  Hash.modify_def (-1) x.v_name Stdlib.Int.succ occurrences;
  let count =  Hash.find occurrences x.v_name in
  (* Adding the number of occurrences to the label to avoid names conflict *)
  let suffix = if count > 0 then Format.asprintf "$%d" count else "" in
  Format.asprintf "G$%s%s" (escape x.v_name) suffix

let format_glob_data globs names =
  (* Creating a Hashtable to count occurrences of a label name*)
  let occurrences = Hash.create 42 in
  let names =
    List.map (fun ((x, _), p) -> (Conv.var_of_cvar x, Conv.z_of_cz p)) names
  in
  List.flatten
    (List.mapi
       (fun i b ->
         let b = Byte (Z.to_string (Conv.z_of_int8 b)) in
         match List.find (fun (_, p) -> Z.equal (Z.of_int i) p) names with
         | exception Not_found -> [ b ]
         | x, _ -> [ Label (string_of_glob occurrences x); b ])
       globs)

(* TODO : Move*)
let hash_to_string (to_string : 'a -> string) =
  let tbl = Hashtbl.create 17 in
  fun r ->
    try Hashtbl.find tbl r
    with Not_found ->
      let s = to_string r in
      Hashtbl.add tbl r s;
      s

let pp_imm imm_pre imm = Format.asprintf "%s%s" imm_pre (Z.to_string imm)

let pp_rip_address p : string =
  Format.asprintf "%s+%a" global_datas_label Z.pp_print (Conv.z_of_int32 p)

let pp_register arch = hash_to_string arch.toS_r.to_string

type parsed_reg_address = {
  base : string;
  displacement : string option;
  offset : string option;
  scale : string option;
}

let parse_reg_address (arch : ('a, 'b, 'c, 'd, 'e) arch_decl) addr =
  match addr.ad_base with
  | None -> failwith (Format.asprintf "TODO_RISC: pp_reg_address")
  | Some r ->
      let base = pp_register arch r in
      let displacement = Conv.z_of_word (arch_pd arch) addr.ad_disp in
      let displacement =
        if Z.equal displacement Z.zero then None
        else Some (Z.to_string displacement)
      in
      let offset = Option.map (pp_register arch) addr.ad_offset in
      let scale = Conv.z_of_nat addr.ad_scale in
      let scale =
        if Z.equal scale Z.zero then None else Some (Z.to_string scale)
      in
      { base; displacement; offset; scale }