@@ -468,23 +468,74 @@ impl fmt::Display for LinkOutputKind {
468
468
469
469
pub type LinkArgs = BTreeMap < LinkerFlavor , Vec < StaticCow < str > > > ;
470
470
471
- #[ derive( Clone , Copy , Hash , Debug , PartialEq , Eq ) ]
471
+ /// Which kind of debuginfo does the target use?
472
+ ///
473
+ /// Useful in determining whether a target supports Split DWARF (a target with
474
+ /// `DebuginfoKind::Dwarf` and supporting `SplitDebuginfo::Unpacked` for example).
475
+ #[ derive( Clone , Copy , Debug , Default , Eq , Hash , PartialEq ) ]
476
+ pub enum DebuginfoKind {
477
+ /// DWARF debuginfo (such as that used on `x86_64_unknown_linux_gnu`).
478
+ #[ default]
479
+ Dwarf ,
480
+ /// DWARF debuginfo in dSYM files (such as on Apple platforms).
481
+ DwarfDsym ,
482
+ /// Program database files (such as on Windows).
483
+ Pdb ,
484
+ }
485
+
486
+ impl DebuginfoKind {
487
+ fn as_str ( & self ) -> & ' static str {
488
+ match self {
489
+ DebuginfoKind :: Dwarf => "dwarf" ,
490
+ DebuginfoKind :: DwarfDsym => "dwarf-dsym" ,
491
+ DebuginfoKind :: Pdb => "pdb" ,
492
+ }
493
+ }
494
+ }
495
+
496
+ impl FromStr for DebuginfoKind {
497
+ type Err = ( ) ;
498
+
499
+ fn from_str ( s : & str ) -> Result < Self , ( ) > {
500
+ Ok ( match s {
501
+ "dwarf" => DebuginfoKind :: Dwarf ,
502
+ "dwarf-dsym" => DebuginfoKind :: DwarfDsym ,
503
+ "pdb" => DebuginfoKind :: Pdb ,
504
+ _ => return Err ( ( ) ) ,
505
+ } )
506
+ }
507
+ }
508
+
509
+ impl ToJson for DebuginfoKind {
510
+ fn to_json ( & self ) -> Json {
511
+ self . as_str ( ) . to_json ( )
512
+ }
513
+ }
514
+
515
+ impl fmt:: Display for DebuginfoKind {
516
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
517
+ f. write_str ( self . as_str ( ) )
518
+ }
519
+ }
520
+
521
+ #[ derive( Clone , Copy , Debug , Default , Eq , Hash , PartialEq ) ]
472
522
pub enum SplitDebuginfo {
473
523
/// Split debug-information is disabled, meaning that on supported platforms
474
524
/// you can find all debug information in the executable itself. This is
475
525
/// only supported for ELF effectively.
476
526
///
477
527
/// * Windows - not supported
478
528
/// * macOS - don't run `dsymutil`
479
- /// * ELF - `.dwarf_*` sections
529
+ /// * ELF - `.debug_*` sections
530
+ #[ default]
480
531
Off ,
481
532
482
533
/// Split debug-information can be found in a "packed" location separate
483
534
/// from the final artifact. This is supported on all platforms.
484
535
///
485
536
/// * Windows - `*.pdb`
486
537
/// * macOS - `*.dSYM` (run `dsymutil`)
487
- /// * ELF - `*.dwp` (run `rust-llvm-dwp `)
538
+ /// * ELF - `*.dwp` (run `thorin `)
488
539
Packed ,
489
540
490
541
/// Split debug-information can be found in individual object files on the
@@ -509,7 +560,7 @@ impl SplitDebuginfo {
509
560
impl FromStr for SplitDebuginfo {
510
561
type Err = ( ) ;
511
562
512
- fn from_str ( s : & str ) -> Result < SplitDebuginfo , ( ) > {
563
+ fn from_str ( s : & str ) -> Result < Self , ( ) > {
513
564
Ok ( match s {
514
565
"off" => SplitDebuginfo :: Off ,
515
566
"unpacked" => SplitDebuginfo :: Unpacked ,
@@ -1436,9 +1487,13 @@ pub struct TargetOptions {
1436
1487
/// thumb and arm interworking.
1437
1488
pub has_thumb_interworking : bool ,
1438
1489
1490
+ /// Which kind of debuginfo is used by this target?
1491
+ pub debuginfo_kind : DebuginfoKind ,
1439
1492
/// How to handle split debug information, if at all. Specifying `None` has
1440
1493
/// target-specific meaning.
1441
1494
pub split_debuginfo : SplitDebuginfo ,
1495
+ /// Which kinds of split debuginfo are supported by the target?
1496
+ pub supported_split_debuginfo : StaticCow < [ SplitDebuginfo ] > ,
1442
1497
1443
1498
/// The sanitizers supported by this target
1444
1499
///
@@ -1596,7 +1651,10 @@ impl Default for TargetOptions {
1596
1651
use_ctors_section : false ,
1597
1652
eh_frame_header : true ,
1598
1653
has_thumb_interworking : false ,
1599
- split_debuginfo : SplitDebuginfo :: Off ,
1654
+ debuginfo_kind : Default :: default ( ) ,
1655
+ split_debuginfo : Default :: default ( ) ,
1656
+ // `Off` is supported by default, but targets can remove this manually, e.g. Windows.
1657
+ supported_split_debuginfo : Cow :: Borrowed ( & [ SplitDebuginfo :: Off ] ) ,
1600
1658
supported_sanitizers : SanitizerSet :: empty ( ) ,
1601
1659
default_adjusted_cabi : None ,
1602
1660
c_enum_min_bits : 32 ,
@@ -1869,6 +1927,19 @@ impl Target {
1869
1927
Some ( Ok ( ( ) ) )
1870
1928
} ) ) . unwrap_or( Ok ( ( ) ) )
1871
1929
} ) ;
1930
+ ( $key_name: ident, DebuginfoKind ) => ( {
1931
+ let name = ( stringify!( $key_name) ) . replace( "_" , "-" ) ;
1932
+ obj. remove( & name) . and_then( |o| o. as_str( ) . and_then( |s| {
1933
+ match s. parse:: <DebuginfoKind >( ) {
1934
+ Ok ( level) => base. $key_name = level,
1935
+ _ => return Some ( Err (
1936
+ format!( "'{s}' is not a valid value for debuginfo-kind. Use 'dwarf', \
1937
+ 'dwarf-dsym' or 'pdb'.")
1938
+ ) ) ,
1939
+ }
1940
+ Some ( Ok ( ( ) ) )
1941
+ } ) ) . unwrap_or( Ok ( ( ) ) )
1942
+ } ) ;
1872
1943
( $key_name: ident, SplitDebuginfo ) => ( {
1873
1944
let name = ( stringify!( $key_name) ) . replace( "_" , "-" ) ;
1874
1945
obj. remove( & name) . and_then( |o| o. as_str( ) . and_then( |s| {
@@ -1905,6 +1976,25 @@ impl Target {
1905
1976
}
1906
1977
}
1907
1978
} ) ;
1979
+ ( $key_name: ident, falliable_list) => ( {
1980
+ let name = ( stringify!( $key_name) ) . replace( "_" , "-" ) ;
1981
+ obj. remove( & name) . and_then( |j| {
1982
+ if let Some ( v) = j. as_array( ) {
1983
+ match v. iter( ) . map( |a| FromStr :: from_str( a. as_str( ) . unwrap( ) ) ) . collect( ) {
1984
+ Ok ( l) => { base. $key_name = l } ,
1985
+ // FIXME: `falliable_list` can't re-use the `key!` macro for list
1986
+ // elements and the error messages from that macro, so it has a bad
1987
+ // generic message instead
1988
+ Err ( _) => return Some ( Err (
1989
+ format!( "`{:?}` is not a valid value for `{}`" , j, name)
1990
+ ) ) ,
1991
+ }
1992
+ } else {
1993
+ incorrect_type. push( name)
1994
+ }
1995
+ Some ( Ok ( ( ) ) )
1996
+ } ) . unwrap_or( Ok ( ( ) ) )
1997
+ } ) ;
1908
1998
( $key_name: ident, optional) => ( {
1909
1999
let name = ( stringify!( $key_name) ) . replace( "_" , "-" ) ;
1910
2000
if let Some ( o) = obj. remove( & name) {
@@ -2191,7 +2281,9 @@ impl Target {
2191
2281
key ! ( use_ctors_section, bool ) ;
2192
2282
key ! ( eh_frame_header, bool ) ;
2193
2283
key ! ( has_thumb_interworking, bool ) ;
2284
+ key ! ( debuginfo_kind, DebuginfoKind ) ?;
2194
2285
key ! ( split_debuginfo, SplitDebuginfo ) ?;
2286
+ key ! ( supported_split_debuginfo, falliable_list) ?;
2195
2287
key ! ( supported_sanitizers, SanitizerSet ) ?;
2196
2288
key ! ( default_adjusted_cabi, Option <Abi >) ?;
2197
2289
key ! ( c_enum_min_bits, u64 ) ;
@@ -2435,7 +2527,9 @@ impl ToJson for Target {
2435
2527
target_option_val ! ( use_ctors_section) ;
2436
2528
target_option_val ! ( eh_frame_header) ;
2437
2529
target_option_val ! ( has_thumb_interworking) ;
2530
+ target_option_val ! ( debuginfo_kind) ;
2438
2531
target_option_val ! ( split_debuginfo) ;
2532
+ target_option_val ! ( supported_split_debuginfo) ;
2439
2533
target_option_val ! ( supported_sanitizers) ;
2440
2534
target_option_val ! ( c_enum_min_bits) ;
2441
2535
target_option_val ! ( generate_arange_section) ;
0 commit comments