2020-09-23 15:13:49 +02:00
//! Handling of everything related to debuginfo.
2019-11-12 20:52:32 +01:00
mod emit ;
2019-11-12 21:08:08 +01:00
mod line_info ;
2021-09-19 13:56:58 +02:00
mod object ;
2020-04-25 18:23:31 +02:00
mod unwind ;
2019-01-17 18:07:27 +01:00
2019-11-12 20:52:32 +01:00
use crate ::prelude ::* ;
2019-10-16 21:21:20 +02:00
2020-09-16 18:45:19 +02:00
use rustc_index ::vec ::IndexVec ;
2020-06-27 11:58:44 +02:00
use cranelift_codegen ::entity ::EntityRef ;
2021-12-30 14:53:41 +01:00
use cranelift_codegen ::ir ::{ Endianness , LabelValueLoc , ValueLabel } ;
2020-04-01 14:12:46 +02:00
use cranelift_codegen ::isa ::TargetIsa ;
2019-12-24 12:40:18 +01:00
use cranelift_codegen ::ValueLocRange ;
2019-11-11 21:43:57 +01:00
2019-01-17 18:07:27 +01:00
use gimli ::write ::{
2020-08-28 12:10:48 +02:00
Address , AttributeValue , DwarfUnit , Expression , LineProgram , LineString , Location ,
LocationList , Range , RangeList , UnitEntryId ,
2019-01-17 18:07:27 +01:00
} ;
2020-04-01 14:12:46 +02:00
use gimli ::{ Encoding , Format , LineEncoding , RunTimeEndian , X86_64 } ;
2019-11-12 20:52:32 +01:00
2020-03-27 12:14:45 +01:00
pub ( crate ) use emit ::{ DebugReloc , DebugRelocName } ;
2020-05-01 19:21:29 +02:00
pub ( crate ) use unwind ::UnwindContext ;
2019-01-17 18:07:27 +01:00
2020-03-27 12:14:45 +01:00
pub ( crate ) struct DebugContext < ' tcx > {
2019-11-09 18:40:11 +01:00
tcx : TyCtxt < ' tcx > ,
2019-01-17 18:07:27 +01:00
endian : RunTimeEndian ,
2019-01-19 12:18:39 +01:00
2019-02-09 17:15:15 +10:00
dwarf : DwarfUnit ,
2019-01-19 12:00:51 +01:00
unit_range_list : RangeList ,
2019-01-17 18:07:27 +01:00
2020-04-05 14:01:02 +02:00
types : FxHashMap < Ty < ' tcx > , UnitEntryId > ,
2019-01-17 18:07:27 +01:00
}
2019-06-16 11:13:49 +02:00
impl < ' tcx > DebugContext < ' tcx > {
2020-04-25 18:23:31 +02:00
pub ( crate ) fn new ( tcx : TyCtxt < ' tcx > , isa : & dyn TargetIsa ) -> Self {
2019-01-26 12:37:49 +01:00
let encoding = Encoding {
format : Format ::Dwarf32 ,
2021-08-06 16:26:56 +02:00
// FIXME this should be configurable
2019-01-26 12:37:49 +01:00
// macOS doesn't seem to support DWARF > 3
2020-04-18 14:56:04 +03:00
// 5 version is required for md5 file hash
2020-11-08 14:27:51 +03:00
version : if tcx . sess . target . is_like_osx {
2020-04-18 16:05:20 +03:00
3
} else {
2020-04-21 12:13:50 +02:00
// FIXME change to version 5 once the gdb and lldb shipping with the latest debian
// support it.
4
2020-04-18 16:05:20 +03:00
} ,
2020-04-25 18:23:31 +02:00
address_size : isa . frontend_config ( ) . pointer_bytes ( ) ,
2019-01-26 12:37:49 +01:00
} ;
2019-01-17 18:07:27 +01:00
2021-12-30 14:53:41 +01:00
let endian = match isa . endianness ( ) {
Endianness ::Little = > RunTimeEndian ::Little ,
Endianness ::Big = > RunTimeEndian ::Big ,
} ;
2019-02-09 17:15:15 +10:00
let mut dwarf = DwarfUnit ::new ( encoding ) ;
2021-07-07 11:14:20 +02:00
let producer = format! (
" cg_clif (rustc {}, cranelift {}) " ,
rustc_interface ::util ::version_str ( ) . unwrap_or ( " unknown version " ) ,
cranelift_codegen ::VERSION ,
) ;
2021-12-20 18:56:35 +01:00
let comp_dir = tcx
. sess
. opts
. working_dir
. to_string_lossy ( FileNameDisplayPreference ::Remapped )
. into_owned ( ) ;
2020-04-18 17:43:00 +03:00
let ( name , file_info ) = match tcx . sess . local_crate_source_file . clone ( ) {
2020-04-18 14:56:04 +03:00
Some ( path ) = > {
let name = path . to_string_lossy ( ) . into_owned ( ) ;
2020-06-04 19:57:12 +02:00
( name , None )
2020-08-28 12:10:48 +02:00
}
2020-04-18 14:56:04 +03:00
None = > ( tcx . crate_name ( LOCAL_CRATE ) . to_string ( ) , None ) ,
2019-01-17 18:07:27 +01:00
} ;
2020-04-18 14:56:04 +03:00
let mut line_program = LineProgram ::new (
2019-01-26 12:37:49 +01:00
encoding ,
2019-02-18 18:32:40 +01:00
LineEncoding ::default ( ) ,
2019-02-09 17:15:15 +10:00
LineString ::new ( comp_dir . as_bytes ( ) , encoding , & mut dwarf . line_strings ) ,
LineString ::new ( name . as_bytes ( ) , encoding , & mut dwarf . line_strings ) ,
2020-04-18 17:43:00 +03:00
file_info ,
2019-02-09 17:15:15 +10:00
) ;
2020-04-18 17:43:00 +03:00
line_program . file_has_md5 = file_info . is_some ( ) ;
2020-04-18 14:56:04 +03:00
2019-02-09 17:15:15 +10:00
dwarf . unit . line_program = line_program ;
2019-01-17 18:07:27 +01:00
{
2020-03-07 11:27:49 +01:00
let name = dwarf . strings . add ( name ) ;
let comp_dir = dwarf . strings . add ( comp_dir ) ;
2019-01-17 18:07:27 +01:00
2019-02-09 17:15:15 +10:00
let root = dwarf . unit . root ( ) ;
let root = dwarf . unit . get_mut ( root ) ;
2021-03-05 19:12:59 +01:00
root . set ( gimli ::DW_AT_producer , AttributeValue ::StringRef ( dwarf . strings . add ( producer ) ) ) ;
root . set ( gimli ::DW_AT_language , AttributeValue ::Language ( gimli ::DW_LANG_Rust ) ) ;
2019-01-17 18:07:27 +01:00
root . set ( gimli ::DW_AT_name , AttributeValue ::StringRef ( name ) ) ;
root . set ( gimli ::DW_AT_comp_dir , AttributeValue ::StringRef ( comp_dir ) ) ;
2021-03-05 19:12:59 +01:00
root . set ( gimli ::DW_AT_low_pc , AttributeValue ::Address ( Address ::Constant ( 0 ) ) ) ;
2019-01-17 18:07:27 +01:00
}
2019-02-21 15:06:09 +01:00
DebugContext {
2019-11-09 18:40:11 +01:00
tcx ,
2021-12-30 14:53:41 +01:00
endian ,
2019-01-19 12:18:39 +01:00
2019-02-09 17:15:15 +10:00
dwarf ,
2019-01-19 12:00:51 +01:00
unit_range_list : RangeList ( Vec ::new ( ) ) ,
2019-01-19 12:18:39 +01:00
2020-04-05 14:01:02 +02:00
types : FxHashMap ::default ( ) ,
2019-01-17 18:07:27 +01:00
}
}
2019-11-09 18:40:11 +01:00
fn dwarf_ty ( & mut self , ty : Ty < ' tcx > ) -> UnitEntryId {
Overhaul `TyS` and `Ty`.
Specifically, change `Ty` from this:
```
pub type Ty<'tcx> = &'tcx TyS<'tcx>;
```
to this
```
pub struct Ty<'tcx>(Interned<'tcx, TyS<'tcx>>);
```
There are two benefits to this.
- It's now a first class type, so we can define methods on it. This
means we can move a lot of methods away from `TyS`, leaving `TyS` as a
barely-used type, which is appropriate given that it's not meant to
be used directly.
- The uniqueness requirement is now explicit, via the `Interned` type.
E.g. the pointer-based `Eq` and `Hash` comes from `Interned`, rather
than via `TyS`, which wasn't obvious at all.
Much of this commit is boring churn. The interesting changes are in
these files:
- compiler/rustc_middle/src/arena.rs
- compiler/rustc_middle/src/mir/visit.rs
- compiler/rustc_middle/src/ty/context.rs
- compiler/rustc_middle/src/ty/mod.rs
Specifically:
- Most mentions of `TyS` are removed. It's very much a dumb struct now;
`Ty` has all the smarts.
- `TyS` now has `crate` visibility instead of `pub`.
- `TyS::make_for_test` is removed in favour of the static `BOOL_TY`,
which just works better with the new structure.
- The `Eq`/`Ord`/`Hash` impls are removed from `TyS`. `Interned`s impls
of `Eq`/`Hash` now suffice. `Ord` is now partly on `Interned`
(pointer-based, for the `Equal` case) and partly on `TyS`
(contents-based, for the other cases).
- There are many tedious sigil adjustments, i.e. adding or removing `*`
or `&`. They seem to be unavoidable.
2022-01-25 14:13:38 +11:00
if let Some ( type_id ) = self . types . get ( & ty ) {
2019-11-09 18:40:11 +01:00
return * type_id ;
}
2019-11-12 21:13:15 +01:00
let new_entry = | dwarf : & mut DwarfUnit , tag | dwarf . unit . add ( dwarf . unit . root ( ) , tag ) ;
2019-11-09 18:40:11 +01:00
2019-11-15 21:32:52 +01:00
let primitive = | dwarf : & mut DwarfUnit , ate | {
2019-11-09 18:40:11 +01:00
let type_id = new_entry ( dwarf , gimli ::DW_TAG_base_type ) ;
let type_entry = dwarf . unit . get_mut ( type_id ) ;
type_entry . set ( gimli ::DW_AT_encoding , AttributeValue ::Encoding ( ate ) ) ;
type_id
} ;
2019-11-15 21:32:52 +01:00
let name = format! ( " {} " , ty ) ;
let layout = self . tcx . layout_of ( ParamEnv ::reveal_all ( ) . and ( ty ) ) . unwrap ( ) ;
2020-09-05 10:38:49 +02:00
let type_id = match ty . kind ( ) {
2019-11-15 21:32:52 +01:00
ty ::Bool = > primitive ( & mut self . dwarf , gimli ::DW_ATE_boolean ) ,
ty ::Char = > primitive ( & mut self . dwarf , gimli ::DW_ATE_UTF ) ,
ty ::Uint ( _ ) = > primitive ( & mut self . dwarf , gimli ::DW_ATE_unsigned ) ,
ty ::Int ( _ ) = > primitive ( & mut self . dwarf , gimli ::DW_ATE_signed ) ,
ty ::Float ( _ ) = > primitive ( & mut self . dwarf , gimli ::DW_ATE_float ) ,
2020-02-22 15:17:30 +01:00
ty ::Ref ( _ , pointee_ty , _mutbl )
2021-03-05 19:12:59 +01:00
| ty ::RawPtr ( ty ::TypeAndMut { ty : pointee_ty , mutbl : _mutbl } ) = > {
2019-11-09 18:40:11 +01:00
let type_id = new_entry ( & mut self . dwarf , gimli ::DW_TAG_pointer_type ) ;
// Ensure that type is inserted before recursing to avoid duplicates
self . types . insert ( ty , type_id ) ;
Overhaul `TyS` and `Ty`.
Specifically, change `Ty` from this:
```
pub type Ty<'tcx> = &'tcx TyS<'tcx>;
```
to this
```
pub struct Ty<'tcx>(Interned<'tcx, TyS<'tcx>>);
```
There are two benefits to this.
- It's now a first class type, so we can define methods on it. This
means we can move a lot of methods away from `TyS`, leaving `TyS` as a
barely-used type, which is appropriate given that it's not meant to
be used directly.
- The uniqueness requirement is now explicit, via the `Interned` type.
E.g. the pointer-based `Eq` and `Hash` comes from `Interned`, rather
than via `TyS`, which wasn't obvious at all.
Much of this commit is boring churn. The interesting changes are in
these files:
- compiler/rustc_middle/src/arena.rs
- compiler/rustc_middle/src/mir/visit.rs
- compiler/rustc_middle/src/ty/context.rs
- compiler/rustc_middle/src/ty/mod.rs
Specifically:
- Most mentions of `TyS` are removed. It's very much a dumb struct now;
`Ty` has all the smarts.
- `TyS` now has `crate` visibility instead of `pub`.
- `TyS::make_for_test` is removed in favour of the static `BOOL_TY`,
which just works better with the new structure.
- The `Eq`/`Ord`/`Hash` impls are removed from `TyS`. `Interned`s impls
of `Eq`/`Hash` now suffice. `Ord` is now partly on `Interned`
(pointer-based, for the `Equal` case) and partly on `TyS`
(contents-based, for the other cases).
- There are many tedious sigil adjustments, i.e. adding or removing `*`
or `&`. They seem to be unavoidable.
2022-01-25 14:13:38 +11:00
let pointee = self . dwarf_ty ( * pointee_ty ) ;
2019-11-09 18:40:11 +01:00
let type_entry = self . dwarf . unit . get_mut ( type_id ) ;
2020-01-09 17:43:10 +01:00
//type_entry.set(gimli::DW_AT_mutable, AttributeValue::Flag(mutbl == rustc_hir::Mutability::Mut));
2020-06-05 12:40:33 +02:00
type_entry . set ( gimli ::DW_AT_type , AttributeValue ::UnitRef ( pointee ) ) ;
2019-11-09 18:40:11 +01:00
type_id
}
2019-11-15 21:32:52 +01:00
ty ::Adt ( adt_def , _substs ) if adt_def . is_struct ( ) & & ! layout . is_unsized ( ) = > {
let type_id = new_entry ( & mut self . dwarf , gimli ::DW_TAG_structure_type ) ;
// Ensure that type is inserted before recursing to avoid duplicates
self . types . insert ( ty , type_id ) ;
let variant = adt_def . non_enum_variant ( ) ;
for ( field_idx , field_def ) in variant . fields . iter ( ) . enumerate ( ) {
let field_offset = layout . fields . offset ( field_idx ) ;
2021-08-25 18:05:10 +03:00
let field_layout = layout . field (
& layout ::LayoutCx { tcx : self . tcx , param_env : ParamEnv ::reveal_all ( ) } ,
field_idx ,
) ;
2019-11-15 21:32:52 +01:00
let field_type = self . dwarf_ty ( field_layout . ty ) ;
let field_id = self . dwarf . unit . add ( type_id , gimli ::DW_TAG_member ) ;
let field_entry = self . dwarf . unit . get_mut ( field_id ) ;
2020-08-28 12:10:48 +02:00
field_entry . set (
gimli ::DW_AT_name ,
2022-01-02 22:37:05 -05:00
AttributeValue ::String ( field_def . name . as_str ( ) . to_string ( ) . into_bytes ( ) ) ,
2020-08-28 12:10:48 +02:00
) ;
field_entry . set (
gimli ::DW_AT_data_member_location ,
AttributeValue ::Udata ( field_offset . bytes ( ) ) ,
) ;
2020-06-05 12:40:33 +02:00
field_entry . set ( gimli ::DW_AT_type , AttributeValue ::UnitRef ( field_type ) ) ;
2019-11-15 21:32:52 +01:00
}
type_id
}
2019-11-09 18:40:11 +01:00
_ = > new_entry ( & mut self . dwarf , gimli ::DW_TAG_structure_type ) ,
} ;
let type_entry = self . dwarf . unit . get_mut ( type_id ) ;
type_entry . set ( gimli ::DW_AT_name , AttributeValue ::String ( name . into_bytes ( ) ) ) ;
2021-03-05 19:12:59 +01:00
type_entry . set ( gimli ::DW_AT_byte_size , AttributeValue ::Udata ( layout . size . bytes ( ) ) ) ;
2019-11-09 18:40:11 +01:00
self . types . insert ( ty , type_id ) ;
type_id
}
2019-01-17 18:07:27 +01:00
2020-06-13 17:03:34 +02:00
fn define_local ( & mut self , scope : UnitEntryId , name : String , ty : Ty < ' tcx > ) -> UnitEntryId {
let dw_ty = self . dwarf_ty ( ty ) ;
2020-08-28 12:10:48 +02:00
let var_id = self . dwarf . unit . add ( scope , gimli ::DW_TAG_variable ) ;
2020-06-13 17:03:34 +02:00
let var_entry = self . dwarf . unit . get_mut ( var_id ) ;
var_entry . set ( gimli ::DW_AT_name , AttributeValue ::String ( name . into_bytes ( ) ) ) ;
var_entry . set ( gimli ::DW_AT_type , AttributeValue ::UnitRef ( dw_ty ) ) ;
2019-01-17 18:07:27 +01:00
2020-06-13 17:03:34 +02:00
var_id
}
pub ( crate ) fn define_function (
& mut self ,
2019-11-11 20:49:20 +01:00
instance : Instance < ' tcx > ,
2019-10-16 21:21:20 +02:00
func_id : FuncId ,
2019-01-17 18:07:27 +01:00
name : & str ,
2020-06-13 17:03:34 +02:00
isa : & dyn TargetIsa ,
context : & Context ,
source_info_set : & indexmap ::IndexSet < SourceInfo > ,
2020-09-16 18:45:19 +02:00
local_map : IndexVec < mir ::Local , CPlace < ' tcx > > ,
2020-06-13 17:03:34 +02:00
) {
let symbol = func_id . as_u32 ( ) as usize ;
let mir = self . tcx . instance_mir ( instance . def ) ;
2019-11-11 20:49:20 +01:00
2020-06-13 17:03:34 +02:00
// FIXME: add to appropriate scope instead of root
let scope = self . dwarf . unit . root ( ) ;
2019-01-17 18:07:27 +01:00
2020-08-28 12:10:48 +02:00
let entry_id = self . dwarf . unit . add ( scope , gimli ::DW_TAG_subprogram ) ;
2020-06-13 17:03:34 +02:00
let entry = self . dwarf . unit . get_mut ( entry_id ) ;
let name_id = self . dwarf . strings . add ( name ) ;
2020-04-23 16:44:12 +02:00
// Gdb requires DW_AT_name. Otherwise the DW_TAG_subprogram is skipped.
2020-08-28 12:10:48 +02:00
entry . set ( gimli ::DW_AT_name , AttributeValue ::StringRef ( name_id ) ) ;
2021-03-05 19:12:59 +01:00
entry . set ( gimli ::DW_AT_linkage_name , AttributeValue ::StringRef ( name_id ) ) ;
2019-01-17 18:07:27 +01:00
2021-03-05 19:12:59 +01:00
let end = self . create_debug_lines ( symbol , entry_id , context , mir . span , source_info_set ) ;
2019-11-12 21:10:51 +01:00
2020-08-28 12:10:48 +02:00
self . unit_range_list . 0. push ( Range ::StartLength {
begin : Address ::Symbol { symbol , addend : 0 } ,
length : u64 ::from ( end ) ,
} ) ;
2019-01-19 16:16:30 +01:00
2020-06-13 17:03:34 +02:00
let func_entry = self . dwarf . unit . get_mut ( entry_id ) ;
2020-04-23 16:44:12 +02:00
// Gdb requires both DW_AT_low_pc and DW_AT_high_pc. Otherwise the DW_TAG_subprogram is skipped.
2020-08-28 12:10:48 +02:00
func_entry . set (
gimli ::DW_AT_low_pc ,
AttributeValue ::Address ( Address ::Symbol { symbol , addend : 0 } ) ,
) ;
2020-04-23 16:44:12 +02:00
// Using Udata for DW_AT_high_pc requires at least DWARF4
func_entry . set ( gimli ::DW_AT_high_pc , AttributeValue ::Udata ( u64 ::from ( end ) ) ) ;
2019-12-16 12:12:51 +01:00
// FIXME make it more reliable and implement scopes before re-enabling this.
if false {
2021-12-20 18:56:35 +01:00
let value_labels_ranges = std ::collections ::HashMap ::new ( ) ; // FIXME
2019-12-16 12:12:51 +01:00
2020-06-13 17:03:34 +02:00
for ( local , _local_decl ) in mir . local_decls . iter_enumerated ( ) {
let ty = self . tcx . subst_and_normalize_erasing_regions (
instance . substs ,
2020-04-22 14:48:56 +02:00
ty ::ParamEnv ::reveal_all ( ) ,
2020-10-28 08:25:06 +01:00
mir . local_decls [ local ] . ty ,
2020-04-22 14:48:56 +02:00
) ;
2020-06-13 17:03:34 +02:00
let var_id = self . define_local ( entry_id , format! ( " {:?} " , local ) , ty ) ;
2019-12-16 12:12:51 +01:00
let location = place_location (
self ,
2020-03-17 15:30:32 +01:00
isa ,
2020-06-13 17:03:34 +02:00
symbol ,
2019-12-16 12:12:51 +01:00
& local_map ,
& value_labels_ranges ,
2021-03-05 19:12:59 +01:00
Place { local , projection : ty ::List ::empty ( ) } ,
2019-12-16 12:12:51 +01:00
) ;
2020-06-13 17:03:34 +02:00
let var_entry = self . dwarf . unit . get_mut ( var_id ) ;
2019-12-16 12:12:51 +01:00
var_entry . set ( gimli ::DW_AT_location , location ) ;
}
2019-11-09 16:42:21 +01:00
}
2019-11-28 21:35:03 +01:00
// FIXME create locals for all entries in mir.var_debug_info
2019-01-17 18:07:27 +01:00
}
}
2020-06-13 17:03:34 +02:00
fn place_location < ' tcx > (
debug_context : & mut DebugContext < ' tcx > ,
2020-03-17 15:30:32 +01:00
isa : & dyn TargetIsa ,
2020-06-13 17:03:34 +02:00
symbol : usize ,
2020-09-16 18:45:19 +02:00
local_map : & IndexVec < mir ::Local , CPlace < ' tcx > > ,
2020-08-28 12:10:48 +02:00
#[ allow(rustc::default_hash_types) ] value_labels_ranges : & std ::collections ::HashMap <
ValueLabel ,
Vec < ValueLocRange > ,
> ,
2019-11-28 21:35:03 +01:00
place : Place < ' tcx > ,
) -> AttributeValue {
assert! ( place . projection . is_empty ( ) ) ; // FIXME implement them
2020-09-16 18:45:19 +02:00
match local_map [ place . local ] . inner ( ) {
2020-06-27 11:58:44 +02:00
CPlaceInner ::Var ( _local , var ) = > {
let value_label = cranelift_codegen ::ir ::ValueLabel ::new ( var . index ( ) ) ;
2019-11-28 21:35:03 +01:00
if let Some ( value_loc_ranges ) = value_labels_ranges . get ( & value_label ) {
let loc_list = LocationList (
value_loc_ranges
. iter ( )
. map ( | value_loc_range | Location ::StartEnd {
begin : Address ::Symbol {
2020-06-13 17:03:34 +02:00
symbol ,
2019-11-28 21:35:03 +01:00
addend : i64 ::from ( value_loc_range . start ) ,
} ,
2021-03-05 19:12:59 +01:00
end : Address ::Symbol { symbol , addend : i64 ::from ( value_loc_range . end ) } ,
2021-12-20 18:56:35 +01:00
data : translate_loc ( isa , value_loc_range . loc ) . unwrap ( ) ,
2019-11-28 21:35:03 +01:00
} )
. collect ( ) ,
) ;
2020-06-13 17:03:34 +02:00
let loc_list_id = debug_context . dwarf . unit . locations . add ( loc_list ) ;
2019-11-28 21:35:03 +01:00
AttributeValue ::LocationListRef ( loc_list_id )
} else {
// FIXME set value labels for unused locals
2020-06-05 12:40:33 +02:00
AttributeValue ::Exprloc ( Expression ::new ( ) )
2019-11-28 21:35:03 +01:00
}
}
2020-07-02 19:23:21 -03:00
CPlaceInner ::VarPair ( _ , _ , _ ) = > {
// FIXME implement this
AttributeValue ::Exprloc ( Expression ::new ( ) )
}
2020-03-28 15:21:58 +01:00
CPlaceInner ::VarLane ( _ , _ , _ ) = > {
// FIXME implement this
AttributeValue ::Exprloc ( Expression ::new ( ) )
}
2019-11-28 21:35:03 +01:00
CPlaceInner ::Addr ( _ , _ ) = > {
// FIXME implement this (used by arguments and returns)
2019-11-11 21:43:57 +01:00
2020-06-05 12:40:33 +02:00
AttributeValue ::Exprloc ( Expression ::new ( ) )
2019-12-20 22:00:12 +01:00
// For PointerBase::Stack:
2021-12-20 18:56:35 +01:00
//AttributeValue::Exprloc(translate_loc(ValueLoc::Stack(*stack_slot)).unwrap())
2019-11-28 21:35:03 +01:00
}
}
}
2019-11-11 21:43:57 +01:00
2020-03-17 15:30:32 +01:00
// Adapted from https://github.com/CraneStation/wasmtime/blob/5a1845b4caf7a5dba8eda1fef05213a532ed4259/crates/debug/src/transform/expression.rs#L59-L137
2021-12-20 18:56:35 +01:00
fn translate_loc ( isa : & dyn TargetIsa , loc : LabelValueLoc ) -> Option < Expression > {
2019-11-11 21:43:57 +01:00
match loc {
2021-03-05 19:12:59 +01:00
LabelValueLoc ::Reg ( reg ) = > {
let machine_reg = isa . map_regalloc_reg_to_dwarf ( reg ) . unwrap ( ) ;
let mut expr = Expression ::new ( ) ;
expr . op_reg ( gimli ::Register ( machine_reg ) ) ;
Some ( expr )
}
LabelValueLoc ::SPOffset ( offset ) = > {
let mut expr = Expression ::new ( ) ;
expr . op_breg ( X86_64 ::RSP , offset ) ;
Some ( expr )
}
2019-11-11 21:43:57 +01:00
}
}