Skip to content

Commit 57c7e94

Browse files
committed
Encode and decode tag types in dwarf properly. Add list module to std. Shift rustc to use std.util.option. Fix various dependent bugs. Closes #73.
1 parent fc2d482 commit 57c7e94

File tree

10 files changed

+243
-114
lines changed

10 files changed

+243
-114
lines changed

src/boot/me/dwarf.ml

+130-35
Original file line numberDiff line numberDiff line change
@@ -1211,6 +1211,19 @@ let (abbrev_subprogram:abbrev) =
12111211
|])
12121212
;;
12131213

1214+
let (abbrev_tag_constructor_subprogram:abbrev) =
1215+
(DW_TAG_subprogram, DW_CHILDREN_yes,
1216+
[|
1217+
(DW_AT_name, DW_FORM_string);
1218+
(DW_AT_rust_tag_type_id, DW_FORM_data4);
1219+
(DW_AT_discr_value, DW_FORM_data4);
1220+
(DW_AT_low_pc, DW_FORM_addr);
1221+
(DW_AT_high_pc, DW_FORM_addr);
1222+
(DW_AT_frame_base, DW_FORM_block1);
1223+
(DW_AT_return_addr, DW_FORM_block1);
1224+
|])
1225+
;;
1226+
12141227
let (abbrev_typedef:abbrev) =
12151228
(DW_TAG_typedef, DW_CHILDREN_yes,
12161229
[|
@@ -1233,7 +1246,7 @@ let (abbrev_variable:abbrev) =
12331246
(DW_TAG_variable, DW_CHILDREN_no,
12341247
[|
12351248
(DW_AT_name, DW_FORM_string);
1236-
(DW_AT_location, DW_FORM_block1);
1249+
(DW_AT_location, DW_FORM_block4);
12371250
(DW_AT_type, DW_FORM_ref_addr)
12381251
|])
12391252
;;
@@ -1243,7 +1256,7 @@ let (abbrev_formal:abbrev) =
12431256
(DW_TAG_formal_parameter, DW_CHILDREN_no,
12441257
[|
12451258
(DW_AT_name, DW_FORM_string);
1246-
(DW_AT_location, DW_FORM_block1);
1259+
(DW_AT_location, DW_FORM_block4);
12471260
(DW_AT_type, DW_FORM_ref_addr)
12481261
|])
12491262
;;
@@ -1572,7 +1585,7 @@ let dwarf_visitor
15721585
ref_addr_for_fix fix
15731586

15741587

1575-
and size_block4 (sz:size) (add_to_base:bool) : frag =
1588+
and size_block4 (sz:size) (push_fbreg:bool) (add_to_base:bool) : frag =
15761589
(* NB: typarams = "words following implicit args" by convention in
15771590
* ABI/x86.
15781591
*)
@@ -1656,7 +1669,12 @@ let dwarf_visitor
16561669
DW_OP_and; (* ... aligned *)
16571670
]
16581671
in
1659-
let ops = sz_ops sz in
1672+
let ops =
1673+
if push_fbreg
1674+
then [ DW_OP_reg abi.Abi.abi_dwarf_fp_reg ]
1675+
else []
1676+
in
1677+
let ops = ops @ (sz_ops sz) in
16601678
let ops =
16611679
if add_to_base
16621680
then ops @ [ DW_OP_plus ]
@@ -1685,7 +1703,7 @@ let dwarf_visitor
16851703
let die = DEF (fix, SEQ [|
16861704
uleb (get_abbrev_code abbrev_struct_type);
16871705
(* DW_AT_byte_size: DW_FORM_block4 *)
1688-
size_block4 (rty_sz rty) false
1706+
size_block4 (rty_sz rty) false false
16891707
|]);
16901708
in
16911709
let rtys =
@@ -1706,9 +1724,9 @@ let dwarf_visitor
17061724
(* DW_AT_data_member_location: DW_FORM_block4 *)
17071725
size_block4
17081726
(Il.get_element_offset word_bits rtys i)
1709-
true;
1727+
false true;
17101728
(* DW_AT_byte_size: DW_FORM_block4 *)
1711-
size_block4 (rty_sz rtys.(i)) false |]);
1729+
size_block4 (rty_sz rtys.(i)) false false |]);
17121730
end
17131731
trec;
17141732
emit_null_die ()
@@ -1908,6 +1926,7 @@ let dwarf_visitor
19081926
*)
19091927

