Here is a very simple file in c++

class C {
public:
    C(){}
    ~C(){}
};

void g()
{
    throw std::exception();
}

void f()
{
    C c;
    g();
}

int main()
{
    return 0;
}

LLVM produces the following (please note the comment I've added, explaining my query).

00000000004044e0 <f()>:

  4044e0: 48 83 ec 18                   subq    $24, %rsp
  4044e4: 48 8d 7c 24 10                leaq    16(%rsp), %rdi
  4044e9: e8 52 00 00 00                callq   0x404540 <C::C()>
  4044ee: e8 6d 00 00 00                callq   0x404560 <g()>
  4044f3: e9 00 00 00 00                jmp 0x4044f8 <f()+0x18>
  4044f8: 48 8d 7c 24 10                leaq    16(%rsp), %rdi
  4044fd: e8 4e 00 00 00                callq   0x404550 <C::~C()>
  404502: 48 83 c4 18                   addq    $24, %rsp
  404506: c3                            retq


; Is this the alternative entry point? How does the unwiding mechanism (__cxa_throw()) reach here?
; Also, when reached here by __cxa_throw, %rax seems to point to an instant of struct _Unwind_Exception,
;which is saved on the stack, and later used as the 1st argument to _Unwind_resume?
; And what is %edx (presumably an int, set by the unwinding mechanism), which is unused here in this frame?
  404507: 48 89 c1                      movq    %rax, %rcx
  40450a: 89 d0                         movl    %edx, %eax
  40450c: 48 89 4c 24 08                movq    %rcx, 8(%rsp)
  404511: 89 44 24 04                   movl    %eax, 4(%rsp)
  404515: 48 8d 7c 24 10                leaq    16(%rsp), %rdi
  40451a: e8 31 00 00 00                callq   0x404550 <C::~C()>
  40451f: 48 8b 7c 24 08                movq    8(%rsp), %rdi
  404524: e8 37 51 0a 00                callq   0x4a9660 <_Unwind_Resume>
  404529: 0f 1f 80 00 00 00 00          nopl    (%rax)

Quoting from llvm-documentaion:

The term used to define the place where an invoke continues after an exception is called a landing pad. LLVM landing pads are conceptually alternative function entry points (emphasis added) where an exception structure reference and a type info index are passed in as arguments. The landing pad saves the exception structure reference and then proceeds to select the catch block that corresponds to the type info of the exception object.

The LLVM ‘landingpad’ Instruction is used to convey information about the landing pad to the back end. For C++, the landingpad instruction returns a pointer and integer pair corresponding to the pointer to the exception structure and the selector value respectively.

The landingpad instruction looks for a reference to the personality function to be used for this try/catch sequence in the parent function’s attribute list. The instruction contains a list of cleanup, catch, and filter clauses.

Any explanation of the above would be much appreciated.

Thanks

0

There are 0 best solutions below