[LLVMdev] [PATCH] Seh exceptions on Win64

Nico Rieck nico.rieck at gmail.com
Tue Apr 15 20:53:51 PDT 2014


On 15.04.2014 20:43, Martell Malone wrote:
> Could I get some feedback on this?
> I'm not sure if the emitting of the register names will effect msvc.

Emitting the register names LGTM (in fact GAS doesn't seem to be able to
parse this anyway). Since this is just GAS assembly, this does not
affect MSVC. Some tests would be nice, if possible.

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.


On 15.04.2014 23:44, Vadim Chugunov wrote:
> I am curious - how does clang deal with epilogue-less functions that result
> from _Raise_Exception being marked 'noreturn'?

AFAIK it doesn't emit anything.

> I've also been playing with Kai's patch, and discovered that this tends to
> greatly confuse Windows stack unwinder in cases when noreturn call is at
> the end of a function, so execution appears to flow directly into the
> prologue of the next function.
> It looks like MSVC solves this problem by inserting 'int 3' after calls to
> noreturns.

The unwinder starts scanning forward looking for an optional add or lea,
then zero or more register pops, followed by a ret or a few simple jmp
variants. So you can insert anything except these. Though int3 would
probably make the most sense.

-Nico



More information about the llvm-dev mailing list