1
- use rustc:: middle:: cstore:: MetadataLoader ;
2
- use rustc_data_structures:: owning_ref:: { self , OwningRef } ;
3
- use rustc_data_structures:: rustc_erase_owner;
4
1
use std:: fs:: File ;
5
2
use std:: path:: Path ;
6
3
4
+ use rustc:: session:: config;
5
+ use rustc:: ty:: TyCtxt ;
6
+ use rustc:: middle:: cstore:: { EncodedMetadata , MetadataLoader } ;
7
+ use rustc_data_structures:: owning_ref:: { self , OwningRef } ;
8
+ use rustc_data_structures:: rustc_erase_owner;
9
+ use rustc_target:: spec:: Target ;
10
+
7
11
pub const METADATA_FILENAME : & str = "rust.metadata.bin" ;
8
12
9
13
pub struct CraneliftMetadataLoader ;
10
14
11
15
impl MetadataLoader for CraneliftMetadataLoader {
12
16
fn get_rlib_metadata (
13
17
& self ,
14
- _target : & crate :: rustc_target :: spec :: Target ,
18
+ _target : & Target ,
15
19
path : & Path ,
16
20
) -> Result < owning_ref:: ErasedBoxRef < [ u8 ] > , String > {
17
21
let mut archive = ar:: Archive :: new ( File :: open ( path) . map_err ( |e| format ! ( "{:?}" , e) ) ?) ;
@@ -32,9 +36,63 @@ impl MetadataLoader for CraneliftMetadataLoader {
32
36
33
37
fn get_dylib_metadata (
34
38
& self ,
35
- _target : & crate :: rustc_target :: spec :: Target ,
36
- _path : & Path ,
39
+ _target : & Target ,
40
+ path : & Path ,
37
41
) -> Result < owning_ref:: ErasedBoxRef < [ u8 ] > , String > {
38
- Err ( "dylib metadata loading is not yet supported" . to_string ( ) )
42
+ println ! ( "abc" ) ;
43
+ use object:: Object ;
44
+ let file = std:: fs:: read ( path) . map_err ( |e| format ! ( "read:{:?}" , e) ) ?;
45
+ let file = object:: File :: parse ( & file) . map_err ( |e| format ! ( "parse: {:?}" , e) ) ?;
46
+ let buf = file. section_data_by_name ( ".rustc" ) . ok_or ( "no .rustc section" ) ?. into_owned ( ) ;
47
+ let buf: OwningRef < Vec < u8 > , [ u8 ] > = OwningRef :: new ( buf) . into ( ) ;
48
+ Ok ( rustc_erase_owner ! ( buf. map_owner_box( ) ) )
39
49
}
40
50
}
51
+
52
+ // Adapted from https://github.com/rust-lang/rust/blob/da573206f87b5510de4b0ee1a9c044127e409bd3/src/librustc_codegen_llvm/base.rs#L47-L112
53
+ pub fn write_metadata < ' a , ' gcx > (
54
+ tcx : TyCtxt < ' a , ' gcx , ' gcx > ,
55
+ artifact : & mut faerie:: Artifact
56
+ ) -> EncodedMetadata {
57
+ use std:: io:: Write ;
58
+ use flate2:: Compression ;
59
+ use flate2:: write:: DeflateEncoder ;
60
+
61
+ #[ derive( PartialEq , Eq , PartialOrd , Ord ) ]
62
+ enum MetadataKind {
63
+ None ,
64
+ Uncompressed ,
65
+ Compressed
66
+ }
67
+
68
+ let kind = tcx. sess . crate_types . borrow ( ) . iter ( ) . map ( |ty| {
69
+ match * ty {
70
+ config:: CrateType :: Executable |
71
+ config:: CrateType :: Staticlib |
72
+ config:: CrateType :: Cdylib => MetadataKind :: None ,
73
+
74
+ config:: CrateType :: Rlib => MetadataKind :: Uncompressed ,
75
+
76
+ config:: CrateType :: Dylib |
77
+ config:: CrateType :: ProcMacro => MetadataKind :: Compressed ,
78
+ }
79
+ } ) . max ( ) . unwrap_or ( MetadataKind :: None ) ;
80
+
81
+ if kind == MetadataKind :: None {
82
+ return EncodedMetadata :: new ( ) ;
83
+ }
84
+
85
+ let metadata = tcx. encode_metadata ( ) ;
86
+ if kind == MetadataKind :: Uncompressed {
87
+ return metadata;
88
+ }
89
+
90
+ assert ! ( kind == MetadataKind :: Compressed ) ;
91
+ let mut compressed = tcx. metadata_encoding_version ( ) ;
92
+ DeflateEncoder :: new ( & mut compressed, Compression :: fast ( ) )
93
+ . write_all ( & metadata. raw_data ) . unwrap ( ) ;
94
+
95
+ artifact. declare_with ( ".rustc" , faerie:: Decl :: debug_section ( ) , compressed) . unwrap ( ) ;
96
+
97
+ metadata
98
+ }
0 commit comments