Commit Graph

88 Commits

Author SHA1 Message Date
Fangrui Song 4b1b9e22b3 Remove unused #include "llvm/ADT/Optional.h" 2022-12-05 04:21:08 +00:00
Fangrui Song f4c16c4473 [MC] llvm::Optional => std::optional
https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-04 21:36:08 +00:00
Kazu Hirata aadaaface2 [llvm] Use std::nullopt instead of None (NFC)
This patch mechanically replaces None with std::nullopt where the
compiler would warn if None were deprecated.  The intent is to reduce
the amount of manual work required in migrating from Optional to
std::optional.

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-02 21:11:44 -08:00
Eli Friedman e65c5eebb8 [AArch64] Make opcode switch in tryARM64PackedUnwind comprehensive.
I don't think compiler-generated code could actually be affected by
this, but better to be thorough.

Differential Revision: https://reviews.llvm.org/D139048
2022-12-01 12:06:31 -08:00
Eli Friedman d98f74a470 [AArch64] Make sure we don't emit packed unwind for .seh_save_any_reg_p
Obvious oversight in implementation in D135417.

Differential Revision: https://reviews.llvm.org/D138955
2022-11-30 13:47:35 -08:00
Guillaume Chatelet 6c09ea3fdd [Alignment][NFC] Use Align in MCStreamer::emitValueToAlignment
Differential Revision: https://reviews.llvm.org/D138674
2022-11-24 16:09:44 +00:00
Eli Friedman d6481dc88c [AArch64][Windows] Add MC support for save_any_reg.
Representing this as 12 separate operations is a bit ugly, but
trying to represent the different modes using a bitfield seemed worse.

Differential Revision: https://reviews.llvm.org/D135417
2022-10-18 11:45:27 -07:00
Martin Storsjö cbd8464595 [MC] [Win64EH] Check that ARM64 prologs and epilogs have the right matching number of instructions
This matches what was done for the ARM implementation (where getting
the instruction sizes right is even more tricky, and hence needed
tighter testing).

This will allow catching any future cases where prologs and epilogs
don't match the instructions within them.

Differential Revision: https://reviews.llvm.org/D131394
2022-10-13 09:47:39 +03:00
Martin Storsjö 918f6f581d [AArch64] [SEH] Rename pac_sign_return_address to pac_sign_lr
This new opcode was initially documented as "pac_sign_return_address"
in https://github.com/MicrosoftDocs/cpp-docs/pull/4202, but was
soon afterwards renamed into "pac_sign_lr" in
https://github.com/MicrosoftDocs/cpp-docs/pull/4209, as the other
name was unwieldy, and there were no other external references to
that name anywhere.

Rename our external .seh assembler directive - it hasn't been merged
for very long yet, so there's probably no external use to account for.

Rename all other internal references to the opcode similarly.

Differential Revision: https://reviews.llvm.org/D135762
2022-10-12 22:19:59 +03:00
Martin Storsjö afa6bb643f [MC] [Win64EH] Generate ARM64 packed unwind info with signed return addresses
Differential Revision: https://reviews.llvm.org/D135660
2022-10-12 11:07:12 +03:00
Martin Storsjö c43bff64e9 [AArch64] Add support for the SEH opcode for return address signing
This was documented upstream in
https://github.com/MicrosoftDocs/cpp-docs/pull/4202.

Differential Revision: https://reviews.llvm.org/D135276
2022-10-12 11:07:11 +03:00
Kazu Hirata fedc59734a [llvm] Use range-based for loops (NFC) 2022-09-03 11:17:40 -07:00
Kazu Hirata 0e9d37ff95 [llvm] Qualify auto in range-based for loops (NFC) 2022-08-28 23:29:00 -07:00
Martin Storsjö 0c52ab3968 [MC] [Win64EH] Fix the calculation of the end of epilogs
Exclude the terminating end opcode from the epilog - it doesn't
correspond to an actual instruction that is included in the epilog
itself (within the .seh_startepilogue/.seh_endepilogue range).

In most (all?) cases, an epilog is followed by a matching terminating
instruction though (a ret or a branch to a tail call), but it's not
strictly within the .seh_startepilogue/.seh_endepilogue range.

This fixes a number of failed asserts in cases where the codegen
has incorrectly reoredered SEH opcodes so they don't match up
exactly with their instructions.

However this still just avoids failing the assertion; the root cause
of generating unexpected epilogs is still present (and fixing that is
a less obvious issue).