19101928
let n_variants = get_n_tag_tups cx ttag in
1929+
let n_args = Array.length ttag.Ast.tag_args in
19111930
let tinfo = Hashtbl.find cx.ctxt_all_tag_info ttag.Ast.tag_id in
19121931
let rty = referent_type cx (Ast.TY_tag ttag) in
19131932
let rty_sz = Il.referent_ty_size abi.Abi.abi_word_bits in
@@ -1921,7 +1940,7 @@ let dwarf_visitor
19211940
DEF (fix, SEQ [|
19221941
uleb (get_abbrev_code abbrev_struct_type);
19231942
(* DW_AT_byte_size: DW_FORM_block4 *)
1924-
size_block4 (rty_sz rty) false
1943+
size_block4 (rty_sz rty) false false
19251944
|])
19261945
in
19271946

@@ -1936,9 +1955,9 @@ let dwarf_visitor
19361955
(* DW_AT_data_member_location: DW_FORM_block4 *)
19371956
size_block4
19381957
(Il.get_element_offset word_bits rtys 0)
1939-
true;
1958+
false true;
19401959
(* DW_AT_byte_size: DW_FORM_block4 *)
1941-
size_block4 (rty_sz rtys.(0)) false |]);
1960+
size_block4 (rty_sz rtys.(0)) false false |]);
19421961
in
19431962

19441963
let variant_part_die =
@@ -1952,6 +1971,7 @@ let dwarf_visitor
19521971
|]
19531972
in
19541973

1974+
19551975
let emit_variant i =
19561976
let (name, _, _) = Hashtbl.find tinfo.tag_nums i in
19571977
let ttup = get_nth_tag_tup cx ttag i in
@@ -1963,9 +1983,19 @@ let dwarf_visitor
19631983
(* DW_AT_name: DW_FORM_string *)
19641984
ZSTRING name
19651985
|]);
1966-
ignore (tup ttup);
1986+
ignore (ref_type_die (Ast.TY_tup ttup));
19671987
emit_null_die ();
19681988
in
1989+
1990+
let emit_arg i =
1991+
let arg = ttag.Ast.tag_args.(i) in
1992+
emit_die (SEQ [|
1993+
uleb (get_abbrev_code abbrev_formal_type);
1994+
(* DW_AT_type: DW_FORM_ref_addr *)
1995+
(ref_type_die arg)
1996+
|]);
1997+
in
1998+
19691999
emit_die outer_structure_die;
19702000
emit_die discr_die;
19712001
emit_die variant_part_die;
@@ -1974,6 +2004,10 @@ let dwarf_visitor
19742004
emit_variant i
19752005
done;
19762006
emit_null_die (); (* end variant-part *)
2007+
for i = 0 to n_args - 1
2008+
do
2009+
emit_arg i
2010+
done;
19772011
emit_null_die (); (* end outer struct *)
19782012
in
19792013

@@ -2024,9 +2058,7 @@ let dwarf_visitor
20242058
| Ast.TY_str -> string_type ()
20252059
| Ast.TY_rec trec -> record trec
20262060
| Ast.TY_tup ttup -> tup ttup
2027-
| Ast.TY_tag ttag ->
2028-
let _ = fun _ -> tag_type ttag in
2029-
unspecified_struct DW_RUST_nil
2061+
| Ast.TY_tag ttag -> tag_type ttag
20302062
| Ast.TY_vec t -> unspecified_ptr_with_ref_ty DW_RUST_vec t
20312063
| Ast.TY_chan t -> unspecified_ptr_with_ref_ty DW_RUST_chan t
20322064
| Ast.TY_port t -> unspecified_ptr_with_ref_ty DW_RUST_port t
@@ -2276,6 +2308,41 @@ let dwarf_visitor
22762308
emit_die subprogram_die
22772309
in
22782310

