Commit Graph

62 Commits

Author SHA1 Message Date
Erik Desjardins
ac9f4f7d0d use attrbuilder to remove attrs in old LLVM 2022-02-26 16:58:45 -05:00
Erik Desjardins
30d3ce0674 Add LLVM attributes in batches instead of individually
This should improve performance.
2022-02-26 13:14:55 -05:00
Matthias Krüger
0bb72a2c66
Rollup merge of #91675 - ivanloz:memtagsan, r=nagisa
Add MemTagSanitizer Support

Add support for the LLVM [MemTagSanitizer](https://llvm.org/docs/MemTagSanitizer.html).

On hardware which supports it (see caveats below), the MemTagSanitizer can catch bugs similar to AddressSanitizer and HardwareAddressSanitizer, but with lower overhead.

On a tag mismatch, a SIGSEGV is signaled with code SEGV_MTESERR / SEGV_MTEAERR.

# Usage

`-Zsanitizer=memtag -C target-feature="+mte"`

# Comments/Caveats

* MemTagSanitizer is only supported on AArch64 targets with hardware support
* Requires `-C target-feature="+mte"`
* LLVM MemTagSanitizer currently only performs stack tagging.

# TODO

* Tests
* Example
2022-02-18 23:23:03 +01:00
Ivan Lozano
568aeda9e9 MemTagSanitizer Support
Adds support for the LLVM MemTagSanitizer.
2022-02-16 09:39:03 -05:00
Augie Fackler
0958c8f4ca llvm: migrate to new parameter-bearing uwtable attr
In https://reviews.llvm.org/D114543 the uwtable attribute gained a flag
so that we can ask for sync uwtables instead of async, as the former are
much cheaper. The default is async, so that's what I've done here, but I
left a TODO that we might be able to do better.

While in here I went ahead and dropped support for removing uwtable
attributes in rustc: we never did it, so I didn't write the extra C++
bridge code to make it work. Maybe I should have done the same thing
with the `sync|async` parameter but we'll see.
2022-02-14 16:09:53 -05:00
Erik Desjardins
8cb0b6ca5b Apply noundef attribute to &T, &mut T, Box<T>, bool
This doesn't handle `char` because it's a bit awkward to distinguish it
from u32 at this point in codegen.

Note that for some types (like `&Struct` and `&mut Struct`),
we already apply `dereferenceable`, which implies `noundef`,
so the IR does not change.
2022-02-05 01:09:52 -05:00
Eric Huss
e1eff1b0e8 Windows: Disable LLVM crash dialog boxes. 2022-01-27 16:53:17 -08:00
Jacob Bramley
e02e9582d2 Use error-on-mismatch policy for PAuth module flags.
This agrees with Clang, and avoids an error when using LTO with mixed
C/Rust. LLVM considers different behaviour flags to be a mismatch,
even when the flag value itself is the same.

This also makes the flag setting explicit for all uses of
LLVMRustAddModuleFlag.
2022-01-24 16:50:10 +00:00
Matthias Krüger
1591dcb659
Rollup merge of #92559 - durin42:llvm-14-attributemask, r=nikic
RustWrapper: adapt to new AttributeMask API

Upstream LLVM change 9290ccc3c1a1 migrated attribute removal to use
AttributeMask instead of AttrBuilder, so we need to follow suit here.

r? ``@nagisa`` cc ``@nikic``
2022-01-06 23:15:18 +01:00
Augie Fackler
34a6b6c423 RustWrapper: simplify removing attributes
Avoids some extra conversions. Spotted by nikic during review.
2022-01-05 13:51:59 -05:00
Augie Fackler
2803fbc447 RustWrapper: adapt to new AttributeMask API
Upstream LLVM change 9290ccc3c1a1 migrated attribute removal to use
AttributeMask instead of AttrBuilder, so we need to follow suit here.
2022-01-04 13:50:02 -05:00
Krasimir Georgiev
4ce56b414d RustWrapper: adapt for an LLVM API change
No functional changes intended.

The LLVM commit
ec501f15a8
removed the signed version of `createExpression`. This adapts the Rust
LLVM wrappers accordingly.
2022-01-03 11:25:33 +01:00
Erik Desjardins
e4463b2453 keep noinline for system llvm < 14 2021-12-30 00:15:51 -05:00
cynecx
91021de1f6 LLVM codgen support for unwinding inline assembly 2021-12-03 23:51:49 +01:00
cynecx
491dd1f387 Adjust llvm wrapper for unwinding support for inlineasm 2021-12-03 23:51:49 +01:00
Matthias Krüger
67762ffe35
Rollup merge of #90833 - tmiasko:optimization-remarks, r=nikic
Emit LLVM optimization remarks when enabled with `-Cremark`

The default diagnostic handler considers all remarks to be disabled by
default unless configured otherwise through LLVM internal flags:
`-pass-remarks`, `-pass-remarks-missed`, and `-pass-remarks-analysis`.
This behaviour makes `-Cremark` ineffective on its own.

Fix this by configuring a custom diagnostic handler that enables
optimization remarks based on the value of `-Cremark` option. With
`-Cremark=all` enabling all remarks.

Fixes #90924.

r? `@nikic`
2021-11-28 23:45:17 +01:00
Benjamin A. Bjørnseth
bb9dee95ed add rustc option for using LLVM stack smash protection
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-22 20:06:22 +01:00
Josh Stone
023cc968e1 Make LLVMRustGetOrInsertGlobal always return a GlobalVariable
`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-19 19:33:29 -08:00
Tomasz Miąsko
8fa45295f4 Recognize machine optimization remarks 2021-11-16 08:19:20 +01:00
Tomasz Miąsko
6846674c75 Emit LLVM optimization remarks when enabled with -Cremark
The default diagnostic handler considers all remarks to be disabled by
default unless configured otherwise through LLVM internal flags:
`-pass-remarks`, `-pass-remarks-missed`, and `-pass-remarks-analysis`.
This behaviour makes `-Cremark` ineffective on its own.

Fix this by configuring a custom diagnostic handler that enables
optimization remarks based on the value of `-Cremark` option. With
`-Cremark=all` enabling all remarks.
2021-11-16 08:19:20 +01:00
Josh Stone
e9f545b9a9 Update the minimum external LLVM to 12 2021-10-22 10:50:07 -07:00
Josh Stone
65150af1b4 Update the minimum external LLVM to 11 2021-10-22 09:22:18 -07:00
Jubilee
6c17601a2e
Rollup merge of #89025 - ricobbe:raw-dylib-link-ordinal, r=michaelwoerister
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-07 20:26:11 -07:00
Krasimir Georgiev
67a82e20cf RustWrapper: adapt for LLVM API change of fatal_error_handler_t
No functional changes intended.

The LLVM commit
e463b69736
changed an argument of fatal_error_handler_t from std::string to char*.
This adapts RustWrapper accordingly.
2021-10-05 16:31:36 +02:00
Richard Cobbe
142f6c0b07 Implement #[link_ordinal] attribute in the context of #[link(kind = "raw-dylib")]. 2021-09-20 14:50:35 -07:00
Augie Fackler
4d045406d1 RustWrapper: remove some uses of AttrBuilder
Turns out we can also use Attribute::get*() methods here, and avoid the
AttrBuilder and an extra helper method here.
2021-09-08 10:47:41 -04:00
Augie Fackler
484b79b950 RustWrapper: just use the *AtIndex funcs directly
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-07 16:15:02 -04:00
Augie Fackler
532bb80f7f RustWrapper: avoid deleted unclear attribute methods
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-09-07 15:30:42 -04:00
Augie Fackler
027db5d036 RustWrapper: adapt to LLVM change 0f45c16f2caa
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-26 10:40:27 -04:00
Nikita Popov
621f5146c3 Handle SrcMgr diagnostics
This is how InlineAsm diagnostics with source information are
reported now. Previously a separate InlineAsm diagnostic handler
was used.
2021-08-16 18:28:17 +02:00
Josh Stone
183d79cc09 Prepare call/invoke for opaque pointers
Rather than relying on `getPointerElementType()` from LLVM function
pointers, we now pass the function type explicitly when building `call`
or `invoke` instructions.
2021-08-05 10:58:55 -07:00
Tomasz Miąsko
8e0df32ad6 Replace LLVMConstInBoundsGEP with LLVMConstInBoundsGEP2*
A custom reimplementation of LLVMConstInBoundsGEP2 is used, since the
LLVM contains a declaration of LLVMConstInBoundsGEP2 but not the
implementation.
2021-08-04 15:51:30 +02:00
Nikita Popov
33e9a6b565 Pass type when creating atomic load
Instead of determining it from the pointer type, explicitly pass
the type to load.
2021-07-09 22:00:19 +02:00
Richard Cobbe
6aa45b71b1 Add first cut of functionality for #58713: support for #[link(kind = "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-04 18:01:35 -07:00
Alex Crichton
0e0338744d rustc: Store metadata-in-rlibs in object files
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-06-04 10:05:20 -07:00
Augie Fackler
fc2a74c640 RustWrapper: work around unification of diagnostic handlers
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-22 15:46:47 -04:00
Simonas Kazlauskas
487e27350a Don't set fast(-math) for certain simd ops
`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-17 23:33:10 +03:00
Simonas Kazlauskas
2f000a78bf Manually set dso_local when its valid to do so
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]: 3001d080c8/clang/lib/CodeGen/CodeGenModule.cpp (L945-L1039)
2021-04-03 00:00:29 +03:00
bors
6e17a5c5fd Auto merge of #83387 - cuviper:min-llvm-10, r=nagisa
Update the minimum external LLVM to 10