Differential Revision: https://reviews.llvm.org/D131393
2022-08-08 23:03:17 +03:00
Fangrui Song de9d80c1c5 [llvm] LLVM_FALLTHROUGH => [[fallthrough]]. NFC
With C++17 there is no Clang pedantic warning or MSVC C5051.
2022-08-08 11:24:15 -07:00
Kazu Hirata e20d210eef [llvm] Qualify auto (NFC)
Identified with readability-qualified-auto.
2022-08-07 23:55:27 -07:00
Zhaoshi Zheng 99e50e5838 [WinEH][ARM64] Split Unwind Info for Fucntions Larger than 1MB
Create function segments and emit unwind info of them.

A segment must be less than 1MB and no prolog or epilog is splitted between two
segments.

This patch should generate correct, though not optimal, unwind info for large
functions. Currently it only generate pacted info (.pdata) only for functions
that are less than 1MB (single-segment functions). This is NFC from before this
patch.

The next step is to enable (.pdata) only unwind info for the first segment or
segments that have neither prolog or epilog in a multi-segment function.

Another future work item is to further split segments that require more than 255
code words or have more than 65535 epilogs.

Reference:
https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling#function-fragments

Differential Revision: https://reviews.llvm.org/D130049
2022-08-05 11:46:41 -07:00
Fangrui Song adf4142f76 [MC] De-capitalize SwitchSection. NFC
Add SwitchSection to return switchSection. The API will be removed soon.
2022-06-10 22:50:55 -07:00
Martin Storsjö 298e9cac92 [MC] [Win64EH] Check that the SEH unwind opcodes match the actual instructions
It's a fairly common issue that the generating code incorrectly marks
instructions as narrow or wide; check that the instruction lengths
add up to the expected value, and error out if it doesn't. This allows
catching code generation bugs.

Also check that prologs and epilogs are properly terminated, to
catch other code generation issues.

Differential Revision: https://reviews.llvm.org/D125647
2022-06-01 11:25:49 +03:00
Martin Storsjö d4022ff331 [MC] [Win64EH] Optimize the ARM unwind info
Use the packed unwind info format if possible; otherwise try to
create a packed epilog.

Differential Revision: https://reviews.llvm.org/D125646
2022-06-01 11:25:49 +03:00
Martin Storsjö 6b75a3523f [ARM] [MC] Add support for writing ARM WinEH unwind info
This includes .seh_* directives for generating it from assembly.
It is designed fairly similarly to the ARM64 handling.

For .seh_handler directives, such as
".seh_handler __C_specific_handler, @except" (which is supported
on x86_64 and aarch64 so far), the "@except" bit doesn't work in
ARM assembly, as '@' is used as a comment character (on all current
platforms).

Allow using '%' instead of '@' for this purpose. This convention
is used by GAS in similar contexts already,
e.g. [1]:

    Note on targets where the @ character is the start of a comment
    (eg ARM) then another character is used instead. For example the
    ARM port uses the % character.

In practice, this unfortunately means that all such .seh_handler
directives will need ifdefs for ARM.

Contrary to ARM64, on ARM, it's quite common that we can't evaluate
e.g. the function length at this point, due to instructions whose
length is finalized later. (Also, inline jump tables end with
a ".p2align 1".)

If unable to to evaluate the function length immediately, emit
it as an MCExpr instead. If we'd implement splitting the unwind
info for a function (which isn't implemented for ARM64 yet either),
we wouldn't know whether we need to split it though.

Avoid calling getFrameIndexOffset() on an unset
FuncInfo.UnwindHelpFrameIdx, to avoid triggering asserts in the
preexisting testcase CodeGen/ARM/Windows/wineh-basic.ll. (Once
MSVC exception handling is fully implemented, those changes
can be reverted.)

[1] https://sourceware.org/binutils/docs/as/Section.html#Section

Differential Revision: https://reviews.llvm.org/D125645
2022-06-01 11:25:48 +03:00
Martin Storsjö e71b07e468 [MC] [Win64EH] Wrap the epilog instructions in a struct. NFC.
For ARM SEH, the epilogs will need a little more associated data than
just the plain list of opcodes.

This is a preparatory refactoring for D125645.

Differential Revision: https://reviews.llvm.org/D125879
2022-06-01 11:25:48 +03:00
Martin Storsjö 924defada9 [MC] [Win64EH] Don't produce packed ARM64 unwind info with homed parameters
There's an inconsistency regarding the epilogs of packed ARM64
unwind info with homed parameters; according to the documentation
(and according to common sense), the epilog wouldn't have a series
of nop instructions matching the stp x0-x7 in the prolog - however
in practice, RtlVirtualUnwind still seems to behave as if the epilog
does have the mirrored nops from the prolog.

In practice, MSVC doesn't seem to produce packed unwind info with
homed parameters, which might be why this inconsistency hasn't
been noticed.

Thus, to play it safe, avoid creating such packed unwind info with
homed parameters. (LLVM's current behaviour matches the current
runtime behaviour of RtlVirtualUnwind, but if it later is bug fixed
to match the documentation, such unwind information would be
incorrect.)

See https://github.com/llvm/llvm-project/issues/54879 for further
discussion on the matter.

Differential Revision: https://reviews.llvm.org/D125876
2022-05-18 20:34:59 +03:00
Martin Storsjö 091a55c16a [MC] [Win64EH] Remove an unused parameter to ARM64EmitUnwindCode. NFC.
Differential Revision: https://reviews.llvm.org/D125878
2022-05-18 20:33:17 +03:00
Martin Storsjö 64a3c63e01 [MC] [Win64EH] Check for matches between epilogs and the prolog on ARM64
This allows sharing opcodes between prolog and epilog even when there
is more than one epilog.

I didn't make any handcrafted special MC level testcases for this (yet
at least), but it does seem to have the expected effect on two existing
CodeGen level testcases.