2311+
let emit_tag_constructor_die
2312+
(id:Ast.ident)
2313+
(tid:opaque_id)
2314+
(n_slots:int)
2315+
(tag_num:int)
2316+
(fix:fixup)
2317+
: unit =
2318+
(* NB: retpc = "top word of frame-base" by convention in ABI/x86. *)
2319+
let abi = cx.ctxt_abi in
2320+
let retpc = Int64.sub abi.Abi.abi_frame_base_sz abi.Abi.abi_word_sz in
2321+
let abbrev_code = get_abbrev_code abbrev_tag_constructor_subprogram in
2322+
let subprogram_die =
2323+
(SEQ [|
2324+
uleb abbrev_code;
2325+
(* DW_AT_name *)
2326+
ZSTRING id;
2327+
(* DW_AT_tag_type_id *)
2328+
WORD (word_ty_mach, IMM (Int64.of_int (int_of_opaque tid)));
2329+
(* DW_AT_discr_value *)
2330+
WORD (word_ty_mach, IMM (Int64.of_int tag_num));
2331+
if n_slots = 0
2332+
then
2333+
SEQ [| WORD (word_ty_mach, IMM 0L);
2334+
WORD (word_ty_mach, IMM 0L); |]
2335+
else
2336+
addr_ranges fix;
2337+
(* DW_AT_frame_base *)
2338+
dw_form_block1 [| DW_OP_reg abi.Abi.abi_dwarf_fp_reg |];
2339+
(* DW_AT_return_addr *)
2340+
dw_form_block1 [| DW_OP_fbreg (Asm.IMM retpc); |];
2341+
|])
2342+
in
2343+
emit_die subprogram_die
2344+
in
2345+
22792346
let emit_typedef_die
22802347
(id:Ast.ident)
22812348
(e:Ast.effect)
@@ -2331,6 +2398,7 @@ let dwarf_visitor
23312398
emit_module_die id;
23322399
emit_type_param_decl_dies item.node.Ast.decl_params;
23332400
end
2401+
23342402
| Ast.MOD_ITEM_fn _ ->
23352403
begin
23362404
let ty = Hashtbl.find cx.ctxt_all_item_types item.id in
@@ -2350,6 +2418,7 @@ let dwarf_visitor
23502418
(Hashtbl.find cx.ctxt_fn_fixups item.id);
23512419
emit_type_param_decl_dies item.node.Ast.decl_params;
23522420
end
2421+
23532422
| Ast.MOD_ITEM_type (e, _) ->
23542423
begin
23552424
log cx "walking typedef '%s' with %d type params"
@@ -2359,6 +2428,15 @@ let dwarf_visitor
23592428
id e (Hashtbl.find cx.ctxt_all_type_items item.id);
23602429
emit_type_param_decl_dies item.node.Ast.decl_params;
23612430
end
2431+
2432+
| Ast.MOD_ITEM_tag (hslots, tid, n) ->
2433+
log cx "walking tag constructor '%s' with %d type params"
2434+
(path_name())
2435+
(Array.length item.node.Ast.decl_params);
2436+
emit_tag_constructor_die id tid (Array.length hslots) n
2437+
(Hashtbl.find cx.ctxt_fn_fixups item.id);
2438+
emit_type_param_decl_dies item.node.Ast.decl_params;
2439+
23622440
| _ -> ()
23632441
end;
23642442
inner.Walk.visit_mod_item_pre id params item
@@ -2386,6 +2464,7 @@ let dwarf_visitor
23862464
match item.node.Ast.decl_item with
23872465
Ast.MOD_ITEM_mod _
23882466
| Ast.MOD_ITEM_fn _
2467+
| Ast.MOD_ITEM_tag _
23892468
| Ast.MOD_ITEM_type _ -> emit_null_die ()
23902469
| _ -> ()
23912470
end;
@@ -2432,8 +2511,8 @@ let dwarf_visitor
24322511
uleb abbrev_code;
24332512
(* DW_AT_name: DW_FORM_string *)
24342513
ZSTRING ident;
2435-
(* DW_AT_location: DW_FORM_block1 *)
2436-
dw_form_block1 slot_loc;
2514+
(* DW_AT_location: DW_FORM_block4 *)
2515+
slot_loc;
24372516
(* DW_AT_type: DW_FORM_ref_addr *)
24382517
ref_slot_die resolved_slot
24392518
|]
@@ -2442,16 +2521,8 @@ let dwarf_visitor
24422521
in
24432522
match htab_search cx.ctxt_slot_offsets s.id with
24442523
Some off ->
2445-
begin
2446-
match Il.size_to_expr64 off with
2447-
(* FIXME (issue #73): handle dynamic-size
2448-
* slots.
2449-
*)
2450-
None -> ()
2451-
| Some off ->
2452-
emit_var_die
2453-
[| DW_OP_fbreg off |]
2454-
end
2524+
emit_var_die (size_block4 off true true)
2525+
24552526
| None ->
24562527
(* FIXME (issue #28): handle slots assigned to
24572528
* vregs.
@@ -2791,6 +2862,10 @@ let rec extract_mod_items
27912862
atab_find die.die_attrs attr
27922863
in
27932864

2865+
let has_attr die attr =
2866+
atab_mem die.die_attrs attr
2867+
in
2868+
27942869
let get_str die attr =
27952870
match get_attr die attr with
27962871
(_, DATA_str s) -> s
@@ -2831,6 +2906,10 @@ let rec extract_mod_items
28312906
get_num die DW_AT_rust_native_type_id
28322907
in
28332908

2909+
let get_tag_id die =
2910+
get_num die DW_AT_rust_tag_type_id
2911+
in
2912+
28342913
let get_type_param_decl die =
28352914
((get_str die DW_AT_name), (get_type_param die))
28362915
in
@@ -2843,9 +2922,9 @@ let rec extract_mod_items
28432922

28442923
let rec get_ty die : Ast.ty =
28452924

2846-
let is_tagged_variant =
2847-
Array.length die.die_children == 2 &&
2848-
die.die_children.(1).die_tag = DW_TAG_variant
2925+
let is_tagged_variant die =
2926+
Array.length die.die_children >= 2 &&
2927+
die.die_children.(1).die_tag = DW_TAG_variant_part
28492928
in
28502929

28512930
match die.die_tag with
@@ -2913,13 +2992,19 @@ let rec extract_mod_items
29132992
| _ -> bug () "unexpected type of DW_TAG_base_type"
29142993
end
29152994

2916-
| DW_TAG_structure_type when is_tagged_variant ->
2995+
| DW_TAG_structure_type when is_tagged_variant die ->
29172996
Ast.TY_tag
2918-
{ Ast.tag_id = Opaque (get_num
2919-
(die.die_children.(1))
2920-
DW_AT_rust_tag_type_id);
2921-
(* FIXME: encode and decode tag args. *)
2922-
Ast.tag_args = [| |] }
2997+
{ Ast.tag_id = get_opaque_of (get_tag_id die.die_children.(1));
2998+
Ast.tag_args =
2999+
let n_children = Array.length die.die_children in
3000+
if n_children > 2
3001+
then
3002+
Array.map
3003+
get_referenced_ty
3004+
(Array.sub die.die_children 2 (n_children - 2))
3005+
else
3006+
[| |]
3007+
}
29233008

29243009
| DW_TAG_structure_type ->
29253010
begin
@@ -3100,6 +3185,16 @@ let rec extract_mod_items
31003185
let mi = Ast.MOD_ITEM_mod (view, sub_mis) in
31013186
htab_put mis ident (decl [||] mi)
31023187

3188+
| DW_TAG_subprogram
3189+
when has_attr die DW_AT_rust_tag_type_id ->
3190+
let ident = get_name die in
3191+
let tid = get_opaque_of (get_tag_id die) in
3192+
let n = get_num die DW_AT_discr_value in
3193+
let (params, islots) = get_formals die in
3194+
let hslots = form_header_slots islots in
3195+
let ctor = Ast.MOD_ITEM_tag (hslots, tid, n) in
3196+
htab_put mis ident (decl params ctor)
3197+
31033198
| DW_TAG_subprogram ->
31043199
(* FIXME (issue #74): finish this. *)
31053200
let ident = get_name die in

src/boot/me/resolve.ml

+6-2
Original file line numberDiff line numberDiff line change
@@ -445,8 +445,12 @@ let type_resolving_visitor
445445
(fun (s,_) -> (slot_ty (resolve_slot_identified s).node))
446446
slots
447447
in
448-
htab_put tinfo.tag_idents id (n, item.id, ttup);
449-
htab_put tinfo.tag_nums n (id, item.id, ttup);
448+
if not (Hashtbl.mem tinfo.tag_idents id)
449+
then
450+
begin
451+
htab_put tinfo.tag_idents id (n, item.id, ttup);
452+
htab_put tinfo.tag_nums n (id, item.id, ttup);
453+
end
450454

451455
| _ -> resolve_and_store_type ()
452456
with

0 commit comments

Comments
 (0)