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.
Paths
| Differential D32330
X86: Don't emit zero-byte functions on Windows ClosedPublic Authored by hans on Apr 20 2017, 5:23 PM.
Details Summary 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.
Diff Detail
Event TimelineComment Actions Sounds like a good story :)
// 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. maybe you can do some refactoring there to do the COFF empty function handling as well? Comment Actions What does MSVC do for this? Is MSVC's behavior predicated on /guard:cf? Is it ok to generate empty functions without /guard:cf? Crash on calling an empty function seems like somewhat non-intuitive behavior. Comment Actions
Nice! I'll try that.
I haven't been able to lure MSVC into emitting a zero-byte function. For example, for __declspec(naked) void f() {} they emit an int3. We can't put this behind the /guard:cf flag (in fact, clang-cl doesn't even support it right now), because the problem happens when the linker is invoked with /guard:cf, it builds the guard table even if the compiled code isn't instrumented with control-flow checks. I don't think crashing on calling a zero-byte function is non-intuitive; the function has no ret instruction, so anything could happen. Since Matthias pointed out we already have a function that inserts nops in similar situations, I'm happy to use that instead. I don't know if CFG is a thing on thumbv7-windows, but if we're doing it in the asm printer now, it's easy to just enable for all windows targets.
Comment Actions Renamed getNoopForMachoTarget() to getNoop() and added FIXME. Please take another look. Comment Actions LGTM
This revision is now accepted and ready to land.Apr 21 2017, 1:49 PM
Closed by commit rL301040: X86: Don't emit zero-byte functions on Windows (authored by hans). · Explain WhyApr 21 2017, 2:11 PM This revision was automatically updated to reflect the committed changes.
Revision Contents
Diff 96230 llvm/trunk/include/llvm/Target/TargetInstrInfo.h
llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
llvm/trunk/lib/CodeGen/TargetInstrInfo.cpp
llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.h
llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.cpp
llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.h
llvm/trunk/lib/Target/ARM/ARMInstrInfo.h
llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp
llvm/trunk/lib/Target/ARM/ARMMCInstLower.cpp
llvm/trunk/lib/Target/ARM/Thumb1InstrInfo.h
llvm/trunk/lib/Target/ARM/Thumb1InstrInfo.cpp
llvm/trunk/lib/Target/ARM/Thumb2InstrInfo.h
llvm/trunk/lib/Target/ARM/Thumb2InstrInfo.cpp
llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.h
llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.cpp
llvm/trunk/lib/Target/X86/X86InstrInfo.h
llvm/trunk/lib/Target/X86/X86InstrInfo.cpp
llvm/trunk/test/CodeGen/X86/empty-function.ll
|