<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - JIT Compiler generates incorrect SEH x64 RVA addresses in .data section"
   href="https://bugs.llvm.org/show_bug.cgi?id=37178">37178</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>JIT Compiler generates incorrect SEH x64 RVA addresses in .data section
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>new-bugs
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>5.0
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Windows 2000
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>new bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>atlaste@yahoo.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Hi,

This bug is about x64 SEH C++ (CxxFrameHandler3) exceptions using a JIT. We
have these working at the moment, so I'll first discuss the issue and then a
workaround.

Somewhere during the process of generating the LLVM code for catching a SEH
exception, you need to register the type information of the exception you're
going to use. The exception handling itself is done using catchpads, etc.

Relevant here is the type information of the object that you're going to catch,
which will eventually end up in the .data section in the memory manager. The
relevant code can be found below in appendix #1.

During compilation, a function table is generated with the exception handling
data. For each handler in the catch pad, a single handler type entry is
generated with some information. In appendix #2 you'll find a definition of the
structure, which is defined in LLVM using a call to CreateCatchPad.

The issue has to do with the value of pType in this structure. What basically
happens is that the pType will be an RVA, pointing to a .data section. However,
the .data section is emitted first in the JIT, so the RVA address will be 0.
Unfortunately, the value '0' has a special meaning for CxxFrameHandler3, which
corresponds to 'catch everything'. In other words: exception filtering won't
work in the JIT if an RVA of 0 is present -- and the default is to generate RVA
0 for the first typeinfo object.

There's a very simple solution to this problem. If compiling for Windows x64,
allocate 0x10 bytes (alignment) in the memory manager _before_ emitting any
section. That way, it's impossible to generate value RVA 0, which immediately
solves the issue.

The current workaround we use is to simply generate a simple stub type
information object in the JIT. However, this is a nasty, volatile solution,
because the compiler might someday decide to optimize it away. 

Cheers,
Stefan.

--- Appendix #1 ---

        llvm::SmallString<256> MangledName(MangleCXXRTTI);

        // Check to see if we've already declared this TypeDescriptor.
        if (llvm::GlobalVariable *GV = LLVMModule.getNamedGlobal(MangledName))
        {
                return llvm::ConstantExpr::getBitCast(GV,
llvm::Type::getInt8PtrTy(LLVMModule.getContext()));
        }

        // Compute the fields for the TypeDescriptor.
        llvm::SmallString<256> TypeInfoString(MangleCXXRTTIName);

        // Declare and initialize the TypeDescriptor.
        llvm::Constant *Fields[] = {
                getTypeInfoVTable(LLVMModule),                 // VFPtr
               
llvm::ConstantPointerNull::get(llvm::Type::getInt8PtrTy(LLVMModule.getContext())),
// Runtime data
                llvm::ConstantDataArray::getString(LLVMModule.getContext(),
TypeInfoString) };

        llvm::StructType *TypeDescriptorType =
getTypeDescriptorType(LLVMModule.getContext(), TypeInfoString);

        auto *Var = new llvm::GlobalVariable(
                LLVMModule, TypeDescriptorType, /Constant=/false,
                llvm::GlobalValue::LinkOnceODRLinkage,
                llvm::ConstantStruct::get(TypeDescriptorType, Fields),
                MangledName);

        if (Var->isWeakForLinker())
                Var->setComdat(LLVMModule.getOrInsertComdat(Var->getName()));

        return llvm::ConstantExpr::getBitCast(Var,
llvm::Type::getInt8PtrTy(LLVMModule.getContext()));


--- Appendix #2 ---

struct HandlerTypeEntry
{
        uint32_t adjectives;// 0x01: const, 0x02: volatile, 0x08: reference
        uint32_t pType;// RTTI descriptor of the exception type. 0=any
(ellipsis) (RVA ->TypeDescriptor*)
        uint32_t dispCatchObj;// rbp-based offset of the exception object in
the function stack. 0 = no object (catch by type)
        uint32_t addressOfHandler;// address of the catch handler code. returns
address where to continues execution (i.e. code after the try block) (RVA - >
void*)
        uint32_t fpDistance;// Distance Between Handler and Parent frame
pointer (RBP)
};</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>