diff mbox series

[RFC,v1,3/9] dwarf: Build the kernel with DWARF information

Message ID 20220407202518.19780-4-madvenka@linux.microsoft.com (mailing list archive)
State New, archived
Headers show
Series arm64: livepatch: Use DWARF Call Frame Information for frame pointer validation | expand

Commit Message

Madhavan T. Venkataraman April 7, 2022, 8:25 p.m. UTC
From: "Madhavan T. Venkataraman" <madvenka@linux.microsoft.com>

Define CONFIG_DWARF_FP - to include DWARF based FP validation code.
Define CONFIG_STACK_VALIDATION - to enable DWARF based FP validation.

When these configs are enabled, invoke objtool on relocatable files during
the kernel build with the following command:

	objtool dwarf generate <object-file>

Objtool creates the following sections in each object file:

.dwarf_rules	Array of DWARF rules
.dwarf_pcs	Array of PCs, one-to-one with rules

In the future, the kernel can use these sections to find the rules for a
given instruction address. The unwinder can then compute the FP at an
instruction address and validate the actual FP with that.

NOTE: CONFIG_STACK_VALIDATION needs to be turned on here. Otherwise, objtool
will not be invoked during the kernel build process. The actual stack
validation code will be added separately. This is harmless.

Signed-off-by: Madhavan T. Venkataraman <madvenka@linux.microsoft.com>
---
 arch/Kconfig                    |  4 +++-
 arch/arm64/Kconfig              |  2 ++
 arch/arm64/Kconfig.debug        |  5 +++++
 arch/arm64/configs/defconfig    |  1 +
 arch/arm64/kernel/vmlinux.lds.S | 22 ++++++++++++++++++++++
 scripts/Makefile.build          |  4 ++++
 scripts/link-vmlinux.sh         |  6 ++++++
 7 files changed, 43 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/arch/Kconfig b/arch/Kconfig
index d3c4ab249e9c..3b0d0db322b9 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -1016,7 +1016,9 @@  config HAVE_STACK_VALIDATION
 	bool
 	help
 	  Architecture supports the 'objtool check' host tool command, which
-	  performs compile-time stack metadata validation.
+	  performs compile-time stack metadata validation. Or, on architectures
+	  that use DWARF validated frame pointers, it supports the
+	  'objtool dwarf generate' host tool command.
 
 config HAVE_RELIABLE_STACKTRACE
 	bool
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index c4207cf9bb17..c82a3a93297f 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -220,6 +220,8 @@  config ARM64
 	select SWIOTLB
 	select SYSCTL_EXCEPTION_TRACE
 	select THREAD_INFO_IN_TASK
+	select HAVE_STACK_VALIDATION	if DWARF_FP
+	select STACK_VALIDATION		if HAVE_STACK_VALIDATION
 	select HAVE_ARCH_USERFAULTFD_MINOR if USERFAULTFD
 	select TRACE_IRQFLAGS_SUPPORT
 	help
diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug
index 265c4461031f..585967062a1c 100644
--- a/arch/arm64/Kconfig.debug
+++ b/arch/arm64/Kconfig.debug
@@ -20,4 +20,9 @@  config ARM64_RELOC_TEST
 	depends on m
 	tristate "Relocation testing module"
 
+config DWARF_FP
+	def_bool y
+	depends on FRAME_POINTER
+	depends on DEBUG_INFO_DWARF4
+
 source "drivers/hwtracing/coresight/Kconfig"
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index f2e2b9bdd702..a59c448f442a 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1233,3 +1233,4 @@  CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_PREEMPT is not set
 # CONFIG_FTRACE is not set
 CONFIG_MEMTEST=y
+CONFIG_DEBUG_INFO_DWARF4=y
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 50bab186c49b..fb3b9970453b 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -122,6 +122,25 @@  jiffies = jiffies_64;
 #define TRAMP_TEXT
 #endif
 
+#ifdef CONFIG_DWARF_FP
+#define DWARF_RULES					\
+	. = ALIGN(8);					\
+	.dwarf_rules : {				\
+		__dwarf_rules_start = .;		\
+		KEEP(*(.dwarf_rules))			\
+		__dwarf_rules_end = .;			\
+	}
+
+#define DWARF_PCS					\
+	. = ALIGN(8);					\
+	__dwarf_pcs_start = .;				\
+	KEEP(*(.dwarf_pcs))				\
+	__dwarf_pcs_end = .;
+#else
+#define DWARF_RULES
+#define DWARF_PCS
+#endif
+
 /*
  * The size of the PE/COFF section that covers the kernel image, which
  * runs from _stext to _edata, must be a round multiple of the PE/COFF
@@ -239,6 +258,7 @@  SECTIONS
 		CON_INITCALL
 		INIT_RAM_FS
 		*(.init.altinstructions .init.bss)	/* from the EFI stub */
+		DWARF_PCS
 	}
 	.exit.data : {
 		EXIT_DATA
@@ -291,6 +311,8 @@  SECTIONS
 		__mmuoff_data_end = .;
 	}
 
+	DWARF_RULES
+
 	PECOFF_EDATA_PADDING
 	__pecoff_data_rawsize = ABSOLUTE(. - __initdata_begin);
 	_edata = .;
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 78656b527fe5..5e8d89c64572 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -227,6 +227,9 @@  ifdef CONFIG_STACK_VALIDATION
 
 objtool := $(objtree)/tools/objtool/objtool
 
+ifdef CONFIG_DWARF_FP
+objtool_args = dwarf generate
+else
 objtool_args =								\
 	$(if $(CONFIG_UNWINDER_ORC),orc generate,check)			\
 	$(if $(part-of-module), --module)				\
@@ -235,6 +238,7 @@  objtool_args =								\
 	$(if $(CONFIG_RETPOLINE), --retpoline)				\
 	$(if $(CONFIG_X86_SMAP), --uaccess)				\
 	$(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount)
+endif
 
 cmd_objtool = $(if $(objtool-enabled), ; $(objtool) $(objtool_args) $@)
 cmd_gen_objtooldep = $(if $(objtool-enabled), { echo ; echo '$@: $$(wildcard $(objtool))' ; } >> $(dot-target).cmd)
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
index 5cdd9bc5c385..433e395f977b 100755
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -104,6 +104,12 @@  objtool_link()
 	local objtoolcmd;
 	local objtoolopt;
 
+	if [ "${CONFIG_LTO_CLANG} ${CONFIG_DWARF_FP}" = "y y" ]
+	then
+		tools/objtool/objtool dwarf generate ${1}
+		return
+	fi
+
 	if [ "${CONFIG_LTO_CLANG} ${CONFIG_STACK_VALIDATION}" = "y y" ]; then
 		# Don't perform vmlinux validation unless explicitly requested,
 		# but run objtool on vmlinux.o now that we have an object file.