@@ -210,133 +210,111 @@ pub(crate) unsafe fn create_module<'ll>(
210210 // If skipping the PLT is enabled, we need to add some module metadata
211211 // to ensure intrinsic calls don't use it.
212212 if !sess. needs_plt ( ) {
213- let avoid_plt = c"RtLibUseGOT" . as_ptr ( ) ;
214- unsafe {
215- llvm:: LLVMRustAddModuleFlagU32 ( llmod, llvm:: LLVMModFlagBehavior :: Warning , avoid_plt, 1 ) ;
216- }
213+ llvm:: add_module_flag_u32 ( llmod, llvm:: ModuleFlagMergeBehavior :: Warning , "RtLibUseGOT" , 1 ) ;
217214 }
218215
219216 // Enable canonical jump tables if CFI is enabled. (See https://reviews.llvm.org/D65629.)
220217 if sess. is_sanitizer_cfi_canonical_jump_tables_enabled ( ) && sess. is_sanitizer_cfi_enabled ( ) {
221- let canonical_jump_tables = c"CFI Canonical Jump Tables" . as_ptr ( ) ;
222- unsafe {
223- llvm:: LLVMRustAddModuleFlagU32 (
224- llmod,
225- llvm:: LLVMModFlagBehavior :: Override ,
226- canonical_jump_tables,
227- 1 ,
228- ) ;
229- }
218+ llvm:: add_module_flag_u32 (
219+ llmod,
220+ llvm:: ModuleFlagMergeBehavior :: Override ,
221+ "CFI Canonical Jump Tables" ,
222+ 1 ,
223+ ) ;
230224 }
231225
232226 // If we're normalizing integers with CFI, ensure LLVM generated functions do the same.
233227 // See https://github.com/llvm/llvm-project/pull/104826
234228 if sess. is_sanitizer_cfi_normalize_integers_enabled ( ) {
235- let cfi_normalize_integers = c"cfi-normalize-integers" . as_ptr ( ) ;
236- unsafe {
237- llvm:: LLVMRustAddModuleFlagU32 (
238- llmod,
239- llvm:: LLVMModFlagBehavior :: Override ,
240- cfi_normalize_integers,
241- 1 ,
242- ) ;
243- }
229+ llvm:: add_module_flag_u32 (
230+ llmod,
231+ llvm:: ModuleFlagMergeBehavior :: Override ,
232+ "cfi-normalize-integers" ,
233+ 1 ,
234+ ) ;
244235 }
245236
246237 // Enable LTO unit splitting if specified or if CFI is enabled. (See
247238 // https://reviews.llvm.org/D53891.)
248239 if sess. is_split_lto_unit_enabled ( ) || sess. is_sanitizer_cfi_enabled ( ) {
249- let enable_split_lto_unit = c"EnableSplitLTOUnit" . as_ptr ( ) ;
250- unsafe {
251- llvm:: LLVMRustAddModuleFlagU32 (
252- llmod,
253- llvm:: LLVMModFlagBehavior :: Override ,
254- enable_split_lto_unit,
255- 1 ,
256- ) ;
257- }
240+ llvm:: add_module_flag_u32 (
241+ llmod,
242+ llvm:: ModuleFlagMergeBehavior :: Override ,
243+ "EnableSplitLTOUnit" ,
244+ 1 ,
245+ ) ;
258246 }
259247
260248 // Add "kcfi" module flag if KCFI is enabled. (See https://reviews.llvm.org/D119296.)
261249 if sess. is_sanitizer_kcfi_enabled ( ) {
262- let kcfi = c"kcfi" . as_ptr ( ) ;
263- unsafe {
264- llvm:: LLVMRustAddModuleFlagU32 ( llmod, llvm:: LLVMModFlagBehavior :: Override , kcfi, 1 ) ;
265- }
250+ llvm:: add_module_flag_u32 ( llmod, llvm:: ModuleFlagMergeBehavior :: Override , "kcfi" , 1 ) ;
266251
267252 // Add "kcfi-offset" module flag with -Z patchable-function-entry (See
268253 // https://reviews.llvm.org/D141172).
269254 let pfe =
270255 PatchableFunctionEntry :: from_config ( sess. opts . unstable_opts . patchable_function_entry ) ;
271256 if pfe. prefix ( ) > 0 {
272- let kcfi_offset = c"kcfi-offset" . as_ptr ( ) ;
273- unsafe {
274- llvm:: LLVMRustAddModuleFlagU32 (
275- llmod,
276- llvm:: LLVMModFlagBehavior :: Override ,
277- kcfi_offset,
278- pfe. prefix ( ) . into ( ) ,
279- ) ;
280- }
257+ llvm:: add_module_flag_u32 (
258+ llmod,
259+ llvm:: ModuleFlagMergeBehavior :: Override ,
260+ "kcfi-offset" ,
261+ pfe. prefix ( ) . into ( ) ,
262+ ) ;
281263 }
282264 }
283265
284266 // Control Flow Guard is currently only supported by the MSVC linker on Windows.
285267 if sess. target . is_like_msvc {
286- unsafe {
287- match sess. opts . cg . control_flow_guard {
288- CFGuard :: Disabled => { }
289- CFGuard :: NoChecks => {
290- // Set `cfguard=1` module flag to emit metadata only.
291- llvm:: LLVMRustAddModuleFlagU32 (
292- llmod,
293- llvm:: LLVMModFlagBehavior :: Warning ,
294- c"cfguard" . as_ptr ( ) as * const _ ,
295- 1 ,
296- )
297- }
298- CFGuard :: Checks => {
299- // Set `cfguard=2` module flag to emit metadata and checks.
300- llvm:: LLVMRustAddModuleFlagU32 (
301- llmod,
302- llvm:: LLVMModFlagBehavior :: Warning ,
303- c"cfguard" . as_ptr ( ) as * const _ ,
304- 2 ,
305- )
306- }
268+ match sess. opts . cg . control_flow_guard {
269+ CFGuard :: Disabled => { }
270+ CFGuard :: NoChecks => {
271+ // Set `cfguard=1` module flag to emit metadata only.
272+ llvm:: add_module_flag_u32 (
273+ llmod,
274+ llvm:: ModuleFlagMergeBehavior :: Warning ,
275+ "cfguard" ,
276+ 1 ,
277+ ) ;
278+ }
279+ CFGuard :: Checks => {
280+ // Set `cfguard=2` module flag to emit metadata and checks.
281+ llvm:: add_module_flag_u32 (
282+ llmod,
283+ llvm:: ModuleFlagMergeBehavior :: Warning ,
284+ "cfguard" ,
285+ 2 ,
286+ ) ;
307287 }
308288 }
309289 }
310290
311291 if let Some ( BranchProtection { bti, pac_ret } ) = sess. opts . unstable_opts . branch_protection {
312292 if sess. target . arch == "aarch64" {
313- unsafe {
314- llvm:: LLVMRustAddModuleFlagU32 (
315- llmod,
316- llvm:: LLVMModFlagBehavior :: Min ,
317- c"branch-target-enforcement" . as_ptr ( ) ,
318- bti. into ( ) ,
319- ) ;
320- llvm:: LLVMRustAddModuleFlagU32 (
321- llmod,
322- llvm:: LLVMModFlagBehavior :: Min ,
323- c"sign-return-address" . as_ptr ( ) ,
324- pac_ret. is_some ( ) . into ( ) ,
325- ) ;
326- let pac_opts = pac_ret. unwrap_or ( PacRet { leaf : false , key : PAuthKey :: A } ) ;
327- llvm:: LLVMRustAddModuleFlagU32 (
328- llmod,
329- llvm:: LLVMModFlagBehavior :: Min ,
330- c"sign-return-address-all" . as_ptr ( ) ,
331- pac_opts. leaf . into ( ) ,
332- ) ;
333- llvm:: LLVMRustAddModuleFlagU32 (
334- llmod,
335- llvm:: LLVMModFlagBehavior :: Min ,
336- c"sign-return-address-with-bkey" . as_ptr ( ) ,
337- u32:: from ( pac_opts. key == PAuthKey :: B ) ,
338- ) ;
339- }
293+ llvm:: add_module_flag_u32 (
294+ llmod,
295+ llvm:: ModuleFlagMergeBehavior :: Min ,
296+ "branch-target-enforcement" ,
297+ bti. into ( ) ,
298+ ) ;
299+ llvm:: add_module_flag_u32 (
300+ llmod,
301+ llvm:: ModuleFlagMergeBehavior :: Min ,
302+ "sign-return-address" ,
303+ pac_ret. is_some ( ) . into ( ) ,
304+ ) ;
305+ let pac_opts = pac_ret. unwrap_or ( PacRet { leaf : false , key : PAuthKey :: A } ) ;
306+ llvm:: add_module_flag_u32 (
307+ llmod,
308+ llvm:: ModuleFlagMergeBehavior :: Min ,
309+ "sign-return-address-all" ,
310+ pac_opts. leaf . into ( ) ,
311+ ) ;
312+ llvm:: add_module_flag_u32 (
313+ llmod,
314+ llvm:: ModuleFlagMergeBehavior :: Min ,
315+ "sign-return-address-with-bkey" ,
316+ u32:: from ( pac_opts. key == PAuthKey :: B ) ,
317+ ) ;
340318 } else {
341319 bug ! (
342320 "branch-protection used on non-AArch64 target; \
@@ -347,75 +325,59 @@ pub(crate) unsafe fn create_module<'ll>(
347325
348326 // Pass on the control-flow protection flags to LLVM (equivalent to `-fcf-protection` in Clang).
349327 if let CFProtection :: Branch | CFProtection :: Full = sess. opts . unstable_opts . cf_protection {
350- unsafe {
351- llvm:: LLVMRustAddModuleFlagU32 (
352- llmod,
353- llvm:: LLVMModFlagBehavior :: Override ,
354- c"cf-protection-branch" . as_ptr ( ) ,
355- 1 ,
356- ) ;
357- }
328+ llvm:: add_module_flag_u32 (
329+ llmod,
330+ llvm:: ModuleFlagMergeBehavior :: Override ,
331+ "cf-protection-branch" ,
332+ 1 ,
333+ ) ;
358334 }
359335 if let CFProtection :: Return | CFProtection :: Full = sess. opts . unstable_opts . cf_protection {
360- unsafe {
361- llvm:: LLVMRustAddModuleFlagU32 (
362- llmod,
363- llvm:: LLVMModFlagBehavior :: Override ,
364- c"cf-protection-return" . as_ptr ( ) ,
365- 1 ,
366- ) ;
367- }
336+ llvm:: add_module_flag_u32 (
337+ llmod,
338+ llvm:: ModuleFlagMergeBehavior :: Override ,
339+ "cf-protection-return" ,
340+ 1 ,
341+ ) ;
368342 }
369343
370344 if sess. opts . unstable_opts . virtual_function_elimination {
371- unsafe {
372- llvm:: LLVMRustAddModuleFlagU32 (
373- llmod,
374- llvm:: LLVMModFlagBehavior :: Error ,
375- c"Virtual Function Elim" . as_ptr ( ) ,
376- 1 ,
377- ) ;
378- }
345+ llvm:: add_module_flag_u32 (
346+ llmod,
347+ llvm:: ModuleFlagMergeBehavior :: Error ,
348+ "Virtual Function Elim" ,
349+ 1 ,
350+ ) ;
379351 }
380352
381353 // Set module flag to enable Windows EHCont Guard (/guard:ehcont).
382354 if sess. opts . unstable_opts . ehcont_guard {
383- unsafe {
384- llvm:: LLVMRustAddModuleFlagU32 (
385- llmod,
386- llvm:: LLVMModFlagBehavior :: Warning ,
387- c"ehcontguard" . as_ptr ( ) as * const _ ,
388- 1 ,
389- )
390- }
355+ llvm:: add_module_flag_u32 ( llmod, llvm:: ModuleFlagMergeBehavior :: Warning , "ehcontguard" , 1 ) ;
391356 }
392357
393358 match sess. opts . unstable_opts . function_return {
394359 FunctionReturn :: Keep => { }
395- FunctionReturn :: ThunkExtern => unsafe {
396- llvm:: LLVMRustAddModuleFlagU32 (
360+ FunctionReturn :: ThunkExtern => {
361+ llvm:: add_module_flag_u32 (
397362 llmod,
398- llvm:: LLVMModFlagBehavior :: Override ,
399- c "function_return_thunk_extern". as_ptr ( ) ,
363+ llvm:: ModuleFlagMergeBehavior :: Override ,
364+ "function_return_thunk_extern" ,
400365 1 ,
401- )
402- } ,
366+ ) ;
367+ }
403368 }
404369
405370 match ( sess. opts . unstable_opts . small_data_threshold , sess. target . small_data_threshold_support ( ) )
406371 {
407372 // Set up the small-data optimization limit for architectures that use
408373 // an LLVM module flag to control this.
409374 ( Some ( threshold) , SmallDataThresholdSupport :: LlvmModuleFlag ( flag) ) => {
410- let flag = SmallCStr :: new ( flag. as_ref ( ) ) ;
411- unsafe {
412- llvm:: LLVMRustAddModuleFlagU32 (
413- llmod,
414- llvm:: LLVMModFlagBehavior :: Error ,
415- flag. as_c_str ( ) . as_ptr ( ) ,
416- threshold as u32 ,
417- )
418- }
375+ llvm:: add_module_flag_u32 (
376+ llmod,
377+ llvm:: ModuleFlagMergeBehavior :: Error ,
378+ & flag,
379+ threshold as u32 ,
380+ ) ;
419381 }
420382 _ => ( ) ,
421383 } ;
@@ -449,33 +411,29 @@ pub(crate) unsafe fn create_module<'ll>(
449411 // If llvm_abiname is empty, emit nothing.
450412 let llvm_abiname = & sess. target . options . llvm_abiname ;
451413 if matches ! ( sess. target. arch. as_ref( ) , "riscv32" | "riscv64" ) && !llvm_abiname. is_empty ( ) {
452- unsafe {
453- llvm:: LLVMRustAddModuleFlagString (
454- llmod,
455- llvm:: LLVMModFlagBehavior :: Error ,
456- c"target-abi" . as_ptr ( ) ,
457- llvm_abiname. as_c_char_ptr ( ) ,
458- llvm_abiname. len ( ) ,
459- ) ;
460- }
414+ llvm:: add_module_flag_str (
415+ llmod,
416+ llvm:: ModuleFlagMergeBehavior :: Error ,
417+ "target-abi" ,
418+ llvm_abiname,
419+ ) ;
461420 }
462421
463422 // Add module flags specified via -Z llvm_module_flag
464- for ( key, value, behavior) in & sess. opts . unstable_opts . llvm_module_flag {
465- let key = format ! ( "{key}\0 " ) ;
466- let behavior = match behavior. as_str ( ) {
467- "error" => llvm:: LLVMModFlagBehavior :: Error ,
468- "warning" => llvm:: LLVMModFlagBehavior :: Warning ,
469- "require" => llvm:: LLVMModFlagBehavior :: Require ,
470- "override" => llvm:: LLVMModFlagBehavior :: Override ,
471- "append" => llvm:: LLVMModFlagBehavior :: Append ,
472- "appendunique" => llvm:: LLVMModFlagBehavior :: AppendUnique ,
473- "max" => llvm:: LLVMModFlagBehavior :: Max ,
474- "min" => llvm:: LLVMModFlagBehavior :: Min ,
423+ for ( key, value, merge_behavior) in & sess. opts . unstable_opts . llvm_module_flag {
424+ let merge_behavior = match merge_behavior. as_str ( ) {
425+ "error" => llvm:: ModuleFlagMergeBehavior :: Error ,
426+ "warning" => llvm:: ModuleFlagMergeBehavior :: Warning ,
427+ "require" => llvm:: ModuleFlagMergeBehavior :: Require ,
428+ "override" => llvm:: ModuleFlagMergeBehavior :: Override ,
429+ "append" => llvm:: ModuleFlagMergeBehavior :: Append ,
430+ "appendunique" => llvm:: ModuleFlagMergeBehavior :: AppendUnique ,
431+ "max" => llvm:: ModuleFlagMergeBehavior :: Max ,
432+ "min" => llvm:: ModuleFlagMergeBehavior :: Min ,
475433 // We already checked this during option parsing
476434 _ => unreachable ! ( ) ,
477435 } ;
478- unsafe { llvm:: LLVMRustAddModuleFlagU32 ( llmod, behavior , key. as_c_char_ptr ( ) , * value) }
436+ llvm:: add_module_flag_u32 ( llmod, merge_behavior , key, * value) ;
479437 }
480438
481439 llmod
0 commit comments