r? `@nikic`
2021-03-25 13:11:18 +00:00
Augie Fackler
9431e8577d cleanup: add some comments per review feedback 2021-03-22 14:37:49 -04:00
Josh Stone
7d872f538e Update the minimum external LLVM to 10 2021-03-22 11:33:43 -07:00
Augie Fackler
babe894bab fix: I meant LLVM version 13, not 12 2021-03-19 16:46:40 -04:00
Augie Fackler
0ed1c33ad9 llvm-wrapper: add alignment argument to CreateAtomicCmpXchg
As far as I can tell what we've been getting is llvm::MaybeAlign(), so
just use that for now. This is required sometime after
24539f1ef2471d07bd87f833cb0288fc0f251f4b.
2021-03-16 17:13:13 -04:00
Nikita Popov
bc96516a28 Mark pure asm as willreturn 2021-03-01 23:35:35 +01:00
Nikita Popov
55f345f325 Support LLVM 12 in rustc 2021-02-28 10:19:44 +01:00
Tri Vo
c7d9bffe76 HWASan support 2021-02-07 23:48:58 -08:00
Hugues de Valon
ce9818f2b7 Add a new ABI to support cmse_nonsecure_call
This commit adds a new ABI to be selected via `extern
"C-cmse-nonsecure-call"` on function pointers in order for the compiler to
apply the corresponding cmse_nonsecure_call callsite attribute.
For Armv8-M targets supporting TrustZone-M, this will perform a
non-secure function call by saving, clearing and calling a non-secure
function pointer using the BLXNS instruction.

