[llvm-bugs] [Bug 46358] New: WinException: Off-by-one building IP2state table

via llvm-bugs llvm-bugs at lists.llvm.org
Tue Jun 16 19:39:21 PDT 2020


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

            Bug ID: 46358
           Summary: WinException: Off-by-one building IP2state table
           Product: libraries
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: Backend: X86
          Assignee: unassignedbugs at nondot.org
          Reporter: sneves at dei.uc.pt
                CC: craig.topper at gmail.com, llvm-bugs at lists.llvm.org,
                    llvm-dev at redking.me.uk, spatel+llvm at rotateright.com

Consider the following example C++ code:


#include <cstdio>

int main(int argc, char* argv[]) {
    try {
        try {
            puts(new char[argc]());
        } catch(...) {
            return -2;
        }
    } catch(...) {
        return -1;
    }
}


It doesn't really matter what it does, all it matters is that there are a few
try..catch blocks that don't get elided. Compiling this with `clang-cl.exe -O2
-EHsc /FA /Fatest.asm test.cpp` we get in test.asm

        $ip2state$main:
        .long   .Lfunc_begin0 at IMGREL    # IP
        .long   -1                      # ToState
        .long   .Ltmp0 at IMGREL+1         # IP
        .long   1                       # ToState
        .long   .Ltmp1 at IMGREL+1         # IP
        .long   -1                      # ToState
        .long   "?catch$3@?0?main at 4HA"@IMGREL # IP
        .long   3                       # ToState
        .long   "?catch$4@?0?main at 4HA"@IMGREL # IP
        .long   2                       # ToState

Now, as you can see, both beginning of the try block offsets in there are off
byte a single byte (the +1). I tracked this down to
https://github.com/llvm/llvm-project/blob/50155bcd46428eda1551efe9616f6611b0ef779a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp#L885-L937

In particular, we have

      // Emit an entry indicating that PCs after 'Label' have this EH state.
      IPToStateTable.push_back(std::make_pair(getLabel(ChangeLabel),
StateChange.NewState));

but looking at the definition of getLabel, we see that (unless the target is
Aarch64, for whatever reason) it adds 1 to the address of its argument. The
following diff appears to fix this issue, although I do not know if it's a
proper fix:


diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
index 039867557..b0d48458c 100644
--- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp
@@ -929,7 +929,7 @@ void WinException::computeIP2StateTable(
         ChangeLabel = StateChange.PreviousEndLabel;
       // Emit an entry indicating that PCs after 'Label' have this EH state.
       IPToStateTable.push_back(
-          std::make_pair(getLabel(ChangeLabel), StateChange.NewState));
+          std::make_pair(create32bitRef(ChangeLabel), StateChange.NewState));
       // FIXME: assert that NewState is between CatchLow and CatchHigh.
     }
   }


With this patch, the above output becomes

        $ip2state$main:
        .long   .Lfunc_begin0 at IMGREL    # IP
        .long   -1                      # ToState
        .long   .Ltmp0 at IMGREL           # IP
        .long   1                       # ToState
        .long   .Ltmp1 at IMGREL           # IP
        .long   -1                      # ToState
        .long   "?catch$3@?0?main at 4HA"@IMGREL # IP
        .long   3                       # ToState
        .long   "?catch$4@?0?main at 4HA"@IMGREL # IP
        .long   2                       # ToState

as expected.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200617/10e1f3ad/attachment-0001.html>


More information about the llvm-bugs mailing list