zmodem wrote:

Here's a reproducer:

```
> type \src\temp\a.h
struct S {
  S();
  virtual ~S();
};
S *s();

>type \src\temp\a.cc
#include "a.h"

S::S() {}
S::~S() {}
S *s() { return new S; }

>type \src\temp\b.cc
#include "a.h"

int main() {
  S *arr = new S[5];

  S *tmp = s();
  delete tmp;

  return 0;
}

>build\bin\clang-cl /guard:cf \src\temp\a.cc \src\temp\b.cc && a.exe && echo 
>OKAY
```

(It's supposed to print OKAY, but it crashes instead.)

---

In a.cc we see the vftable and cfg table defined as below. Note that the 
vftable references the vector deleting dtor (`??_ES@@UEAAPEAXI@Z`) which in 
this TU is an alias to the scalar deleting dtor (`??_GS@@UEAAPEAXI@Z`). The CFG 
table (`.gfids$y`) includes the scalar deleting dtor.

```
>build\bin\clang -cc1 -triple x86_64-pc-win32 -S -o - \src\temp\a.cc -cfguard 
>-fno-rtti
...
        .section        .rdata,"dr",discard,"??_7S@@6B@"
        .globl  "??_7S@@6B@"                    # @"??_7S@@6B@"
        .p2align        3, 0x0
"??_7S@@6B@":
        .quad   "??_ES@@UEAAPEAXI@Z"
...
        .weak   "??_ES@@UEAAPEAXI@Z"
        .def    "??_ES@@UEAAPEAXI@Z";
        .scl    2;
        .type   32;
        .endef
"??_ES@@UEAAPEAXI@Z" = "??_GS@@UEAAPEAXI@Z"
...
        .section        .gfids$y,"dr"
        .symidx "??_GS@@UEAAPEAXI@Z"
...
```

In b.cc we emit a real definition of the vector deleting dtor.

```
>build\bin\clang -cc1 -triple x86_64-pc-win32 -S -o - \src\temp\b.cc -cfguard 
>-fno-rtti
...
        .globl  "??_ES@@UEAAPEAXI@Z"            # -- Begin function 
??_ES@@UEAAPEAXI@Z
        .p2align        4
"??_ES@@UEAAPEAXI@Z":                   # @"??_ES@@UEAAPEAXI@Z"
# %bb.0:                                # %entry
        subq    $104, %rsp
...
```

Because the vftable now points to a function (`??_ES@@UEAAPEAXI@Z`) that's not 
in the CFG table (we put `??_GS@@UEAAPEAXI@Z` there), we'll fail the CFG check 
and crash when doing the indirect call.

---

> Otherwise it sounds like there is no support for weak symbols in 
> llvm/lib/CodeGen/AsmPrinter/WinCFGuard.cpp ?

Yeah, or for a weak *alias* at least. I think if it could put the alias itself 
into the table, and not the aliasee, it would work correctly.



https://github.com/llvm/llvm-project/pull/185653
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to