@@ -950,6 +950,29 @@ pub(crate) unsafe fn codegen(
950
950
) )
951
951
}
952
952
953
+ fn create_section_with_flags_asm ( section_name : & str , section_flags : & str , data : & [ u8 ] ) -> Vec < u8 > {
954
+ let mut asm = format ! ( ".section {},\" {}\" \n " , section_name, section_flags) . into_bytes ( ) ;
955
+ asm. extend_from_slice ( b".ascii \" " ) ;
956
+ asm. reserve ( data. len ( ) ) ;
957
+ for & byte in data {
958
+ if byte == b'\\' || byte == b'"' {
959
+ asm. push ( b'\\' ) ;
960
+ asm. push ( byte) ;
961
+ } else if byte < 0x20 || byte >= 0x80 {
962
+ // Avoid non UTF-8 inline assembly. Use octal escape sequence, because it is fixed
963
+ // width, while hex escapes will consume following characters.
964
+ asm. push ( b'\\' ) ;
965
+ asm. push ( b'0' + ( ( byte >> 6 ) & 0x7 ) ) ;
966
+ asm. push ( b'0' + ( ( byte >> 3 ) & 0x7 ) ) ;
967
+ asm. push ( b'0' + ( ( byte >> 0 ) & 0x7 ) ) ;
968
+ } else {
969
+ asm. push ( byte) ;
970
+ }
971
+ }
972
+ asm. extend_from_slice ( b"\" \n " ) ;
973
+ asm
974
+ }
975
+
953
976
/// Embed the bitcode of an LLVM module in the LLVM module itself.
954
977
///
955
978
/// This is done primarily for iOS where it appears to be standard to compile C
@@ -975,34 +998,6 @@ unsafe fn embed_bitcode(
975
998
cmdline : & str ,
976
999
bitcode : & [ u8 ] ,
977
1000
) {
978
- let llconst = common:: bytes_in_context ( llcx, bitcode) ;
979
- let llglobal = llvm:: LLVMAddGlobal (
980
- llmod,
981
- common:: val_ty ( llconst) ,
982
- "rustc.embedded.module\0 " . as_ptr ( ) . cast ( ) ,
983
- ) ;
984
- llvm:: LLVMSetInitializer ( llglobal, llconst) ;
985
-
986
- let is_apple = cgcx. opts . target_triple . triple ( ) . contains ( "-ios" )
987
- || cgcx. opts . target_triple . triple ( ) . contains ( "-darwin" )
988
- || cgcx. opts . target_triple . triple ( ) . contains ( "-tvos" ) ;
989
-
990
- let section = if is_apple { "__LLVM,__bitcode\0 " } else { ".llvmbc\0 " } ;
991
- llvm:: LLVMSetSection ( llglobal, section. as_ptr ( ) . cast ( ) ) ;
992
- llvm:: LLVMRustSetLinkage ( llglobal, llvm:: Linkage :: PrivateLinkage ) ;
993
- llvm:: LLVMSetGlobalConstant ( llglobal, llvm:: True ) ;
994
-
995
- let llconst = common:: bytes_in_context ( llcx, cmdline. as_bytes ( ) ) ;
996
- let llglobal = llvm:: LLVMAddGlobal (
997
- llmod,
998
- common:: val_ty ( llconst) ,
999
- "rustc.embedded.cmdline\0 " . as_ptr ( ) . cast ( ) ,
1000
- ) ;
1001
- llvm:: LLVMSetInitializer ( llglobal, llconst) ;
1002
- let section = if is_apple { "__LLVM,__cmdline\0 " } else { ".llvmcmd\0 " } ;
1003
- llvm:: LLVMSetSection ( llglobal, section. as_ptr ( ) . cast ( ) ) ;
1004
- llvm:: LLVMRustSetLinkage ( llglobal, llvm:: Linkage :: PrivateLinkage ) ;
1005
-
1006
1001
// We're adding custom sections to the output object file, but we definitely
1007
1002
// do not want these custom sections to make their way into the final linked
1008
1003
// executable. The purpose of these custom sections is for tooling
@@ -1024,31 +1019,54 @@ unsafe fn embed_bitcode(
1024
1019
// * COFF - if we don't do anything the linker will by default copy all
1025
1020
// these sections to the output artifact, not what we want! To subvert
1026
1021
// this we want to flag the sections we inserted here as
1027
- // `IMAGE_SCN_LNK_REMOVE`. Unfortunately though LLVM has no native way to
1028
- // do this. Thankfully though we can do this with some inline assembly,
1029
- // which is easy enough to add via module-level global inline asm.
1022
+ // `IMAGE_SCN_LNK_REMOVE`.
1030
1023
//
1031
1024
// * ELF - this is very similar to COFF above. One difference is that these
1032
1025
// sections are removed from the output linked artifact when
1033
1026
// `--gc-sections` is passed, which we pass by default. If that flag isn't
1034
1027
// passed though then these sections will show up in the final output.
1035
1028
// Additionally the flag that we need to set here is `SHF_EXCLUDE`.
1029
+ //
1030
+ // Unfortunately, LLVM provides no way to set custom section flags. For ELF
1031
+ // and COFF we emit the sections using module level inline assembly for that
1032
+ // reason (see issue #90326 for historical background).
1033
+ let is_apple = cgcx. opts . target_triple . triple ( ) . contains ( "-ios" )
1034
+ || cgcx. opts . target_triple . triple ( ) . contains ( "-darwin" )
1035
+ || cgcx. opts . target_triple . triple ( ) . contains ( "-tvos" ) ;
1036
1036
if is_apple
1037
1037
|| cgcx. opts . target_triple . triple ( ) . starts_with ( "wasm" )
1038
1038
|| cgcx. opts . target_triple . triple ( ) . starts_with ( "asmjs" )
1039
1039
{
1040
- // nothing to do here
1041
- } else if cgcx. is_pe_coff {
1042
- let asm = "
1043
- .section .llvmbc,\" n\"
1044
- .section .llvmcmd,\" n\"
1045
- " ;
1046
- llvm:: LLVMRustAppendModuleInlineAsm ( llmod, asm. as_ptr ( ) . cast ( ) , asm. len ( ) ) ;
1040
+ // We don't need custom section flags, create LLVM globals.
1041
+ let llconst = common:: bytes_in_context ( llcx, bitcode) ;
1042
+ let llglobal = llvm:: LLVMAddGlobal (
1043
+ llmod,
1044
+ common:: val_ty ( llconst) ,
1045
+ "rustc.embedded.module\0 " . as_ptr ( ) . cast ( ) ,
1046
+ ) ;
1047
+ llvm:: LLVMSetInitializer ( llglobal, llconst) ;
1048
+
1049
+ let section = if is_apple { "__LLVM,__bitcode\0 " } else { ".llvmbc\0 " } ;
1050
+ llvm:: LLVMSetSection ( llglobal, section. as_ptr ( ) . cast ( ) ) ;
1051
+ llvm:: LLVMRustSetLinkage ( llglobal, llvm:: Linkage :: PrivateLinkage ) ;
1052
+ llvm:: LLVMSetGlobalConstant ( llglobal, llvm:: True ) ;
1053
+
1054
+ let llconst = common:: bytes_in_context ( llcx, cmdline. as_bytes ( ) ) ;
1055
+ let llglobal = llvm:: LLVMAddGlobal (
1056
+ llmod,
1057
+ common:: val_ty ( llconst) ,
1058
+ "rustc.embedded.cmdline\0 " . as_ptr ( ) . cast ( ) ,
1059
+ ) ;
1060
+ llvm:: LLVMSetInitializer ( llglobal, llconst) ;
1061
+ let section = if is_apple { "__LLVM,__cmdline\0 " } else { ".llvmcmd\0 " } ;
1062
+ llvm:: LLVMSetSection ( llglobal, section. as_ptr ( ) . cast ( ) ) ;
1063
+ llvm:: LLVMRustSetLinkage ( llglobal, llvm:: Linkage :: PrivateLinkage ) ;
1047
1064
} else {
1048
- let asm = "
1049
- .section .llvmbc,\" e\"
1050
- .section .llvmcmd,\" e\"
1051
- " ;
1065
+ // We need custom section flags, so emit module-level inline assembly.
1066
+ let section_flags = if cgcx. is_pe_coff { "n" } else { "e" } ;
1067
+ let asm = create_section_with_flags_asm ( ".llvmbc" , section_flags, bitcode) ;
1068
+ llvm:: LLVMRustAppendModuleInlineAsm ( llmod, asm. as_ptr ( ) . cast ( ) , asm. len ( ) ) ;
1069
+ let asm = create_section_with_flags_asm ( ".llvmcmd" , section_flags, cmdline. as_bytes ( ) ) ;
1052
1070
llvm:: LLVMRustAppendModuleInlineAsm ( llmod, asm. as_ptr ( ) . cast ( ) , asm. len ( ) ) ;
1053
1071
}
1054
1072
}
0 commit comments