Skip to content

Commit 0d6cf1f

Browse files
committed
DWARF inlined frames support
1 parent 0d455ea commit 0d6cf1f

33 files changed

+1271
-116
lines changed

backend/arm64/emit.mlp

Lines changed: 126 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,6 +1268,125 @@ let data l =
12681268
` .align 3\n`;
12691269
List.iter emit_item l
12701270

1271+
let emit_line str = emit_string (str ^ "\n")
1272+
1273+
let file_emitter ~file_num ~file_name =
1274+
emit_line (Printf.sprintf ".file %d %S" file_num file_name)
1275+
1276+
let build_asm_directives () : (module Asm_targets.Asm_directives_intf.S) = (
1277+
module Asm_targets.Asm_directives.Make(struct
1278+
let emit_line = emit_line
1279+
1280+
let get_file_num file_name =
1281+
Emitaux.get_file_num ~file_emitter file_name
1282+
1283+
let debugging_comments_in_asm_files =
1284+
!Flambda_backend_flags.dasm_comments
1285+
1286+
module D = struct
1287+
type constant =
1288+
| Int64 of Int64.t
1289+
| Label of string
1290+
| Add of constant * constant
1291+
| Sub of constant * constant
1292+
1293+
let rec string_of_constant const =
1294+
match const with
1295+
| Int64 n -> Int64.to_string n
1296+
| Label s -> s
1297+
| Add (c1, c2) ->
1298+
Printf.sprintf "(%s + %s)"
1299+
(string_of_constant c1) (string_of_constant c2)
1300+
| Sub (c1, c2) ->
1301+
Printf.sprintf "(%s - %s)"
1302+
(string_of_constant c1) (string_of_constant c2)
1303+
1304+
let const_int64 num = Int64 num
1305+
let const_label str = Label str
1306+
let const_add c1 c2 = Add (c1, c2)
1307+
let const_sub c1 c2 = Sub (c1, c2)
1308+
1309+
type data_type =
1310+
| NONE
1311+
| DWORD
1312+
| QWORD
1313+
| VEC128
1314+
1315+
let file = file_emitter
1316+
1317+
let loc ~file_num ~line ~col ?discriminator () =
1318+
ignore discriminator;
1319+
emit_line (Printf.sprintf ".loc %d %d %d" file_num line col)
1320+
1321+
let comment str =
1322+
emit_line (Printf.sprintf "; %s" str)
1323+
1324+
let label ?data_type str =
1325+
let _ = data_type in
1326+
emit_line (Printf.sprintf "%s:" str)
1327+
1328+
let section ?delayed:_ name flags args =
1329+
match name, flags, args with
1330+
| [".data" ], _, _ -> emit_line "\t.data"
1331+
| [".text" ], _, _ -> emit_line "\t.text"
1332+
| name, flags, args ->
1333+
emit_string (Printf.sprintf "\t.section %s"
1334+
(String.concat "," name));
1335+
begin match flags with
1336+
| None -> ()
1337+
| Some flags -> emit_string (Printf.sprintf ",%S" flags)
1338+
end;
1339+
begin match args with
1340+
| [] -> ()
1341+
| _ ->
1342+
emit_string (Printf.sprintf ",%s" (String.concat "," args))
1343+
end;
1344+
emit_string "\n"
1345+
1346+
let text () = emit_line "\t.text"
1347+
1348+
let new_line () = emit_line ""
1349+
1350+
let global sym = emit_line (Printf.sprintf "\t.globl %s" sym)
1351+
1352+
let protected _sym = () (* CR mshinwell: fixme *)
1353+
1354+
let type_ sym typ_ = emit_line (Printf.sprintf "\t.type %s,%s" sym typ_)
1355+
1356+
let byte const =
1357+
emit_line
1358+
(Printf.sprintf "\t.byte %s" (string_of_constant const))
1359+
1360+
let word const =
1361+
emit_line
1362+
(Printf.sprintf "\t.short %s" (string_of_constant const))
1363+
1364+
let long const =
1365+
emit_line
1366+
(Printf.sprintf "\t.long %s" (string_of_constant const))
1367+
1368+
let qword const =
1369+
emit_line
1370+
(Printf.sprintf "\t.quad %s" (string_of_constant const))
1371+
1372+
let bytes str =
1373+
emit_line (Printf.sprintf "\t.ascii %S" str)
1374+
1375+
let uleb128 const =
1376+
emit_line
1377+
(Printf.sprintf "\t.uleb128 %s" (string_of_constant const))
1378+
1379+
let sleb128 const =
1380+
emit_line
1381+
(Printf.sprintf "\t.sleb128 %s" (string_of_constant const))
1382+
1383+
let direct_assignment var const =
1384+
emit_line
1385+
(Printf.sprintf "\t.set %s,%s" var (string_of_constant const))
1386+
end
1387+
end)
1388+
)
1389+
12711390
(* Beginning / end of an assembly file *)
12721391