See the page on the unstable book for details.

Signed-off-by: Hugues de Valon <hugues.devalon@arm.com>
2021-02-02 13:04:31 +00:00
Erik Desjardins
cd25807223 Use probe-stack=inline-asm in LLVM 11+ 2021-01-14 22:49:16 -05:00
Josh Stone
0342fd16ff Remove the unused context from CreateDebugLocation
This went unused in commit 88d874de63, part of #68965.
2021-01-13 11:55:49 -08:00
David Wood
341aa97adb
llvm: update ffi bindings for split dwarf
This commit modifies the FFI bindings to LLVM required for Split DWARF
support in rustc. In particular:

- `addPassesToEmitFile`'s wrapper, `LLVMRustWriteOutputFile` now takes
  a `DwoPath` `const char*`. When disabled, `nullptr` should be provided
  which will preserve existing behaviour. When enabled, the path to the
  `.dwo` file should be provided.
- `createCompileUnit`'s wrapper, `LLVMRustDIBuilderCreateCompileUnit`
  now has two additional arguments, for the `DWOId` and to enable
  `SplitDebugInlining`. `DWOId` should always be zero.
- `createTargetMachine`'s wrapper, `LLVMRustCreateTargetMachine` has an
  additional argument which should be provided the path to the `.dwo`
  when enabled.

Signed-off-by: David Wood <david@davidtw.co>
2020-12-16 10:31:42 +00:00