@@ -1211,6 +1211,19 @@ let (abbrev_subprogram:abbrev) =
1211
1211
|])
1212
1212
;;
1213
1213
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
+
1214
1227
let (abbrev_typedef:abbrev ) =
1215
1228
(DW_TAG_typedef , DW_CHILDREN_yes ,
1216
1229
[|
@@ -1233,7 +1246,7 @@ let (abbrev_variable:abbrev) =
1233
1246
(DW_TAG_variable , DW_CHILDREN_no ,
1234
1247
[|
1235
1248
(DW_AT_name , DW_FORM_string );
1236
- (DW_AT_location , DW_FORM_block1 );
1249
+ (DW_AT_location , DW_FORM_block4 );
1237
1250
(DW_AT_type , DW_FORM_ref_addr )
1238
1251
|])
1239
1252
;;
@@ -1243,7 +1256,7 @@ let (abbrev_formal:abbrev) =
1243
1256
(DW_TAG_formal_parameter , DW_CHILDREN_no ,
1244
1257
[|
1245
1258
(DW_AT_name , DW_FORM_string );
1246
- (DW_AT_location , DW_FORM_block1 );
1259
+ (DW_AT_location , DW_FORM_block4 );
1247
1260
(DW_AT_type , DW_FORM_ref_addr )
1248
1261
|])
1249
1262
;;
@@ -1572,7 +1585,7 @@ let dwarf_visitor
1572
1585
ref_addr_for_fix fix
1573
1586
1574
1587
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 =
1576
1589
(* NB: typarams = "words following implicit args" by convention in
1577
1590
* ABI/x86.
1578
1591
*)
@@ -1656,7 +1669,12 @@ let dwarf_visitor
1656
1669
DW_OP_and ; (* ... aligned *)
1657
1670
]
1658
1671
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
1660
1678
let ops =
1661
1679
if add_to_base
1662
1680
then ops @ [ DW_OP_plus ]
@@ -1685,7 +1703,7 @@ let dwarf_visitor
1685
1703
let die = DEF (fix, SEQ [|
1686
1704
uleb (get_abbrev_code abbrev_struct_type);
1687
1705
(* DW_AT_byte_size: DW_FORM_block4 *)
1688
- size_block4 (rty_sz rty) false
1706
+ size_block4 (rty_sz rty) false false
1689
1707
|]);
1690
1708
in
1691
1709
let rtys =
@@ -1706,9 +1724,9 @@ let dwarf_visitor
1706
1724
(* DW_AT_data_member_location: DW_FORM_block4 *)
1707
1725
size_block4
1708
1726
(Il. get_element_offset word_bits rtys i)
1709
- true ;
1727
+ false true ;
1710
1728
(* DW_AT_byte_size: DW_FORM_block4 *)
1711
- size_block4 (rty_sz rtys.(i)) false |]);
1729
+ size_block4 (rty_sz rtys.(i)) false false |]);
1712
1730
end
1713
1731
trec;
1714
1732
emit_null_die ()
@@ -1908,6 +1926,7 @@ let dwarf_visitor
1908
1926
*)
1909
1927
1910
1928
let n_variants = get_n_tag_tups cx ttag in
1929
+ let n_args = Array. length ttag.Ast. tag_args in
1911
1930
let tinfo = Hashtbl. find cx.ctxt_all_tag_info ttag.Ast. tag_id in
1912
1931
let rty = referent_type cx (Ast. TY_tag ttag) in
1913
1932
let rty_sz = Il. referent_ty_size abi.Abi. abi_word_bits in
@@ -1921,7 +1940,7 @@ let dwarf_visitor
1921
1940
DEF (fix, SEQ [|
1922
1941
uleb (get_abbrev_code abbrev_struct_type);
1923
1942
(* DW_AT_byte_size: DW_FORM_block4 *)
1924
- size_block4 (rty_sz rty) false
1943
+ size_block4 (rty_sz rty) false false
1925
1944
|])
1926
1945
in
1927
1946
@@ -1936,9 +1955,9 @@ let dwarf_visitor
1936
1955
(* DW_AT_data_member_location: DW_FORM_block4 *)
1937
1956
size_block4
1938
1957
(Il. get_element_offset word_bits rtys 0 )
1939
- true ;
1958
+ false true ;
1940
1959
(* DW_AT_byte_size: DW_FORM_block4 *)
1941
- size_block4 (rty_sz rtys.(0 )) false |]);
1960
+ size_block4 (rty_sz rtys.(0 )) false false |]);
1942
1961
in
1943
1962
1944
1963
let variant_part_die =
@@ -1952,6 +1971,7 @@ let dwarf_visitor
1952
1971
|]
1953
1972
in
1954
1973
1974
+
1955
1975
let emit_variant i =
1956
1976
let (name, _, _) = Hashtbl. find tinfo.tag_nums i in
1957
1977
let ttup = get_nth_tag_tup cx ttag i in
@@ -1963,9 +1983,19 @@ let dwarf_visitor
1963
1983
(* DW_AT_name: DW_FORM_string *)
1964
1984
ZSTRING name
1965
1985
|]);
1966
- ignore (tup ttup);
1986
+ ignore (ref_type_die ( Ast. TY_tup ttup) );
1967
1987
emit_null_die () ;
1968
1988
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
+
1969
1999
emit_die outer_structure_die;
1970
2000
emit_die discr_die;
1971
2001
emit_die variant_part_die;
@@ -1974,6 +2004,10 @@ let dwarf_visitor
1974
2004
emit_variant i
1975
2005
done ;
1976
2006
emit_null_die () ; (* end variant-part *)
2007
+ for i = 0 to n_args - 1
2008
+ do
2009
+ emit_arg i
2010
+ done ;
1977
2011
emit_null_die () ; (* end outer struct *)
1978
2012
in
1979
2013
@@ -2024,9 +2058,7 @@ let dwarf_visitor
2024
2058
| Ast. TY_str -> string_type ()
2025
2059
| Ast. TY_rec trec -> record trec
2026
2060
| 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
2030
2062
| Ast. TY_vec t -> unspecified_ptr_with_ref_ty DW_RUST_vec t
2031
2063
| Ast. TY_chan t -> unspecified_ptr_with_ref_ty DW_RUST_chan t
2032
2064
| Ast. TY_port t -> unspecified_ptr_with_ref_ty DW_RUST_port t
@@ -2276,6 +2308,41 @@ let dwarf_visitor
2276
2308
emit_die subprogram_die
2277
2309
in
2278
2310
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
+
2279
2346
let emit_typedef_die
2280
2347
(id :Ast.ident )
2281
2348
(e :Ast.effect )
@@ -2331,6 +2398,7 @@ let dwarf_visitor
2331
2398
emit_module_die id;
2332
2399
emit_type_param_decl_dies item.node.Ast. decl_params;
2333
2400
end
2401
+
2334
2402
| Ast. MOD_ITEM_fn _ ->
2335
2403
begin
2336
2404
let ty = Hashtbl. find cx.ctxt_all_item_types item.id in
@@ -2350,6 +2418,7 @@ let dwarf_visitor
2350
2418
(Hashtbl. find cx.ctxt_fn_fixups item.id);
2351
2419
emit_type_param_decl_dies item.node.Ast. decl_params;
2352
2420
end
2421
+
2353
2422
| Ast. MOD_ITEM_type (e , _ ) ->
2354
2423
begin
2355
2424
log cx " walking typedef '%s' with %d type params"
@@ -2359,6 +2428,15 @@ let dwarf_visitor
2359
2428
id e (Hashtbl. find cx.ctxt_all_type_items item.id);
2360
2429
emit_type_param_decl_dies item.node.Ast. decl_params;
2361
2430
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
+
2362
2440
| _ -> ()
2363
2441
end ;
2364
2442
inner.Walk. visit_mod_item_pre id params item
@@ -2386,6 +2464,7 @@ let dwarf_visitor
2386
2464
match item.node.Ast. decl_item with
2387
2465
Ast. MOD_ITEM_mod _
2388
2466
| Ast. MOD_ITEM_fn _
2467
+ | Ast. MOD_ITEM_tag _
2389
2468
| Ast. MOD_ITEM_type _ -> emit_null_die ()
2390
2469
| _ -> ()
2391
2470
end ;
@@ -2432,8 +2511,8 @@ let dwarf_visitor
2432
2511
uleb abbrev_code;
2433
2512
(* DW_AT_name: DW_FORM_string *)
2434
2513
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;
2437
2516
(* DW_AT_type: DW_FORM_ref_addr *)
2438
2517
ref_slot_die resolved_slot
2439
2518
|]
@@ -2442,16 +2521,8 @@ let dwarf_visitor
2442
2521
in
2443
2522
match htab_search cx.ctxt_slot_offsets s.id with
2444
2523
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
+
2455
2526
| None ->
2456
2527
(* FIXME (issue #28): handle slots assigned to
2457
2528
* vregs.
@@ -2791,6 +2862,10 @@ let rec extract_mod_items
2791
2862
atab_find die.die_attrs attr
2792
2863
in
2793
2864
2865
+ let has_attr die attr =
2866
+ atab_mem die.die_attrs attr
2867
+ in
2868
+
2794
2869
let get_str die attr =
2795
2870
match get_attr die attr with
2796
2871
(_ , DATA_str s ) -> s
@@ -2831,6 +2906,10 @@ let rec extract_mod_items
2831
2906
get_num die DW_AT_rust_native_type_id
2832
2907
in
2833
2908
2909
+ let get_tag_id die =
2910
+ get_num die DW_AT_rust_tag_type_id
2911
+ in
2912
+
2834
2913
let get_type_param_decl die =
2835
2914
((get_str die DW_AT_name ), (get_type_param die))
2836
2915
in
@@ -2843,9 +2922,9 @@ let rec extract_mod_items
2843
2922
2844
2923
let rec get_ty die : Ast.ty =
2845
2924
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
2849
2928
in
2850
2929
2851
2930
match die.die_tag with
@@ -2913,13 +2992,19 @@ let rec extract_mod_items
2913
2992
| _ -> bug () " unexpected type of DW_TAG_base_type"
2914
2993
end
2915
2994
2916
- | DW_TAG_structure_type when is_tagged_variant ->
2995
+ | DW_TAG_structure_type when is_tagged_variant die ->
2917
2996
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
+ }
2923
3008
2924
3009
| DW_TAG_structure_type ->
2925
3010
begin
@@ -3100,6 +3185,16 @@ let rec extract_mod_items
3100
3185
let mi = Ast. MOD_ITEM_mod (view, sub_mis) in
3101
3186
htab_put mis ident (decl [||] mi)
3102
3187
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
+
3103
3198
| DW_TAG_subprogram ->
3104
3199
(* FIXME (issue #74): finish this. *)
3105
3200
let ident = get_name die in
0 commit comments