[PATCH] x86: Detect CFI support in the assembler at runtime
... instead of using a CONFIG option. The config option still controls
if the resulting executable actually has unwind information.
This is useful to prevent compilation errors when users select
CONFIG_STACK_UNWIND on old binutils and also allows to use
CFI in the future for non kernel debugging applications.
Cc: jbeulich@novell.com
Cc: sam@ravnborg.org
Signed-off-by: Andi Kleen <ak@suse.de>
diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt
index b7d6abb..e2cbd59 100644
--- a/Documentation/kbuild/makefiles.txt
+++ b/Documentation/kbuild/makefiles.txt
@@ -421,6 +421,11 @@
The second argument is optional, and if supplied will be used
if first argument is not supported.
+ as-instr
+ as-instr checks if the assembler reports a specific instruction
+ and then outputs either option1 or option2
+ C escapes are supported in the test instruction
+
cc-option
cc-option is used to check if $(CC) supports a given option, and not
supported to use an optional second option.
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
index 3e4adb1..508cdbe 100644
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -46,6 +46,10 @@
# a lot more stack due to the lack of sharing of stacklots:
CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-option,-fno-unit-at-a-time); fi ;)
+# do binutils support CFI?
+cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
+AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
+
CFLAGS += $(cflags-y)
# Default subarch .c files
diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile
index 431bb4b..d6472dd 100644
--- a/arch/x86_64/Makefile
+++ b/arch/x86_64/Makefile
@@ -54,6 +54,9 @@
cflags-y += $(call cc-option,-funit-at-a-time)
# prevent gcc from generating any FP code by mistake
cflags-y += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,)
+# do binutils support CFI?
+cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
+AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
CFLAGS += $(cflags-y)
CFLAGS_KERNEL += $(cflags-kernel-y)
diff --git a/include/asm-x86_64/dwarf2.h b/include/asm-x86_64/dwarf2.h
index 0744db7..2b93683 100644
--- a/include/asm-x86_64/dwarf2.h
+++ b/include/asm-x86_64/dwarf2.h
@@ -13,7 +13,7 @@
away for older version.
*/
-#ifdef CONFIG_UNWIND_INFO
+#ifdef CONFIG_AS_CFI
#define CFI_STARTPROC .cfi_startproc
#define CFI_ENDPROC .cfi_endproc
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index 3d52389..7adef12 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -63,6 +63,13 @@
-xassembler /dev/null > /dev/null 2>&1; then echo "$(1)"; \
else echo "$(2)"; fi ;)
+# as-instr
+# Usage: cflags-y += $(call as-instr, instr, option1, option2)
+
+as-instr = $(shell if echo -e "$(1)" | $(AS) -Z -o astest$$$$.out \
+ 2>&1 >/dev/null ; then echo "$(2)"; else echo "$(3)"; fi; \
+ rm -f astest$$$$.out)
+
# cc-option
# Usage: cflags-y += $(call cc-option, -march=winchip-c6, -march=i586)