@@ -136,7 +136,7 @@ fn fill_region_tables<'tcx>(
136
136
/// as a global variable in the `__llvm_covfun` section.
137
137
pub ( crate ) fn generate_covfun_record < ' tcx > (
138
138
cx : & CodegenCx < ' _ , ' tcx > ,
139
- filenames_ref : u64 ,
139
+ filenames_hash : u64 ,
140
140
covfun : & CovfunRecord < ' tcx > ,
141
141
) {
142
142
let & CovfunRecord {
@@ -155,46 +155,45 @@ pub(crate) fn generate_covfun_record<'tcx>(
155
155
regions,
156
156
) ;
157
157
158
- // Concatenate the encoded coverage mappings
159
- let coverage_mapping_size = coverage_mapping_buffer. len ( ) ;
160
- let coverage_mapping_val = cx. const_bytes ( & coverage_mapping_buffer) ;
161
-
158
+ // A covfun record consists of four target-endian integers, followed by the
159
+ // encoded mapping data in bytes. Note that the length field is 32 bits.
160
+ // <https://llvm.org/docs/CoverageMappingFormat.html#llvm-ir-representation>
161
+ // See also `src/llvm-project/clang/lib/CodeGen/CoverageMappingGen.cpp` and
162
+ // `COVMAP_V3` in `src/llvm-project/llvm/include/llvm/ProfileData/InstrProfData.inc`.
162
163
let func_name_hash = llvm_cov:: hash_bytes ( mangled_function_name. as_bytes ( ) ) ;
163
- let func_name_hash_val = cx. const_u64 ( func_name_hash) ;
164
- let coverage_mapping_size_val = cx. const_u32 ( coverage_mapping_size as u32 ) ;
165
- let source_hash_val = cx. const_u64 ( source_hash) ;
166
- let filenames_ref_val = cx. const_u64 ( filenames_ref) ;
167
- let func_record_val = cx. const_struct (
164
+ let covfun_record = cx. const_struct (
168
165
& [
169
- func_name_hash_val ,
170
- coverage_mapping_size_val ,
171
- source_hash_val ,
172
- filenames_ref_val ,
173
- coverage_mapping_val ,
166
+ cx . const_u64 ( func_name_hash ) ,
167
+ cx . const_u32 ( coverage_mapping_buffer . len ( ) as u32 ) ,
168
+ cx . const_u64 ( source_hash ) ,
169
+ cx . const_u64 ( filenames_hash ) ,
170
+ cx . const_bytes ( & coverage_mapping_buffer ) ,
174
171
] ,
175
- /*packed=*/ true ,
172
+ // This struct needs to be packed, so that the 32-bit length field
173
+ // doesn't have unexpected padding.
174
+ true ,
176
175
) ;
177
176
178
177
// Choose a variable name to hold this function's covfun data.
179
178
// Functions that are used have a suffix ("u") to distinguish them from
180
179
// unused copies of the same function (from different CGUs), so that if a
181
180
// linker sees both it won't discard the used copy's data.
182
- let func_record_var_name =
183
- CString :: new ( format ! ( "__covrec_{:X}{}" , func_name_hash, if is_used { "u" } else { "" } ) )
184
- . unwrap ( ) ;
185
- debug ! ( "function record var name: {:?}" , func_record_var_name) ;
186
-
187
- let llglobal = llvm:: add_global ( cx. llmod , cx. val_ty ( func_record_val) , & func_record_var_name) ;
188
- llvm:: set_initializer ( llglobal, func_record_val) ;
189
- llvm:: set_global_constant ( llglobal, true ) ;
190
- llvm:: set_linkage ( llglobal, llvm:: Linkage :: LinkOnceODRLinkage ) ;
191
- llvm:: set_visibility ( llglobal, llvm:: Visibility :: Hidden ) ;
192
- llvm:: set_section ( llglobal, cx. covfun_section_name ( ) ) ;
181
+ let u = if is_used { "u" } else { "" } ;
182
+ let covfun_var_name = CString :: new ( format ! ( "__covrec_{func_name_hash:X}{u}" ) ) . unwrap ( ) ;
183
+ debug ! ( "function record var name: {covfun_var_name:?}" ) ;
184
+
185
+ let covfun_global = llvm:: add_global ( cx. llmod , cx. val_ty ( covfun_record) , & covfun_var_name) ;
186
+ llvm:: set_initializer ( covfun_global, covfun_record) ;
187
+ llvm:: set_global_constant ( covfun_global, true ) ;
188
+ llvm:: set_linkage ( covfun_global, llvm:: Linkage :: LinkOnceODRLinkage ) ;
189
+ llvm:: set_visibility ( covfun_global, llvm:: Visibility :: Hidden ) ;
190
+ llvm:: set_section ( covfun_global, cx. covfun_section_name ( ) ) ;
193
191
// LLVM's coverage mapping format specifies 8-byte alignment for items in this section.
194
192
// <https://llvm.org/docs/CoverageMappingFormat.html>
195
- llvm:: set_alignment ( llglobal , Align :: EIGHT ) ;
193
+ llvm:: set_alignment ( covfun_global , Align :: EIGHT ) ;
196
194
if cx. target_spec ( ) . supports_comdat ( ) {
197
- llvm:: set_comdat ( cx. llmod , llglobal , & func_record_var_name ) ;
195
+ llvm:: set_comdat ( cx. llmod , covfun_global , & covfun_var_name ) ;
198
196
}
199
- cx. add_used_global ( llglobal) ;
197
+
198
+ cx. add_used_global ( covfun_global) ;
200
199
}
0 commit comments