This is an archive of the discontinued LLVM Phabricator instance.

SEH exceptions on Win64 (LLVM)
AbandonedPublic

Authored by yaron.keren on Apr 18 2014, 12:58 AM.

Details

Summary

Patch by Martell Malone, based on Kai Nacke patch from http://wiki.dlang.org/Building_and_hacking_LDC_on_Windows_using_MSVC

See http://reviews.llvm.org/differential/revision/edit/3419/ for the clang part of the patch.

Diff Detail

Event Timeline

Nico Reick comment from e-mail thread:

Unwind emission still suffers from the same problems that the old code
did. It doesn't handle realigned stacks, and as I summarized in PR16779,
I believe it's not necessary to change the prologue emission for Win64.
Currently ilist_node::getPrevNode of MachineInstr is unusable because it
segfaults on the first node in a list. I raised this issue before on
llvm-dev and proposed a patch but nobody cared, so you have to do
something like this:

static const MachineInstr *getPrevNode(const MachineInstr *MI) {
  if (&*MI->getParent()->instr_begin() == MI)
    return nullptr;
  return MI->getPrevNode();
}

Some small nits:

+ if (MI->getOperand(1).getImm() != 1 || MI->getOperand(2).getImm() != 0 ||
+ MI->getOperand(4).getImm() != 0)

Spacing. Also, a comment clarifying that scale/index/segment must be
unused might be helpful here.

+ if (MI->getNextNode()) {
+ const MachineInstr *MI2 = MI->getNextNode();
+ if (!(MI2->getFlag(MachineInstr::FrameSetup) ||
+ (MI2->isCFIInstruction() && MI2->getNextNode() &&
+ MI2->getNextNode()->getFlag(MachineInstr::FrameSetup)))) {
+ OutStreamer.EmitWin64EHEndProlog();
+ }
+ }

I'd simplify this and just skip over all CFI instructions. If there's
still a node left, and it lacks the FrameSetup flag, end the prolog.

+; WIN64: callq {{chkstk|_chkstk_ms}}

This check should really differentiate between MSVC and Mingw. You can
add additional FileCheck prefixes so the rest does not have to be
duplicated.

Overall this needs more tests covering __chkstk, alloca, manual
over-alignment and various combinations.

if (is64Bit && Triple.isWindowsGNUEnvironment())
should be
if (is64Bit && T.isWindowsGNUEnvironment())

yaron.keren updated this revision to Unknown Object (????).Apr 18 2014, 7:15 AM

Updated if (is64Bit && T.isWindowsGNUEnvironment())

Looks like this review thread went silent. What's needed to un-stall it?

Ping... It's been a week since anything happened on this review. Is there any action that can be taken to un-stall this?

Chandler, did Kai address your concern regarding patch authorship?

chandlerc edited edge metadata.Apr 25 2014, 2:36 PM

First, reviews are sometimes slow, sorry. This isn't something I can easily
review, so your best bet is to ping every week or so until a reviewer can
find time.

It also still has the problems that I mentioned about any of the patches
from this project (I mentioned this on the original thread, but none have
responded so I don't know if there is anything to be done there...)

There's been much back-and-forth on the mailing list thread, so I am no longer sure which problems absolutely need to be fixed, and which were mentioned just in passing. It would be helpful to restate them in one place (here probably).

I would really like to see this landing in LLVM master, because some of my work depends on it. If Kai and Martell have their hands full, I'd be happy to take over this patch to address any remaining technical problems with it. Kai, Martell, I assume that's all right with you guys?

Finally, I'd like to make sure that we have the right set of people involved in this review. Who owns this area and can give the final go ahead? According to code_owners.txt that would be Anton, right?

@nrieck, you've said above "I believe it's not necessary to change the prologue emission for Win64". However I don't see how would one express 'and ..., %rsp' with SEH unwind instructions, because the effective RSP offset here is not a compile-time constant.

As far as I understand, DWARF unwind info does not care about the exact number of bytes added to RSP, as long as it can compute the CFA, because that's where RSP is restored from.
SEH, on the other hand, wants to keep track of RSP offset at all times, so the MSVC way of realigning stack seems to be the only way possible.
An extra wrinkle here is that LLVM continues to use RSP for addressing stack variables, even though it had just established frame with RBP. Seems like a bunch of codegen will need to change if we start re-aligning RBP instead.

Am I missing something here?

(the asm code I am referring to is in http://llvm.org/bugs/show_bug.cgi?id=16779)

Kai edited edge metadata.Apr 28 2014, 11:01 PM

@Vadim, Chandler

Regarding the authorship of the code, I responded on llvm-dev. The base part of the code is by Charles Davis. I attach the mail communication how I received the code.


From my point of view, I got the right to further develop this code.

@Vadim
If you like to take ownership of this code please go ahead!

@vadimcn:
You are more than welcome to go ahead with this (pending approval to commit). I don't have a lot of time to devote to this right now.

Everyone:
This was originally my code, but from the looks of it, it's been heavily modified. I don't even recognize some parts of it anymore. I'm passing whatever little ownership over this patch I had left over to whomever will take it (probably @vadimcn, since that's whom Kai blessed).

logan added a subscriber: logan.May 21 2014, 7:20 AM

I ended up with an almost complete rewrite, so positing it as a new review: D4081