Differential Revision: https://reviews.llvm.org/D125619
2022-05-17 00:41:39 +03:00
Martin Storsjö cabefea2ec [MC] [Win64EH] Try writing an ARM64 "packed epilog" even if the epilog doesn't share opcodes with the prolog
The "packed epilog" form only implies that the epilog is located
exactly at the end of the function (so the location of the epilog
is implicit from the epilog opcodes), but it doesn't have to share
opcodes with the prolog - as long as the total number of opcode
bytes and the offset to the epilog fit within the bitfields.

This avoids writing a 4 byte epilog scope in many cases. (I haven't
measured how much this shrinks actual xdata sections in practice
though.)

Differential Revision: https://reviews.llvm.org/D125536
2022-05-17 00:41:39 +03:00
Martin Storsjö 490cd14fe6 [MC] [Win64EH] Simplify code using WinEH::Instruction::operator!=. NFC.
operator== and operator!= were added in
1308bb99e0 / D87369, but this existing
codepath wasn't updated to use them.

Also fix the indentation of the enclosed liens.

Differential Revision: https://reviews.llvm.org/D125368
2022-05-12 15:23:04 +03:00
Ilia Diachkov 28a681316f Fix nulltpr typo in comment. NFC
The patch fixes the typo "nulltpr", accidentally found in comments.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D122993
2022-04-04 09:05:06 -07:00
serge-sans-paille ef736a1c39 Cleanup LLVMMC headers
There's a few relevant forward declarations in there that may require downstream
adding explicit includes:

llvm/MC/MCContext.h no longer includes llvm/BinaryFormat/ELF.h, llvm/MC/MCSubtargetInfo.h, llvm/MC/MCTargetOptions.h
llvm/MC/MCObjectStreamer.h no longer include llvm/MC/MCAssembler.h
llvm/MC/MCAssembler.h no longer includes llvm/MC/MCFixup.h, llvm/MC/MCFragment.h

Counting preprocessed lines required to rebuild llvm-project on my setup:
before: 1052436830
after:  1049293745

Which is significant and backs up the change in addition to the usual benefits of
decreasing coupling between headers and compilation units.

Discourse thread: https://discourse.llvm.org/t/include-what-you-use-include-cleanup
Differential Revision: https://reviews.llvm.org/D119244
2022-02-09 11:09:17 +01:00
Kazu Hirata ccdd5bb2c2 [llvm] Use range-based for loops (NFC) 2021-12-09 09:37:29 -08:00
Martin Storsjö ac3edc4c97 [Win64EH] Write .pdata symbol relocations relative to the temporary begin symbol
Previously the relocations pointed at the public user facing,
possibly external symbol.

When the function itself is weak, that symbol may be overridden at
link time, pointing at another strong implementation of the same
function instead. In that case, there's two conflicting pdata entries
pointing at the same address, and the wrong unwind info might end up
used.

Both GCC/binutils and MSVC produce pdata pointing at internal static
symbols. (GCC/binutils point at the .text section just as LLVM does
after this change, MSVC points at special label type symbols with the
type IMAGE_SYM_CLASS_LABEL and names like '$LN4'.)

This fixes unwinding through an overridden "operator new" with a
statically linked C++ library in MinGW mode. (Building libc++ with
-ffunction-sections and linking with --gc-sections might avoid the
issue too.)

This makes the produced object files a little less user friendly
to debug, but with other recent improvements for llvm-readobj, the
unwind info debugging experience should be pretty much the same.

