1
- use crate :: llvm;
2
- use crate :: llvm:: archive_ro:: ArchiveRO ;
3
- use crate :: llvm:: { mk_section_iter, False , ObjectFile } ;
4
- use rustc_middle:: middle:: cstore:: MetadataLoader ;
5
1
use rustc_target:: spec:: Target ;
6
2
7
- use rustc_codegen_ssa:: METADATA_FILENAME ;
8
- use rustc_data_structures:: owning_ref:: OwningRef ;
9
- use rustc_data_structures:: rustc_erase_owner;
10
- use tracing:: debug;
11
-
12
3
use rustc_fs_util:: path_to_c_string;
13
4
use std:: path:: Path ;
14
5
use std:: slice;
15
6
16
- pub use rustc_data_structures:: sync:: MetadataRef ;
17
-
18
- pub struct LlvmMetadataLoader ;
19
-
20
- impl MetadataLoader for LlvmMetadataLoader {
21
- fn get_rlib_metadata ( & self , _: & Target , filename : & Path ) -> Result < MetadataRef , String > {
22
- // Use ArchiveRO for speed here, it's backed by LLVM and uses mmap
23
- // internally to read the file. We also avoid even using a memcpy by
24
- // just keeping the archive along while the metadata is in use.
25
- let archive =
26
- ArchiveRO :: open ( filename) . map ( |ar| OwningRef :: new ( Box :: new ( ar) ) ) . map_err ( |e| {
27
- debug ! ( "llvm didn't like `{}`: {}" , filename. display( ) , e) ;
28
- format ! ( "failed to read rlib metadata in '{}': {}" , filename. display( ) , e)
29
- } ) ?;
30
- let buf: OwningRef < _ , [ u8 ] > = archive. try_map ( |ar| {
31
- ar. iter ( )
32
- . filter_map ( |s| s. ok ( ) )
33
- . find ( |sect| sect. name ( ) == Some ( METADATA_FILENAME ) )
34
- . map ( |s| s. data ( ) )
35
- . ok_or_else ( || {
36
- debug ! ( "didn't find '{}' in the archive" , METADATA_FILENAME ) ;
37
- format ! ( "failed to read rlib metadata: '{}'" , filename. display( ) )
38
- } )
39
- } ) ?;
40
- Ok ( rustc_erase_owner ! ( buf) )
41
- }
42
-
43
- fn get_dylib_metadata ( & self , target : & Target , filename : & Path ) -> Result < MetadataRef , String > {
44
- unsafe {
45
- let buf = path_to_c_string ( filename) ;
46
- let mb = llvm:: LLVMRustCreateMemoryBufferWithContentsOfFile ( buf. as_ptr ( ) )
47
- . ok_or_else ( || format ! ( "error reading library: '{}'" , filename. display( ) ) ) ?;
48
- let of =
49
- ObjectFile :: new ( mb) . map ( |of| OwningRef :: new ( Box :: new ( of) ) ) . ok_or_else ( || {
50
- format ! ( "provided path not an object file: '{}'" , filename. display( ) )
51
- } ) ?;
52
- let buf = of. try_map ( |of| search_meta_section ( of, target, filename) ) ?;
53
- Ok ( rustc_erase_owner ! ( buf) )
54
- }
55
- }
56
- }
57
-
58
- fn search_meta_section < ' a > (
59
- of : & ' a ObjectFile ,
60
- target : & Target ,
61
- filename : & Path ,
62
- ) -> Result < & ' a [ u8 ] , String > {
63
- unsafe {
64
- let si = mk_section_iter ( of. llof ) ;
65
- while llvm:: LLVMIsSectionIteratorAtEnd ( of. llof , si. llsi ) == False {
66
- let mut name_buf = None ;
67
- let name_len = llvm:: LLVMRustGetSectionName ( si. llsi , & mut name_buf) ;
68
- let name = name_buf. map_or_else (
69
- String :: new, // We got a null ptr, ignore `name_len`.
70
- |buf| {
71
- String :: from_utf8 (
72
- slice:: from_raw_parts ( buf. as_ptr ( ) as * const u8 , name_len as usize )
73
- . to_vec ( ) ,
74
- )
75
- . unwrap ( )
76
- } ,
77
- ) ;
78
- debug ! ( "get_metadata_section: name {}" , name) ;
79
- if read_metadata_section_name ( target) == name {
80
- let cbuf = llvm:: LLVMGetSectionContents ( si. llsi ) ;
81
- let csz = llvm:: LLVMGetSectionSize ( si. llsi ) as usize ;
82
- // The buffer is valid while the object file is around
83
- let buf: & ' a [ u8 ] = slice:: from_raw_parts ( cbuf as * const u8 , csz) ;
84
- return Ok ( buf) ;
85
- }
86
- llvm:: LLVMMoveToNextSection ( si. llsi ) ;
87
- }
88
- }
89
- Err ( format ! ( "metadata not found: '{}'" , filename. display( ) ) )
90
- }
91
-
92
7
pub fn metadata_section_name ( target : & Target ) -> & ' static str {
93
8
// Historical note:
94
9
//
@@ -106,7 +21,3 @@ pub fn metadata_section_name(target: &Target) -> &'static str {
106
21
107
22
if target. is_like_osx { "__DATA,.rustc" } else { ".rustc" }
108
23
}
109
-
110
- fn read_metadata_section_name ( _target : & Target ) -> & ' static str {
111
- ".rustc"
112
- }
0 commit comments