summary refs log tree commit diff
path: root/compiler/rustc_llvm/llvm-wrapper
AgeCommit message (Collapse)AuthorLines
2021-11-22add rustc option for using LLVM stack smash protectionBenjamin A. Bjørnseth-0/+9
LLVM has built-in heuristics for adding stack canaries to functions. These heuristics can be selected with LLVM function attributes. This patch adds a rustc option `-Z stack-protector={none,basic,strong,all}` which controls the use of these attributes. This gives rustc the same stack smash protection support as clang offers through options `-fno-stack-protector`, `-fstack-protector`, `-fstack-protector-strong`, and `-fstack-protector-all`. The protection this can offer is demonstrated in test/ui/abi/stack-protector.rs. This fills a gap in the current list of rustc exploit mitigations (https://doc.rust-lang.org/rustc/exploit-mitigations.html), originally discussed in #15179. Stack smash protection adds runtime overhead and is therefore still off by default, but now users have the option to trade performance for security as they see fit. An example use case is adding Rust code in an existing C/C++ code base compiled with stack smash protection. Without the ability to add stack smash protection to the Rust code, the code base artifacts could be exploitable in ways not possible if the code base remained pure C/C++. Stack smash protection support is present in LLVM for almost all the current tier 1/tier 2 targets: see test/assembly/stack-protector/stack-protector-target-support.rs. The one exception is nvptx64-nvidia-cuda. This patch follows clang's example, and adds a warning message printed if stack smash protection is used with this target (see test/ui/stack-protector/warn-stack-protector-unsupported.rs). Support for tier 3 targets has not been checked. Since the heuristics are applied at the LLVM level, the heuristics are expected to add stack smash protection to a fraction of functions comparable to C/C++. Some experiments demonstrating how Rust code is affected by the different heuristics can be found in test/assembly/stack-protector/stack-protector-heuristics-effect.rs. There is potential for better heuristics using Rust-specific safety information. For example it might be reasonable to skip stack smash protection in functions which transitively only use safe Rust code, or which uses only a subset of functions the user declares safe (such as anything under `std.*`). Such alternative heuristics could be added at a later point. LLVM also offers a "safestack" sanitizer as an alternative way to guard against stack smashing (see #26612). This could possibly also be included as a stack-protection heuristic. An alternative is to add it as a sanitizer (#39699). This is what clang does: safestack is exposed with option `-fsanitize=safe-stack`. The options are only supported by the LLVM backend, but as with other codegen options it is visible in the main codegen option help menu. The heuristic names "basic", "strong", and "all" are hopefully sufficiently generic to be usable in other backends as well. Reviewed-by: Nikita Popov <nikic@php.net> Extra commits during review: - [address-review] make the stack-protector option unstable - [address-review] reduce detail level of stack-protector option help text - [address-review] correct grammar in comment - [address-review] use compiler flag to avoid merging functions in test - [address-review] specify min LLVM version in fortanix stack-protector test Only for Fortanix test, since this target specifically requests the `--x86-experimental-lvi-inline-asm-hardening` flag. - [address-review] specify required LLVM components in stack-protector tests - move stack protector option enum closer to other similar option enums - rustc_interface/tests: sort debug option list in tracking hash test - add an explicit `none` stack-protector option Revert "set LLVM requirements for all stack protector support test revisions" This reverts commit a49b74f92a4e7d701d6f6cf63d207a8aff2e0f68.
2021-11-19Make `LLVMRustGetOrInsertGlobal` always return a `GlobalVariable`Josh Stone-1/+11
`Module::getOrInsertGlobal` returns a `Constant*`, which is a super class of `GlobalVariable`, but if the given type doesn't match an existing declaration, it returns a bitcast of that global instead. This causes UB when we pass that to `LLVMGetVisibility` which unconditionally casts the opaque argument to a `GlobalValue*`. Instead, we can do our own get-or-insert without worrying whether existing types match exactly. It's not relevant when we're just trying to get/set the linkage and visibility, and if types are needed we can bitcast or error nicely from `rustc_codegen_llvm` instead.
2021-11-11PassWrapper: additional sanitizer update to match clangKrasimir Georgiev-1/+0
This happened later in the stream than the other changes, but the fix is overlapping. Fix taken from a55c4ec1cee7683d9095327d9d33e7137ec25292 in LLVM.
2021-11-09Didn't mean to invert this boolean.Augie Fackler-1/+1
2021-11-09rustc_llvm: update PassWrapper for recent LLVMAugie Fackler-6/+9
Now AddressSanitizerOptions is a struct, but at least the change was tiny. r? nikic
2021-11-05Initialize LLVM time trace profiler on each code generation threadTomasz Miąsko-0/+4
In https://reviews.llvm.org/D71059 LLVM 11, the time trace profiler was extended to support multiple threads. `timeTraceProfilerInitialize` creates a thread local profiler instance. When a thread finishes `timeTraceProfilerFinishThread` moves a thread local instance into a global collection of instances. Finally when all codegen work is complete `timeTraceProfilerWrite` writes data from the current thread local instance and the instances in global collection of instances. Previously, the profiler was intialized on a single thread only. Since this thread performs no code generation on its own, the resulting profile was empty. Update LLVM codegen to initialize & finish time trace profiler on each code generation thread.
2021-10-25Rollup merge of #89581 - jblazquez:master, r=Mark-SimulacrumMatthias Krüger-0/+2
Add -Z no-unique-section-names to reduce ELF header bloat. This change adds a new compiler flag that can help reduce the size of ELF binaries that contain many functions. By default, when enabling function sections (which is the default for most targets), the LLVM backend will generate different section names for each function. For example, a function `func` would generate a section called `.text.func`. Normally this is fine because the linker will merge all those sections into a single one in the binary. However, starting with [LLVM 12](https://github.com/llvm/llvm-project/commit/ee5d1a04), the backend will also generate unique section names for exception handling, resulting in thousands of `.gcc_except_table.*` sections ending up in the final binary because some linkers like LLD don't currently merge or strip these EH sections (see discussion [here](https://reviews.llvm.org/D83655)). This can bloat the ELF headers and string table significantly in binaries that contain many functions. The new option is analogous to Clang's `-fno-unique-section-names`, and instructs LLVM to generate the same `.text` and `.gcc_except_table` section for each function, resulting in a smaller final binary. The motivation to add this new option was because we have a binary that ended up with so many ELF sections (over 65,000) that it broke some existing ELF tools, which couldn't handle so many sections. Here's our old binary: ``` $ readelf --sections old.elf | head -1 There are 71746 section headers, starting at offset 0x2a246508: $ readelf --sections old.elf | grep shstrtab [71742] .shstrtab STRTAB 0000000000000000 2977204c ad44bb 00 0 0 1 ``` That's an 11MB+ string table. Here's the new binary using this option: ``` $ readelf --sections new.elf | head -1 There are 43 section headers, starting at offset 0x29143ca8: $ readelf --sections new.elf | grep shstrtab [40] .shstrtab STRTAB 0000000000000000 29143acc 0001db 00 0 0 1 ``` The whole binary size went down by over 20MB, which is quite significant.
2021-10-22Update the minimum external LLVM to 12Josh Stone-98/+2
2021-10-22Update the minimum external LLVM to 11Josh Stone-114/+0
2021-10-18RustWrapper: adapt for an LLVM API changeKrasimir Georgiev-1/+5
No functional changes intended. The LLVM commit https://github.com/llvm/llvm-project/commit/89b57061f7b769e9ea9bf6ed686e284f3e55affe moved TargetRegistry.(h|cpp) from Support to MC. This adapts RustWrapper accordingly.
2021-10-11Add -Z no-unique-section-names to reduce ELF header bloat.Javier Blazquez-0/+2
This change adds a new compiler flag that can help reduce the size of ELF binaries that contain many functions. By default, when enabling function sections (which is the default for most targets), the LLVM backend will generate different section names for each function. For example, a function "func" would generate a section called ".text.func". Normally this is fine because the linker will merge all those sections into a single one in the binary. However, starting with LLVM 12 (llvm/llvm-project@ee5d1a0), the backend will also generate unique section names for exception handling, resulting in thousands of ".gcc_except_table.*" sections ending up in the final binary because some linkers don't currently merge or strip these EH sections. This can bloat the ELF headers and string table significantly in binaries that contain many functions. The new option is analogous to Clang's -fno-unique-section-names, and instructs LLVM to generate the same ".text" and ".gcc_except_table" section for each function, resulting in smaller object files and potentially a smaller final binary.
2021-10-07Rollup merge of #89025 - ricobbe:raw-dylib-link-ordinal, r=michaelwoeristerJubilee-4/+7
Implement `#[link_ordinal(n)]` Allows the use of `#[link_ordinal(n)]` with `#[link(kind = "raw-dylib")]`, allowing Rust to link against DLLs that export symbols by ordinal rather than by name. As long as the ordinal matches, the name of the function in Rust is not required to match the name of the corresponding function in the exporting DLL. Part of #58713.
2021-10-07Rollup merge of #87918 - mikebenfield:pr-afdo, r=nikicJubilee-9/+21
Enable AutoFDO. This largely involves implementing the options debug-info-for-profiling and profile-sample-use and forwarding them on to LLVM. AutoFDO can be used on x86-64 Linux like this: rustc -O -Clink-arg='Wl,--no-rosegment' -Cdebug-info-for-profiling main.rs -o main perf record -b ./main create_llvm_prof --binary=main --out=code.prof rustc -O -Cprofile-sample-use=code.prof main.rs -o main2 Now `main2` will have feedback directed optimization applied to it. The create_llvm_prof tool can be obtained from this github repository: https://github.com/google/autofdo The option -Clink-arg='Wl,--no-rosegment' is necessary to avoid lld putting an extra RO segment before the executable code, which would make the binary silently incompatible with create_llvm_prof.
2021-10-06Enable AutoFDO.Michael Benfield-9/+21
This largely involves implementing the options debug-info-for-profiling and profile-sample-use and forwarding them on to LLVM. AutoFDO can be used on x86-64 Linux like this: rustc -O -Cdebug-info-for-profiling main.rs -o main perf record -b ./main create_llvm_prof --binary=main --out=code.prof rustc -O -Cprofile-sample-use=code.prof main.rs -o main2 Now `main2` will have feedback directed optimization applied to it. The create_llvm_prof tool can be obtained from this github repository: https://github.com/google/autofdo Fixes #64892.
2021-10-05RustWrapper: adapt for LLVM API change of fatal_error_handler_tKrasimir Georgiev-0/+4
No functional changes intended. The LLVM commit https://github.com/llvm/llvm-project/commit/e463b69736da8b0a950ecd937cf990401bdfcdeb changed an argument of fatal_error_handler_t from std::string to char*. This adapts RustWrapper accordingly.
2021-09-27PassWrapper: handle function rename from upstream D36850Augie Fackler-0/+4
thinLTOResolvePrevailingInModule became thinLTOFinalizeInModule and gained the ability to propagate noRecurse and noUnwind function attributes. I ran codegen tests with it both on and off, as the upstream patch uses it in both modes, and the tests pass both ways. Given that, it seemed reasonable to go ahead and let the propagation be enabled in rustc, and see what happens. See https://reviews.llvm.org/D36850 for more examples of how the new version of the function gets used.
2021-09-25Use correct pipeline for LTO at O0Nikita Popov-1/+4
Unlike the pre-link piplines, the LTO pipelines do support O0, and using them is required to avoid leaving behind undefined references for the linker.
2021-09-22Rollup merge of #89041 - sticnarf:sticnarf/fat-lto-dwarf, r=nagisathe8472-2/+2
Work around invalid DWARF bugs for fat LTO This PR applies the same workaround in #46772 to fat LTO. It seems to fix the bug reported in https://github.com/rust-lang/rust/issues/66118#issuecomment-917434036.
2021-09-20Implement #[link_ordinal] attribute in the context of #[link(kind = ↵Richard Cobbe-4/+7
"raw-dylib")].
2021-09-17Work around invalid DWARF bugs for fat LTOYilin Chen-2/+2
Signed-off-by: Yilin Chen <sticnarf@gmail.com>
2021-09-17compiler/rustc_llvm: Enable M68k LLVM targetJohn Paul Adrian Glaubitz-0/+7
2021-09-16PassWrapper: these two lines shouldn't have been ifdef'dAugie Fackler-2/+2
2021-09-16PassWrapper: handle separate Module*SanitizerPassAugie Fackler-0/+8
Change ab41eef9aca3 in LLVM split MemorySanitizerPass into MemorySanitizerPass for functions and ModuleMemorySanitizerPass for modules. There's a related change for ThreadSanitizerPass, and in here since we're using a ModulePassManager I only add the module flavor of the pass on LLVM 14. r? @nikic cc @nagisa
2021-09-08RustWrapper: remove some uses of AttrBuilderAugie Fackler-19/+6
Turns out we can also use Attribute::get*() methods here, and avoid the AttrBuilder and an extra helper method here.
2021-09-07RustWrapper: just use the *AtIndex funcs directlyAugie Fackler-36/+3
Otherwise we're kind of reimplementing the inverse of the well-named methods, and that's not a direction we want to go.
2021-09-07RustWrapper: avoid deleted unclear attribute methodsAugie Fackler-18/+70
These were deleted in https://reviews.llvm.org/D108614, and in C++ I definitely see the argument for their removal. I didn't try and propagate the changes up into higher layers of rustc in this change because my initial goal was to get rustc working against LLVM HEAD promptly, but I'm happy to follow up with some refactoring to make the API on the Rust side match the LLVM API more directly (though the way the enum works in Rust makes the API less scary IMO). r? @nagisa cc @nikic
2021-08-26RustWrapper: adapt to LLVM change 0f45c16f2caaAugie Fackler-14/+9
The above-mentioned commit (part of the LLVM 14 development cycle) removes a method that rustc uses somewhat extensively. We mostly switch to lower-level methods that exist in all versions of LLVM we use, so no new ifdef logic is required in most cases.
2021-08-22Rollup merge of #88164 - durin42:llvm-14-san-opts, r=nikicGuillaume Gomez-0/+15
PassWrapper: adapt for LLVM 14 changes These API changes appear to have all taken place in https://reviews.llvm.org/D105007, which moved HWAddressSanitizerPass and AddressSanitizerPass to only accept their options type as a ctor argument instead of the sequence of bools etc. This required a couple of parameter additions, which I made match the default prior to the mentioned upstream LLVM change. This patch restores rustc to building (though not quite passing all tests, I've mailed other patches for those issues) against LLVM HEAD.
2021-08-19PassWrapper: adapt for LLVM 14 changesAugie Fackler-0/+15
These API changes appear to have all taken place in https://reviews.llvm.org/D105007, which moved HWAddressSanitizerPass and AddressSanitizerPass to only accept their options type as a ctor argument instead of the sequence of bools etc. This required a couple of parameter additions, which I made match the default prior to the mentioned upstream LLVM change. This patch restores rustc to building (though not quite passing all tests, I've mailed other patches for those issues) against LLVM HEAD.
2021-08-16Handle SrcMgr diagnosticsNikita Popov-3/+17
This is how InlineAsm diagnostics with source information are reported now. Previously a separate InlineAsm diagnostic handler was used.
2021-08-08Auto merge of #87798 - durin42:llvm-14, r=nikicbors-27/+31
PassWrapper: handle move of OptimizationLevel class out of PassBuilder This is the first build break of the LLVM 14 cycle, and was caused by https://reviews.llvm.org/D107025. Mercifully an easy fix.
2021-08-06PassWrapper: handle move of OptimizationLevel class out of PassBuilderAugie Fackler-27/+31
This is the first build break of the LLVM 14 cycle, and was caused by https://reviews.llvm.org/D107025. Mercifully an easy fix.
2021-08-05Prepare call/invoke for opaque pointersJosh Stone-7/+7
Rather than relying on `getPointerElementType()` from LLVM function pointers, we now pass the function type explicitly when building `call` or `invoke` instructions.
2021-08-04Replace LLVMConstInBoundsGEP with LLVMConstInBoundsGEP2*Tomasz Miąsko-0/+10
A custom reimplementation of LLVMConstInBoundsGEP2 is used, since the LLVM contains a declaration of LLVMConstInBoundsGEP2 but not the implementation.
2021-07-09Pass type when creating atomic loadNikita Popov-4/+3
Instead of determining it from the pointer type, explicitly pass the type to load.
2021-06-04Add first cut of functionality for #58713: support for #[link(kind = ↵Richard Cobbe-0/+52
"raw-dylib")]. This does not yet support #[link_name] attributes on functions, the #[link_ordinal] attribute, #[link(kind = "raw-dylib")] on extern blocks in bin crates, or stdcall functions on 32-bit x86.
2021-06-04rustc: Store metadata-in-rlibs in object filesAlex Crichton-35/+0
This commit updates how rustc compiler metadata is stored in rlibs. Previously metadata was stored as a raw file that has the same format as `--emit metadata`. After this commit, however, the metadata is encoded into a small object file which has one section which is the contents of the metadata. The motivation for this commit is to fix a common case where #83730 arises. The problem is that when rustc crates a `dylib` crate type it needs to include entire rlib files into the dylib, so it passes `--whole-archive` (or the equivalent) to the linker. The problem with this, though, is that the linker will attempt to read all files in the archive. If the metadata file were left as-is (today) then the linker would generate an error saying it can't read the file. The previous solution was to alter the rlib just before linking, creating a new archive in a temporary directory which has the metadata file removed. This problem from before this commit is now removed if the metadata file is stored in an object file that the linker can read. The only caveat we have to take care of is to ensure that the linker never actually includes the contents of the object file into the final output. We apply similar tricks as the `.llvmbc` bytecode sections to do this. This involved changing the metadata loading code a bit, namely updating some of the LLVM C APIs used to use non-deprecated ones and fiddling with the lifetimes a bit to get everything to work out. Otherwise though this isn't intended to be a functional change really, only that metadata is stored differently in archives now. This should end up fixing #83730 because by default dylibs will no longer have their rlib dependencies "altered" meaning that split-debuginfo will continue to have valid paths pointing at the original rlibs. (note that we still "alter" rlibs if LTO is enabled to remove Rust object files and we also "alter" for the #[link(cfg)] feature, but that's rarely used). Closes #83730
2021-05-21Auto merge of #85416 - durin42:llvm-catchup-may-2021, r=nagisabors-1/+12
PassWrapper: update for LLVM change D102093 In https://reviews.llvm.org/D102093 lots of things stopped taking the DebugLogging boolean parameter. Mercifully we appear to always set DebugPassManager to false, so I don't think we're losing anything by not passing this parameter.
2021-05-17PassWrapper: update for LLVM change D102093Augie Fackler-1/+12
In https://reviews.llvm.org/D102093 lots of things stopped taking the DebugLogging boolean parameter. Mercifully we appear to always set DebugPassManager to false, so I don't think we're losing anything by not passing this parameter.
2021-05-08Support -C passes in NewPMNikita Popov-2/+12
And report an error if parsing the additional pass pipeline fails. Threading through the error accounts for most of the changes here.
2021-05-08Explicitly register GCOV profiling pass as wellNikita Popov-1/+11
2021-05-08Explicitly register instrprof passNikita Popov-1/+11
Don't use "passes" for this purpose, explicitly insert it into the correct place in the pipeline instead.
2021-04-29Replace llvm::sys::fs::F_None with llvm::sys::fs::OF_NoneFangrui Song-3/+3
The former is deprecated. OF_None has been available in LLVM since 2018-06.
2021-04-22RustWrapper: work around unification of diagnostic handlersAugie Fackler-1/+11
This lets me build against llvm/main as of March 23rd, 2021. I'm not entirely sure this is _correct_, but it appears to be functionally identical to what was done in LLVM: existing callsites of setInlineAsmDiagnosticHandler were moved to SetDiagnosticHandler() on the context object, which we already set up in both places that we called setInlineAsmDiagnosticHandler().
2021-04-17Don't set `fast`(-math) for certain simd opsSimonas Kazlauskas-2/+4
`fast-math` implies things like functions not being able to accept as an argument or return as a result, say, `inf` which made these functions confusingly named or behaving incorrectly, depending on how you interpret it. Since the time when these intrinsics have been implemented the intrinsics user's (stdsimd) approach has changed significantly and so now it is required that these intrinsics operate normally rather than in "whatever" way. Fixes #84268
2021-04-09Categorize and explain target features supportMatt Ickstadt-18/+15
2021-04-03Manually set dso_local when its valid to do soSimonas Kazlauskas-0/+4
This should have no real effect in most cases, as e.g. `hidden` visibility already implies `dso_local` (or at least LLVM IR does not preserve the `dso_local` setting if the item is already `hidden`), but it should fix `-Crelocation-model=static` and improve codegen in executables. Note that this PR does not exhaustively port the logic in [clang]. Only the obviously correct portion and what is necessary to fix a regression from LLVM 12 that relates to `-Crelocation_model=static`. Fixes #83335 [clang]: https://github.com/llvm/llvm-project/blob/3001d080c813da20b329303bf8f45451480e5905/clang/lib/CodeGen/CodeGenModule.cpp#L945-L1039
2021-03-25Auto merge of #83387 - cuviper:min-llvm-10, r=nagisabors-83/+0
Update the minimum external LLVM to 10 r? `@nikic`
2021-03-24LLVMWrapper: attractive nuisance macrosAugie Fackler-7/+0
THis came up in the review of #83425: it's hard to imagine a use of LLVM_VERSION_LE() or LLVM_VERSION_EQ() that's not asking for trouble when a point release gets created, so let's just discard them to prevent the issue.
2021-03-22cleanup: add some comments per review feedbackAugie Fackler-0/+6