@@ -210,133 +210,111 @@ pub(crate) unsafe fn create_module<'ll>(
210
210
// If skipping the PLT is enabled, we need to add some module metadata
211
211
// to ensure intrinsic calls don't use it.
212
212
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 ) ;
217
214
}
218
215
219
216
// Enable canonical jump tables if CFI is enabled. (See https://reviews.llvm.org/D65629.)
220
217
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
+ ) ;
230
224
}
231
225
232
226
// If we're normalizing integers with CFI, ensure LLVM generated functions do the same.
233
227
// See https://github.com/llvm/llvm-project/pull/104826
234
228
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
+ ) ;
244
235
}
245
236
246
237
// Enable LTO unit splitting if specified or if CFI is enabled. (See
247
238
// https://reviews.llvm.org/D53891.)
248
239
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
+ ) ;
258
246
}
259
247
260
248
// Add "kcfi" module flag if KCFI is enabled. (See https://reviews.llvm.org/D119296.)
261
249
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 ) ;
266
251
267
252
// Add "kcfi-offset" module flag with -Z patchable-function-entry (See
268
253
// https://reviews.llvm.org/D141172).
269
254
let pfe =
270
255
PatchableFunctionEntry :: from_config ( sess. opts . unstable_opts . patchable_function_entry ) ;
271
256
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
+ ) ;
281
263
}
282
264
}
283
265
284
266
// Control Flow Guard is currently only supported by the MSVC linker on Windows.
285
267
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
+ ) ;
307
287
}
308
288
}
309
289
}
310
290
311
291
if let Some ( BranchProtection { bti, pac_ret } ) = sess. opts . unstable_opts . branch_protection {
312
292
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
+ ) ;
340
318
} else {
341
319
bug ! (
342
320
"branch-protection used on non-AArch64 target; \
@@ -347,75 +325,59 @@ pub(crate) unsafe fn create_module<'ll>(
347
325
348
326
// Pass on the control-flow protection flags to LLVM (equivalent to `-fcf-protection` in Clang).
349
327
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
+ ) ;
358
334
}
359
335
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
+ ) ;
368
342
}
369
343
370
344
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
+ ) ;
379
351
}
380
352
381
353
// Set module flag to enable Windows EHCont Guard (/guard:ehcont).
382
354
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 ) ;
391
356
}
392
357
393
358
match sess. opts . unstable_opts . function_return {
394
359
FunctionReturn :: Keep => { }
395
- FunctionReturn :: ThunkExtern => unsafe {
396
- llvm:: LLVMRustAddModuleFlagU32 (
360
+ FunctionReturn :: ThunkExtern => {
361
+ llvm:: add_module_flag_u32 (
397
362
llmod,
398
- llvm:: LLVMModFlagBehavior :: Override ,
399
- c "function_return_thunk_extern". as_ptr ( ) ,
363
+ llvm:: ModuleFlagMergeBehavior :: Override ,
364
+ "function_return_thunk_extern" ,
400
365
1 ,
401
- )
402
- } ,
366
+ ) ;
367
+ }
403
368
}
404
369
405
370
match ( sess. opts . unstable_opts . small_data_threshold , sess. target . small_data_threshold_support ( ) )
406
371
{
407
372
// Set up the small-data optimization limit for architectures that use
408
373
// an LLVM module flag to control this.
409
374
( 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
+ ) ;
419
381
}
420
382
_ => ( ) ,
421
383
} ;
@@ -449,33 +411,29 @@ pub(crate) unsafe fn create_module<'ll>(
449
411
// If llvm_abiname is empty, emit nothing.
450
412
let llvm_abiname = & sess. target . options . llvm_abiname ;
451
413
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
+ ) ;
461
420
}
462
421
463
422
// 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 ,
475
433
// We already checked this during option parsing
476
434
_ => unreachable ! ( ) ,
477
435
} ;
478
- unsafe { llvm:: LLVMRustAddModuleFlagU32 ( llmod, behavior , key. as_c_char_ptr ( ) , * value) }
436
+ llvm:: add_module_flag_u32 ( llmod, merge_behavior , key, * value) ;
479
437
}
480
438
481
439
llmod
0 commit comments