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