Differential Revision: https://reviews.llvm.org/D109651
2021-09-14 11:05:37 +03:00
Martin Storsjö 6f792041a5 Reapply "[CodeGen] [WinException] Only produce handler data at the end of the function if needed"
This reapplies 36c64af9d7 in updated
form.

Emit the xdata for each function at .seh_endproc. This keeps the
exact same output header order for most code generated by the LLVM
CodeGen layer. (Sections still change order for code built from
assembly where functions lack an explicit .seh_handlerdata
directive, and functions with chained unwind info.)

The practical effect should be that assembly output lacks
superfluous ".seh_handlerdata; .text" pairs at the end of functions
that don't handle exceptions, which allows such functions to use
the AArch64 packed unwind format again.

Differential Revision: https://reviews.llvm.org/D87448
2020-11-23 23:17:03 +02:00
Martin Storsjö f69e090d7d [MC] [Win64EH] Try to generate packed unwind info where possible
In practice, this only gives modest savings (for a 6.5 MB DLL with
230 KB xdata, the xdata sections shrinks by around 2.5 KB); to
gain more, the frame lowering would need to be tweaked to more often
generate frame layouts that match the canonical layouts that can
be written in packed form.

Differential Revision: https://reviews.llvm.org/D87371
2020-09-23 09:03:01 +03:00
Martin Storsjö e6419d320d [MC] [Win64EH] Fix builds with expensive checks enabled
This fixes a failed assert if expensive checks are enabled,
since 1308bb99e0.
2020-09-11 11:17:01 +03:00
Martin Storsjö 1308bb99e0 [MC] [Win64EH] Write packed ARM64 epilogues if possible
This gives a pretty substantial size reduction; for a 6.5 MB
DLL with 300 KB .xdata, the .xdata shrinks by 66 KB.

Differential Revision: https://reviews.llvm.org/D87369
2020-09-11 10:31:04 +03:00
Martin Storsjö 700fbe591a [MC] [Win64EH] Canonicalize ARM64 unwind opcodes
Convert 2-byte opcodes to equivalent 1-byte ones.

Adjust the existing exhaustive testcase to avoid being altered by
the simplification rules (to keep that test exercising all individual
opcodes).

Fix the assembler parser limits for register pairs; for .seh_save_regp
and .seh_save_regp_x, we can allow up to x29, for a x29+x30 pair
(which gets remapped to the UOP_SaveFPLR(X) opcodes), for .seh_save_fregp
and .seh_save_fregpx, allow up to d14+d15.

Not creating .seh_save_next for float register pairs, as the
actual unwinder implementation in current versions of Windows is buggy
for that case.

This gives a minimal but measurable size reduction. (For a 6.5 MB
DLL with 300 KB .xdata, the .xdata shrinks by 48 bytes. The opcode
sequences are padded to a 4 byte boundary, so very small improvements
might not end up mattering directly.)

Differential Revision: https://reviews.llvm.org/D87367
2020-09-11 10:31:04 +03:00
Martin Storsjö f5e2ea9a43 [AArch64] Add asm directives for the remaining SEH unwind codes
Add support in llvm-readobj for displaying them and support in the
asm parsser, AArch64TargetStreamer and MCWin64EH for emitting them.

The directives for the remaining basic opcodes have names that
match the opcode in the documentation.

The directives for custom stack cases, that are named
MSFT_OP_TRAP_FRAME, MSFT_OP_MACHINE_FRAME, MSFT_OP_CONTEXT
and MSFT_OP_CLEAR_UNWOUND_TO_CALL, are given matching assembler
directive names that fit into the rest of the opcode naming;
.seh_trap_frame, .seh_context, .seh_clear_unwound_to_call

The opcode MSFT_OP_MACHINE_FRAME is mapped to the existing
opecode enum UOP_PushMachFrame that is used on x86_64, and also
uses the corresponding existing x86_64 directive name
.seh_pushframe.

Differential Revision: https://reviews.llvm.org/D86889
2020-09-03 11:12:01 +03:00
Martin Storsjö 20f7773bb4 [MC] [Win64EH] Fill in FuncletOrFuncEnd if missing
This can happen e.g. for code that declare .seh_proc/.seh_endproc
in assembly, or for code that use .seh_handlerdata (which triggers
the unwind info to be emitted before the end of the function).

The TextSection field must be made non-const to be able to use it
with Streamer.SwitchSection().

