diff options
author | Hans Wennborg <hans@hanshq.net> | 2017-04-21 20:58:12 +0000 |
---|---|---|
committer | Hans Wennborg <hans@hanshq.net> | 2017-04-21 20:58:12 +0000 |
commit | cb3e81071495dd2f63af38f6b50945a47939f9d7 (patch) | |
tree | 7826b28b7b5818fd416502e8c46a184c8188ce39 /llvm/lib/CodeGen | |
parent | 79873efcfb3ae8c4da5f8c6855105a9e496ce1f7 (diff) | |
download | bcm5719-llvm-cb3e81071495dd2f63af38f6b50945a47939f9d7.tar.gz bcm5719-llvm-cb3e81071495dd2f63af38f6b50945a47939f9d7.zip |
X86: Don't emit zero-byte functions on Windows
Empty functions can lead to duplicate entries in the Guard CF Function
Table of a binary due to multiple functions sharing the same RVA,
causing the kernel to refuse to load that binary.
We had a terrific bug due to this in Chromium.
It turns out we were already doing this for Mach-O in certain
situations. This patch expands the code for that in
AsmPrinter::EmitFunctionBody() and renames
TargetInstrInfo::getNoopForMachoTarget() to simply getNoop() since it
seems it was used for not just Mach-O anyway.
Differential Revision: https://reviews.llvm.org/D32330
llvm-svn: 301040
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 16 | ||||
-rw-r--r-- | llvm/lib/CodeGen/TargetInstrInfo.cpp | 4 |
2 files changed, 11 insertions, 9 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 028c79f3ab6..bf2e5818940 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1046,15 +1046,17 @@ void AsmPrinter::EmitFunctionBody() { // If the function is empty and the object file uses .subsections_via_symbols, // then we need to emit *something* to the function body to prevent the // labels from collapsing together. Just emit a noop. - if ((MAI->hasSubsectionsViaSymbols() && !HasAnyRealCode)) { + // Similarly, don't emit empty functions on Windows either. It can lead to + // duplicate entries (two functions with the same RVA) in the Guard CF Table + // after linking, causing the kernel not to load the binary: + // https://developercommunity.visualstudio.com/content/problem/45366/vc-linker-creates-invalid-dll-with-clang-cl.html + // FIXME: Hide this behind some API in e.g. MCAsmInfo or MCTargetStreamer. + if (!HasAnyRealCode && + (MAI->hasSubsectionsViaSymbols() || TM.getTargetTriple().isOSWindows())) { MCInst Noop; - MF->getSubtarget().getInstrInfo()->getNoopForMachoTarget(Noop); + MF->getSubtarget().getInstrInfo()->getNoop(Noop); OutStreamer->AddComment("avoids zero-length function"); - - // Targets can opt-out of emitting the noop here by leaving the opcode - // unspecified. - if (Noop.getOpcode()) - OutStreamer->EmitInstruction(Noop, getSubtargetInfo()); + OutStreamer->EmitInstruction(Noop, getSubtargetInfo()); } const Function *F = MF->getFunction(); diff --git a/llvm/lib/CodeGen/TargetInstrInfo.cpp b/llvm/lib/CodeGen/TargetInstrInfo.cpp index 711144a3474..69b2517e129 100644 --- a/llvm/lib/CodeGen/TargetInstrInfo.cpp +++ b/llvm/lib/CodeGen/TargetInstrInfo.cpp @@ -428,8 +428,8 @@ static const TargetRegisterClass *canFoldCopy(const MachineInstr &MI, return nullptr; } -void TargetInstrInfo::getNoopForMachoTarget(MCInst &NopInst) const { - llvm_unreachable("Not a MachO target"); +void TargetInstrInfo::getNoop(MCInst &NopInst) const { + llvm_unreachable("Not implemented"); } static MachineInstr *foldPatchpoint(MachineFunction &MF, MachineInstr &MI, |