+2018-11-29 Andi Kleen <ak@linux.intel.com>
+
+ * config/i386/i386-opts.h (enum instrument_return): Add.
+ * config/i386/i386.c (output_return_instrumentation): Add.
+ (ix86_output_function_return): Call output_return_instrumentation.
+ (ix86_output_call_insn): Call output_return_instrumentation.
+ * config/i386/i386.opt: Add -minstrument-return=.
+ * doc/invoke.texi (-minstrument-return): Document.
+
2018-11-29 Eric Botcazou <ebotcazou@adacore.com>
PR target/87807
indirect_branch_thunk_extern
};
+enum instrument_return {
+ instrument_return_none = 0,
+ instrument_return_call,
+ instrument_return_nop5
+};
+
#endif
return "%!jmp\t%A0";
}
+/* Output return instrumentation for current function if needed. */
+
+static void
+output_return_instrumentation (void)
+{
+ if (ix86_instrument_return != instrument_return_none
+ && flag_fentry
+ && !DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (cfun->decl))
+ {
+ if (ix86_flag_record_return)
+ fprintf (asm_out_file, "1:\n");
+ switch (ix86_instrument_return)
+ {
+ case instrument_return_call:
+ fprintf (asm_out_file, "\tcall\t__return__\n");
+ break;
+ case instrument_return_nop5:
+ /* 5 byte nop: nopl 0(%[re]ax,%[re]ax,1) */
+ fprintf (asm_out_file, ASM_BYTE "0x0f, 0x1f, 0x44, 0x00, 0x00\n");
+ break;
+ case instrument_return_none:
+ break;
+ }
+
+ if (ix86_flag_record_return)
+ {
+ fprintf (asm_out_file, "\t.section __return_loc, \"a\",@progbits\n");
+ fprintf (asm_out_file, "\t.%s 1b\n", TARGET_64BIT ? "quad" : "long");
+ fprintf (asm_out_file, "\t.previous\n");
+ }
+ }
+}
+
/* Output function return. CALL_OP is the jump target. Add a REP
prefix to RET if LONG_P is true and function return is kept. */
const char *
ix86_output_function_return (bool long_p)
{
+ output_return_instrumentation ();
+
if (cfun->machine->function_return_type != indirect_branch_keep)
{
char thunk_name[32];
if (SIBLING_CALL_P (insn))
{
+ output_return_instrumentation ();
if (direct_p)
{
if (ix86_nopic_noplt_attribute_p (call_op))
mcldemote
Target Report Mask(ISA_CLDEMOTE) Var(ix86_isa_flags2) Save
Support CLDEMOTE built-in functions and code generation.
+
+minstrument-return=
+Target Report RejectNegative Joined Enum(instrument_return) Var(ix86_instrument_return) Init(instrument_return_none)
+Instrument function exit in instrumented functions with __fentry__.
+
+Enum
+Name(instrument_return) Type(enum instrument_return)
+Known choices for return instrumentation with -minstrument-return=
+
+EnumValue
+Enum(instrument_return) String(none) Value(instrument_return_none)
+
+EnumValue
+Enum(instrument_return) String(call) Value(instrument_return_call)
+
+EnumValue
+Enum(instrument_return) String(nop5) Value(instrument_return_nop5)
+
+mrecord-return
+Target Report Var(ix86_flag_record_return) Init(0)
+Generate a __return_loc section pointing to all return instrumentation code.
-mcmodel=@var{code-model} -mabi=@var{name} -maddress-mode=@var{mode} @gol
-m32 -m64 -mx32 -m16 -miamcu -mlarge-data-threshold=@var{num} @gol
-msse2avx -mfentry -mrecord-mcount -mnop-mcount -m8bit-idiv @gol
+-minstrument-return=@var{type} @gol
-mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol
-malign-data=@var{type} -mstack-protector-guard=@var{guard} @gol
-mstack-protector-guard-reg=@var{reg} @gol
should be patched in later dynamically. This is likely only
useful together with @option{-mrecord-mcount}.
+@item -minstrument-return=@var{type}
+@opindex minstrument-return
+Instrument function exit in -pg -mfentry instrumented functions with
+call to specified function. This only instruments true returns ending
+with ret, but not sibling calls ending with jump. Valid types
+are @var{none} to not instrument, @var{call} to generate a call to __return__,
+or @var{nop5} to generate a 5 byte nop.
+
+@item -mrecord-return
+@itemx -mno-record-return
+@opindex mrecord-return
+Generate a __return_loc section pointing to all return instrumentation code.
+
@item -mskip-rax-setup
@itemx -mno-skip-rax-setup
@opindex mskip-rax-setup
+2018-11-29 Andi Kleen <ak@linux.intel.com>
+
+ * gcc.target/i386/returninst1.c: New test.
+ * gcc.target/i386/returninst2.c: New test.
+ * gcc.target/i386/returninst3.c: New test.
+
2018-11-29 Eric Botcazou <ebotcazou@adacore.com>
* gcc.target/sparc/20181129-1.c: New test.
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-pg -mfentry -minstrument-return=call -mrecord-return" } */
+/* { dg-final { scan-assembler "call.*__return__" } } */
+/* { dg-final { scan-assembler "section.*return_loc" } } */
+
+int func(int a)
+{
+ return a+1;
+}
+
+int func2(int a)
+{
+ return a+1;
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-pg -mfentry -minstrument-return=nop5 -mrecord-return" } */
+/* { dg-final { scan-assembler-times "0x0f, 0x1f, 0x44, 0x00, 0x00" 3 } } */
+/* { dg-final { scan-assembler "section.*return_loc" } } */
+
+int func(int a)
+{
+ return a+1;
+}
+
+int func2(int a)
+{
+ return a+1;
+}
+
+extern void func4(int);
+
+int func3(int a)
+{
+ func4(a + 1);
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-pg -mfentry -minstrument-return=call" } */
+/* { dg-final { scan-assembler-not "call.*__return__" } } */
+
+__attribute__((no_instrument_function))
+int func(int a)
+{
+ return a+1;
+}