diff options
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index e7a7ca79e33..3516f4a7b37 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -706,6 +706,21 @@ void AsmPrinter::EmitFunctionHeader() { } } + // Emit M NOPs for -fpatchable-function-entry=N,M where M>0. We arbitrarily + // place prefix data before NOPs. + unsigned PatchableFunctionPrefix = 0; + (void)F.getFnAttribute("patchable-function-prefix") + .getValueAsString() + .getAsInteger(10, PatchableFunctionPrefix); + if (PatchableFunctionPrefix) { + CurrentPatchableFunctionEntrySym = + OutContext.createLinkerPrivateTempSymbol(); + OutStreamer->EmitLabel(CurrentPatchableFunctionEntrySym); + emitNops(PatchableFunctionPrefix); + } else { + CurrentPatchableFunctionEntrySym = CurrentFnBegin; + } + // Emit the function descriptor. This is a virtual function to allow targets // to emit their specific function descriptor. if (MAI->needsFunctionDescriptors()) @@ -1167,7 +1182,7 @@ void AsmPrinter::EmitFunctionBody() { // unspecified. if (Noop.getOpcode()) { OutStreamer->AddComment("avoids zero-length function"); - OutStreamer->EmitInstruction(Noop, getSubtargetInfo()); + emitNops(1); } } @@ -2797,6 +2812,13 @@ void AsmPrinter::printOffset(int64_t Offset, raw_ostream &OS) const { OS << Offset; } +void AsmPrinter::emitNops(unsigned N) { + MCInst Nop; + MF->getSubtarget().getInstrInfo()->getNoop(Nop); + for (; N; --N) + EmitToStreamer(*OutStreamer, Nop); +} + //===----------------------------------------------------------------------===// // Symbol Lowering Routines. //===----------------------------------------------------------------------===// @@ -3199,11 +3221,14 @@ void AsmPrinter::recordSled(MCSymbol *Sled, const MachineInstr &MI, void AsmPrinter::emitPatchableFunctionEntries() { const Function &F = MF->getFunction(); - unsigned PatchableFunctionEntry = 0; + unsigned PatchableFunctionPrefix = 0, PatchableFunctionEntry = 0; + (void)F.getFnAttribute("patchable-function-prefix") + .getValueAsString() + .getAsInteger(10, PatchableFunctionPrefix); (void)F.getFnAttribute("patchable-function-entry") .getValueAsString() .getAsInteger(10, PatchableFunctionEntry); - if (!PatchableFunctionEntry) + if (!PatchableFunctionPrefix && !PatchableFunctionEntry) return; const unsigned PointerSize = getPointerSize(); if (TM.getTargetTriple().isOSBinFormatELF()) { @@ -3232,7 +3257,7 @@ void AsmPrinter::emitPatchableFunctionEntries() { "__patchable_function_entries", ELF::SHT_PROGBITS, Flags)); } EmitAlignment(Align(PointerSize)); - OutStreamer->EmitSymbolValue(CurrentFnBegin, PointerSize); + OutStreamer->EmitSymbolValue(CurrentPatchableFunctionEntrySym, PointerSize); } } |