Differential Revision: https://reviews.llvm.org/D86528
2020-08-29 15:15:22 +03:00
Martin Storsjö 37ef743cbf [MC] [Win64EH] Avoid producing malformed xdata records
If there's no unwinding opcodes, omit writing the xdata/pdata records.

Previously, this generated truncated xdata records, and llvm-readobj
would error out when trying to print them.

If writing of an xdata record is forced via the .seh_handlerdata
directive, skip it if there's no info to make a sensible unwind
info structure out of, and clearly error out if such info appeared
later in the process.

Differential Revision: https://reviews.llvm.org/D86527
2020-08-28 09:05:36 +03:00
Fangrui Song 692e0c9648 [MC] Add MCStreamer::emitInt{8,16,32,64}
Similar to AsmPrinter::emitInt{8,16,32,64}.
2020-02-29 09:40:21 -08:00
Fangrui Song 774971030d [MCStreamer] De-capitalize EmitValue EmitIntValue{,InHex} 2020-02-14 23:08:40 -08:00
Fangrui Song 6d2d589b06 [MC] De-capitalize another set of MCStreamer::Emit* functions
Emit{ValueTo,Code}Alignment Emit{DTP,TP,GP}* EmitSymbolValue etc
2020-02-14 19:26:52 -08:00
Eli Friedman 0b61d220c9 [AArch64][Windows] Compute function length correctly in unwind tables.
The primary fix here is to WinException.cpp: we need to exclude jump
tables when computing the length of a function, or else we fail to
correctly compute the length. (We can only compute the number of bytes
consumed by certain assembler directives after the entire file is
parsed. ".p2align" is one of those directives, and is used by jump table
generation.)

The secondary fix, to MCWin64EH, is to make sure we don't silently
miscompile if we hit a similar situation in the future.

It's possible we could extend ARM64EmitUnwindInfo so it allows function
bodies that contain assembler directives, but that's a lot more
complicated; see the FIXME in MCWin64EH.cpp.

Fixes https://bugs.llvm.org/show_bug.cgi?id=41581 .

Differential Revision: https://reviews.llvm.org/D61095

llvm-svn: 359849
2019-05-03 00:10:45 +00:00
Chandler Carruth 2946cd7010 Update the file headers across all of the LLVM projects in the monorepo
to reflect the new license.

We understand that people may be surprised that we're moving the header
entirely to discuss the new license. We checked this carefully with the
Foundation's lawyer and we believe this is the correct approach.

Essentially, all code in the project is now made available by the LLVM
project under our new license, so you will see that the license headers
include that license only. Some of our contributors have contributed
code under our old license, and accordingly, we have retained a copy of
our old license notice in the top-level files in each project and
repository.

llvm-svn: 351636
2019-01-19 08:50:56 +00:00
Sanjin Sijaric eaa421d1f9 Fix the buildbot issue introduced by r351421
The EXPENSIVE_CHECK x86_64 Windows buildbot is failing due to this change. Fix
the map access.

llvm-svn: 351577
2019-01-18 19:34:20 +00:00
Benjamin Kramer bd13c9787f [MC] Remove unused variable
llvm-svn: 351426
2019-01-17 10:25:18 +00:00
Sanjin Sijaric b694030647 [ARM64][Windows] Share unwind codes between epilogues
There are cases where we have multiple epilogues that have the exact same unwind
code sequence.  In that case, the epilogues can share the same unwind codes in
the .xdata section.  This should get us past the assert "SEH unwind data
splitting not yet implemented" in many cases.

We still need to add support for generating multiple .pdata/.xdata sections for
those functions that need to be split into fragments.

Differential Revision: https://reviews.llvm.org/D56813

llvm-svn: 351421
2019-01-17 09:45:17 +00:00
Martin Storsjo df20c666d6 [AArch64] Avoid crashing on .seh directives in assembly
Differential Revision: https://reviews.llvm.org/D55670

llvm-svn: 349549
2018-12-18 22:10:17 +00:00
Eli Friedman ab296670e1 [ARM64] [Windows] Improve error reporting for unsupported SEH unwind.
Use report_fatal_error instead of crashing or miscompiling. (It's
currently easier than it should be to hit this case because we don't
reuse codes across epilogs.)

llvm-svn: 346440
2018-11-08 21:20:52 +00:00
Sanjin Sijaric 96f2ea3dd4 [ARM64][Windows] MCLayer support for exception handling
Add ARM64 unwind codes to MCLayer, as well SEH directives that will be emitted
by the frame lowering patch to follow.  We only emit unwind codes into object
object files for now.

Differential Revision: https://reviews.llvm.org/D50166

llvm-svn: 345450
2018-10-27 06:13:06 +00:00