12731392
let begin_assembly _unix =
@@ -1290,9 +1409,12 @@ let begin_assembly _unix =
12901409
` nop\n`;
12911410
` .align 3\n`
12921411
end;
1293-
()
1412+
let lbl_end = Cmm_helpers.make_symbol "code_end" in
1413+
Emitaux.Dwarf_helpers.begin_dwarf ~build_asm_directives
1414+
~code_begin:lbl_begin ~code_end:lbl_end
1415+
~file_emitter
12941416

1295-
let end_assembly _dwarf =
1417+
let end_assembly () =
12961418
let lbl_end = Cmm_helpers.make_symbol "code_end" in
12971419
emit_named_text_section lbl_end;
12981420
` .globl {emit_symbol lbl_end}\n`;
@@ -1325,6 +1447,8 @@ let end_assembly _dwarf =
13251447
efa_string = (fun s -> emit_string_directive " .asciz " s) };
13261448
emit_symbol_type emit_symbol lbl "object";
13271449
emit_symbol_size lbl;
1450+
if not !Flambda_backend_flags.internal_assembler then
1451+
Emitaux.Dwarf_helpers.emit_dwarf ();
13281452
begin match Config.system with
13291453
| "linux" ->
13301454
(* Mark stack as non-executable *)

backend/arm64/proc.ml

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -405,17 +405,46 @@ let frame_required ~fun_contains_calls ~fun_num_stack_slots =
405405
let prologue_required ~fun_contains_calls ~fun_num_stack_slots =
406406
frame_required ~fun_contains_calls ~fun_num_stack_slots
407407

408-
let frame_size ~stack_offset:_ ~fun_contains_calls:_ ~fun_num_stack_slots:_ =
409-
Misc.fatal_error "Full DWARF support for arm64 not yet implemented"
408+
let compute_initial_stack_offset ~fun_contains_calls ~fun_num_stack_slots =
409+
8 * fun_num_stack_slots.(0) +
410+
8 * fun_num_stack_slots.(1) +
411+
(if fun_contains_calls then 8 else 0)
412+
413+
let frame_size ~stack_offset ~fun_contains_calls ~fun_num_stack_slots =
414+
let sz =
415+
stack_offset +
416+
compute_initial_stack_offset ~fun_contains_calls ~fun_num_stack_slots
417+
in Misc.align sz 16
410418

411419
type slot_offset =
412420
| Bytes_relative_to_stack_pointer of int
413421
| Bytes_relative_to_domainstate_pointer of int
414422
[@@ocaml.warning "-37"]
415423

416-
let slot_offset _loc ~stack_class:_ ~stack_offset:_ ~fun_contains_calls:_
417-
~fun_num_stack_slots:_ =
418-
Misc.fatal_error "Full DWARF support for arm64 not yet implemented"
424+
let slot_offset (loc : Reg.stack_location) ~stack_class ~stack_offset
425+
~fun_contains_calls ~fun_num_stack_slots =
426+
match loc with
427+
Incoming n ->
428+
assert (n >= 0);
429+
let frame_size =
430+
frame_size ~stack_offset ~fun_contains_calls
431+
~fun_num_stack_slots
432+
in
433+
Bytes_relative_to_stack_pointer (frame_size + n)
434+
| Local n ->
435+
let offset =
436+
stack_offset +
437+
(if stack_class = 0
438+
then n * 8
439+
else fun_num_stack_slots.(0) * 8 + n * 8)
440+
in
441+
Bytes_relative_to_stack_pointer offset
442+
| Outgoing n ->
443+
assert (n >= 0);
444+
Bytes_relative_to_stack_pointer n
445+
| Domainstate n ->
446+
Bytes_relative_to_domainstate_pointer (
447+
n + Domainstate.(idx_of_field Domain_extra_params) * 8)
419448

420449
(* Calling the assembler *)
421450

backend/debug/compute_ranges.ml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,17 @@ module Make (S : Compute_ranges_intf.S_functor) = struct
120120

121121
let fold t ~init ~f = List.fold_left f init t.subranges
122122

123+
type get_singleton =
124+
| No_ranges
125+
| One_subrange of Subrange.t
126+
| More_than_one_subrange
127+
128+
let get_singleton t =
129+
match t.subranges with
130+
| [] -> No_ranges
131+
| [subrange] -> One_subrange subrange
132+
| _ :: _ :: _ -> More_than_one_subrange
133+
123134
let no_subranges t = match t.subranges with [] -> true | _ -> false
124135

125136
let rewrite_labels_and_remove_empty_subranges t ~env =
@@ -272,6 +283,8 @@ module Make (S : Compute_ranges_intf.S_functor) = struct
272283
keeping things fast---but we still populate ranges for all parent
273284
blocks, thus avoiding any post-processing, by using [K.all_parents]
274285
here. *)
286+
(* XXX this seems to be broken (e.g. removing parents when it shouldn't
287+
be) *)
275288
KS.fold
276289
(fun key result ->
277290
List.fold_left

backend/debug/compute_ranges_intf.ml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,8 @@ module type S = sig
216216
(** The label at the start of the range. *)
217217
val start_pos : t -> Linear.label
218218

219+
(* CR mshinwell: use Targetint.t *)
220+
219221
(** How many bytes from the label at [start_pos] the range actually
220222
commences. If this value is zero, then the first byte of the range has
221223
the address of the label given by [start_pos]. *)
@@ -251,6 +253,13 @@ module type S = sig
251253

252254
(** Fold over all subranges within the given range. *)
253255
val fold : t -> init:'a -> f:('a -> Subrange.t -> 'a) -> 'a
256+
257+
type get_singleton = private
258+
| No_ranges
259+
| One_subrange of Subrange.t
260+
| More_than_one_subrange
261+
262+
val get_singleton : t -> get_singleton
254263
end
255264

256265
(** The type holding information on computed ranges. *)

backend/debug/dwarf/dwarf_flags/dwarf_flags.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ let use_g () =
7272
then use_g1 ()
7373
else current_debug_settings := bytecode_g
7474

75-
let restrict_to_upstream_dwarf = ref true
75+
let restrict_to_upstream_dwarf = ref false
7676

7777
(* Currently the maximum number of stack slots, see asmgen.ml *)
7878
let dwarf_max_function_complexity = ref 50

backend/debug/dwarf/dwarf_ocaml/dwarf.ml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ let create ~sourcefile ~unit_name ~asm_directives ~get_file_id ~code_begin
6161
DS.create ~compilation_unit_header_label ~compilation_unit_proto_die
6262
~value_type_proto_die ~start_of_code_symbol debug_loc_table
6363
debug_ranges_table address_table location_list_table
64+
~get_file_num:get_file_id
65+
(* CR mshinwell: does get_file_id successfully emit .file directives for
66+
files we haven't seen before? *)
6467
in
6568
{ state;
6669
asm_directives;
@@ -83,10 +86,15 @@ let dwarf_for_fundecl t fundecl ~fun_end_label =
8386
(fun fundecl -> Available_ranges_vars.create fundecl)
8487
~accumulate:true fundecl
8588
in
89+
let inlined_frame_ranges, fundecl =
90+
Profile.record "debug_inlined_frame_ranges"
91+
(fun fundecl -> Inlined_frame_ranges.create fundecl)
92+
~accumulate:true fundecl
93+
in
8694
Dwarf_concrete_instances.for_fundecl ~get_file_id:t.get_file_id t.state
8795
fundecl
8896
~fun_end_label:(Asm_label.create_int Text fun_end_label)
89-
available_ranges_vars;
97+
available_ranges_vars inlined_frame_ranges;
9098
{ fun_end_label; fundecl }
9199

92100
let emit t ~basic_block_sections ~binary_backend_available =

0 commit comments

Comments
 (0)