[RFC 28/31] x86/alternative: Create symbols for special section entries

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Create a symbol for each special section entry.  This helps objtool
extract needed entries.

Signed-off-by: Josh Poimboeuf <jpoimboe@xxxxxxxxxx>
---
 arch/x86/include/asm/alternative.h | 50 ++++++++++++++++++++----------
 arch/x86/include/asm/asm.h         | 24 +++++++++-----
 arch/x86/include/asm/bug.h         |  2 ++
 arch/x86/include/asm/cpufeature.h  |  2 ++
 arch/x86/include/asm/jump_label.h  |  2 ++
 include/linux/objtool.h            | 31 +++++++++++++++++-
 tools/objtool/check.c              | 22 +++++++++++--
 7 files changed, 104 insertions(+), 29 deletions(-)

diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h
index ba99ef75f56c..2617253bcb00 100644
--- a/arch/x86/include/asm/alternative.h
+++ b/arch/x86/include/asm/alternative.h
@@ -157,7 +157,9 @@ static inline int alternatives_text_reserved(void *start, void *end)
 #define ALT_CALL_INSTR		"call BUG_func"
 
 #define b_replacement(num)	"664"#num
-#define e_replacement(num)	"665"#num
+
+#define __e_replacement(num)	__PASTE(665, num)
+#define e_replacement(num)	__stringify(__e_replacement(num))
 
 #define alt_end_marker		"663"
 #define alt_slen		"662b-661b"
@@ -203,15 +205,21 @@ static inline int alternatives_text_reserved(void *start, void *end)
 	alt_end_marker ":\n"
 
 #define ALTINSTR_ENTRY(ft_flags, num)					      \
+	FAKE_SYMBOL(__alt_, 681f)					      \
 	" .long 661b - .\n"				/* label           */ \
 	" .long " b_replacement(num)"f - .\n"		/* new instruction */ \
 	" .4byte " __stringify(ft_flags) "\n"		/* feature + flags */ \
 	" .byte " alt_total_slen "\n"			/* source len      */ \
-	" .byte " alt_rlen(num) "\n"			/* replacement len */
+	" .byte " alt_rlen(num) "\n"			/* replacement len */ \
+	"681:\n"
 
-#define ALTINSTR_REPLACEMENT(newinstr, num)		/* replacement */	\
+#define ALTINSTR_REPLACEMENT(newinstr, num)					\
 	"# ALT: replacement " #num "\n"						\
-	b_replacement(num)":\n\t" newinstr "\n" e_replacement(num) ":\n"
+	FAKE_SYMBOL(__alt_instr_, __PASTE(__e_replacement(num), f))		\
+	b_replacement(num) ":\n"						\
+	"\t" newinstr "\n"							\
+	e_replacement(num) ":\n"
+
 
 /* alternative assembly primitive: */
 #define ALTERNATIVE(oldinstr, newinstr, ft_flags)			\
@@ -370,12 +378,20 @@ void nop_func(void);
  * enough information for the alternatives patching code to patch an
  * instruction. See apply_alternatives().
  */
-.macro altinstr_entry orig alt ft_flags orig_len alt_len
+.macro ALTINSTR_ENTRY orig alt ft_flags orig_len alt_len
+	FAKE_SYMBOL(__alt_, 681f)
 	.long \orig - .
 	.long \alt - .
 	.4byte \ft_flags
 	.byte \orig_len
 	.byte \alt_len
+	681:
+.endm
+
+.macro ALTINSTR_REPLACEMENT newinstr
+	FAKE_SYMBOL(__alt_instr_, 681f)
+	\newinstr
+	681:
 .endm
 
 .macro ALT_CALL_INSTR
@@ -396,12 +412,12 @@ void nop_func(void);
 142:
 
 	.pushsection .altinstructions,"a"
-	altinstr_entry 140b,143f,\ft_flags,142b-140b,144f-143f
+	ALTINSTR_ENTRY 140b,143f,\ft_flags,142b-140b,144f-143f
 	.popsection
 
 	.pushsection .altinstr_replacement,"ax"
 143:
-	\newinstr
+	ALTINSTR_REPLACEMENT "\newinstr"
 144:
 	.popsection
 .endm
@@ -435,15 +451,15 @@ void nop_func(void);
 142:
 
 	.pushsection .altinstructions,"a"
-	altinstr_entry 140b,143f,\ft_flags1,142b-140b,144f-143f
-	altinstr_entry 140b,144f,\ft_flags2,142b-140b,145f-144f
+	ALTINSTR_ENTRY 140b,143f,\ft_flags1,142b-140b,144f-143f
+	ALTINSTR_ENTRY 140b,144f,\ft_flags2,142b-140b,145f-144f
 	.popsection
 
 	.pushsection .altinstr_replacement,"ax"
 143:
-	\newinstr1
+	ALTINSTR_REPLACEMENT "\newinstr1"
 144:
-	\newinstr2
+	ALTINSTR_REPLACEMENT "\newinstr2"
 145:
 	.popsection
 .endm
@@ -457,18 +473,18 @@ void nop_func(void);
 142:
 
 	.pushsection .altinstructions,"a"
-	altinstr_entry 140b,143f,\ft_flags1,142b-140b,144f-143f
-	altinstr_entry 140b,144f,\ft_flags2,142b-140b,145f-144f
-	altinstr_entry 140b,145f,\ft_flags3,142b-140b,146f-145f
+	ALTINSTR_ENTRY 140b,143f,\ft_flags1,142b-140b,144f-143f
+	ALTINSTR_ENTRY 140b,144f,\ft_flags2,142b-140b,145f-144f
+	ALTINSTR_ENTRY 140b,145f,\ft_flags3,142b-140b,146f-145f
 	.popsection
 
 	.pushsection .altinstr_replacement,"ax"
 143:
-	\newinstr1
+	ALTINSTR_REPLACEMENT "\newinstr1"
 144:
-	\newinstr2
+	ALTINSTR_REPLACEMENT "\newinstr2"
 145:
-	\newinstr3
+	ALTINSTR_REPLACEMENT "\newinstr3"
 146:
 	.popsection
 .endm
diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h
index 2bec0c89a95c..c337240d342c 100644
--- a/arch/x86/include/asm/asm.h
+++ b/arch/x86/include/asm/asm.h
@@ -2,6 +2,8 @@
 #ifndef _ASM_X86_ASM_H
 #define _ASM_X86_ASM_H
 
+#include <linux/objtool.h>
+
 #ifdef __ASSEMBLY__
 # define __ASM_FORM(x, ...)		x,## __VA_ARGS__
 # define __ASM_FORM_RAW(x, ...)		x,## __VA_ARGS__
@@ -149,9 +151,11 @@ static __always_inline __pure void *rip_rel_ptr(void *p)
 # define _ASM_EXTABLE_TYPE(from, to, type)			\
 	.pushsection "__ex_table","a" ;				\
 	.balign 4 ;						\
+	FAKE_SYMBOL(__ex_table_, 555f) ;			\
 	.long (from) - . ;					\
 	.long (to) - . ;					\
 	.long type ;						\
+	555: ;							\
 	.popsection
 
 # ifdef CONFIG_KPROBES
@@ -196,19 +200,23 @@ static __always_inline __pure void *rip_rel_ptr(void *p)
 # define _ASM_EXTABLE_TYPE(from, to, type)			\
 	" .pushsection \"__ex_table\",\"a\"\n"			\
 	" .balign 4\n"						\
+	FAKE_SYMBOL(__ex_table_, 555f)			\
 	" .long (" #from ") - .\n"				\
 	" .long (" #to ") - .\n"				\
 	" .long " __stringify(type) " \n"			\
+	" 555:\n"						\
 	" .popsection\n"
 
-# define _ASM_EXTABLE_TYPE_REG(from, to, type, reg)				\
-	" .pushsection \"__ex_table\",\"a\"\n"					\
-	" .balign 4\n"								\
-	" .long (" #from ") - .\n"						\
-	" .long (" #to ") - .\n"						\
-	DEFINE_EXTABLE_TYPE_REG							\
-	"extable_type_reg reg=" __stringify(reg) ", type=" __stringify(type) " \n"\
-	UNDEFINE_EXTABLE_TYPE_REG						\
+# define _ASM_EXTABLE_TYPE_REG(from, to, type, reg)					\
+	" .pushsection \"__ex_table\",\"a\"\n"						\
+	" .balign 4\n"									\
+	FAKE_SYMBOL(__ex_table_, 555f)							\
+	" .long (" #from ") - .\n"							\
+	" .long (" #to ") - .\n"							\
+	DEFINE_EXTABLE_TYPE_REG								\
+	"extable_type_reg reg=" __stringify(reg) ", type=" __stringify(type) " \n"	\
+	UNDEFINE_EXTABLE_TYPE_REG							\
+	" 555:\n"									\
 	" .popsection\n"
 
 /* For C file, we already have NOKPROBE_SYMBOL macro */
diff --git a/arch/x86/include/asm/bug.h b/arch/x86/include/asm/bug.h
index a3ec87d198ac..86304d7d68f5 100644
--- a/arch/x86/include/asm/bug.h
+++ b/arch/x86/include/asm/bug.h
@@ -27,6 +27,7 @@
 do {									\
 	asm_inline volatile("1:\t" ins "\n"				\
 		     ".pushsection __bug_table,\"aw\"\n"		\
+		     FAKE_SYMBOL(__bug_table_, . + %c3)			\
 		     "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n"	\
 		     "\t"  __BUG_REL(%c0) "\t# bug_entry::file\n"	\
 		     "\t.word %c1"        "\t# bug_entry::line\n"	\
@@ -45,6 +46,7 @@ do {									\
 do {									\
 	asm_inline volatile("1:\t" ins "\n"				\
 		     ".pushsection __bug_table,\"aw\"\n"		\
+		     FAKE_SYMBOL(__bug_table_, . + %c1)			\
 		     "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n"	\
 		     "\t.word %c0"        "\t# bug_entry::flags\n"	\
 		     "\t.org 2b+%c1\n"					\
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
index 0b9611da6c53..9decf644d55a 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -178,9 +178,11 @@ static __always_inline bool _static_cpu_has(u16 bit)
 	asm goto(ALTERNATIVE_TERNARY("jmp 6f", %c[feature], "", "jmp %l[t_no]")
 		".pushsection .altinstr_aux,\"ax\"\n"
 		"6:\n"
+		FAKE_SYMBOL(__alt_aux_, 681f)
 		" testb %[bitnum], %a[cap_byte]\n"
 		" jnz %l[t_yes]\n"
 		" jmp %l[t_no]\n"
+		"681:\n"
 		".popsection\n"
 		 : : [feature]  "i" (bit),
 		     [bitnum]   "i" (1 << (bit & 7)),
diff --git a/arch/x86/include/asm/jump_label.h b/arch/x86/include/asm/jump_label.h
index cbbef32517f0..731d7e69d244 100644
--- a/arch/x86/include/asm/jump_label.h
+++ b/arch/x86/include/asm/jump_label.h
@@ -15,9 +15,11 @@
 #define JUMP_TABLE_ENTRY				\
 	".pushsection __jump_table,  \"aw\" \n\t"	\
 	_ASM_ALIGN "\n\t"				\
+	FAKE_SYMBOL(__jump_table_, 2f)			\
 	".long 1b - . \n\t"				\
 	".long %l[l_yes] - . \n\t"			\
 	_ASM_PTR "%c0 + %c1 - .\n\t"			\
+	"2:\n\t"					\
 	".popsection \n\t"
 
 #ifdef CONFIG_HAVE_JUMP_LABEL_HACK
diff --git a/include/linux/objtool.h b/include/linux/objtool.h
index 5e66b6d26df5..ae5030cac10d 100644
--- a/include/linux/objtool.h
+++ b/include/linux/objtool.h
@@ -10,9 +10,27 @@
 
 #ifndef __ASSEMBLY__
 
-#define UNWIND_HINT(type, sp_reg, sp_offset, signal)	\
+#define DEFINE_FAKE_SYMBOL						\
+	".macro fake_symbol name, end\n\t"				\
+	"#ifdef __x86_64__\n"						\
+	".type \\name\\@, @object\n"					\
+	".size \\name\\@, \\end - .\n"					\
+	"\\name\\@:\n"							\
+	"#endif\n"							\
+	".endm\n\t"
+
+#define UNDEFINE_FAKE_SYMBOL						\
+	".purgem fake_symbol\n\t"
+
+#define FAKE_SYMBOL(name, end)							\
+	DEFINE_FAKE_SYMBOL							\
+	"fake_symbol " __stringify(name) ", \"" __stringify(end) "\"\n\t"	\
+	UNDEFINE_FAKE_SYMBOL
+
+#define UNWIND_HINT(type, sp_reg, sp_offset, signal)		\
 	"987: \n\t"						\
 	".pushsection .discard.unwind_hints\n\t"		\
+	FAKE_SYMBOL(__unwind_hint_, 988f)			\
 	/* struct unwind_hint */				\
 	".long 987b - .\n\t"					\
 	".short " __stringify(sp_offset) "\n\t"			\
@@ -20,6 +38,7 @@
 	".byte " __stringify(type) "\n\t"			\
 	".byte " __stringify(signal) "\n\t"			\
 	".balign 4 \n\t"					\
+	"988:\n\t"						\
 	".popsection\n\t"
 
 /*
@@ -60,6 +79,14 @@
 
 #else /* __ASSEMBLY__ */
 
+.macro fake_symbol name, end
+	.type \name\@, @object
+	.size \name\@, \end - .
+	\name\@:
+.endm
+
+#define FAKE_SYMBOL(name, end) fake_symbol name, __stringify(end)
+
 /*
  * This macro indicates that the following intra-function call is valid.
  * Any non-annotated intra-function call will cause objtool to issue a warning.
@@ -94,6 +121,7 @@
 .macro UNWIND_HINT type:req sp_reg=0 sp_offset=0 signal=0
 .Lhere_\@:
 	.pushsection .discard.unwind_hints
+		FAKE_SYMBOL(__unwind_hint_, .Lend_\@)
 		/* struct unwind_hint */
 		.long .Lhere_\@ - .
 		.short \sp_offset
@@ -101,6 +129,7 @@
 		.byte \type
 		.byte \signal
 		.balign 4
+		.Lend_\@:
 	.popsection
 .endm
 
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 3c8d0903dfa7..5dd78a7f75c3 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -633,6 +633,18 @@ static void add_dead_ends(struct objtool_file *file)
 	}
 }
 
+static void create_fake_symbol(struct objtool_file *file, const char *name_pfx,
+			       struct section *sec, unsigned long offset,
+			       size_t size)
+{
+	char name[256];
+	static int ctr;
+
+	snprintf(name, 256, "%s_%d", name_pfx, ctr++);
+
+	elf_create_symbol(file->elf, name, sec, STB_LOCAL, STT_OBJECT, offset, size);
+}
+
 static void create_static_call_sections(struct objtool_file *file)
 {
 	struct static_call_site *site;
@@ -664,10 +676,11 @@ static void create_static_call_sections(struct objtool_file *file)
 
 	idx = 0;
 	list_for_each_entry(insn, &file->static_call_list, call_node) {
+		unsigned long offset = idx * sizeof(*site);
 
 		/* populate reloc for 'addr' */
-		elf_init_reloc_text_sym(file->elf, sec, idx * sizeof(*site),
-					idx * 2, insn->sec, insn->offset);
+		elf_init_reloc_text_sym(file->elf, sec, offset, idx * 2,
+					insn->sec, insn->offset);
 
 		/* find key symbol */
 		key_name = strdup(insn_call_dest(insn)->name);
@@ -698,10 +711,13 @@ static void create_static_call_sections(struct objtool_file *file)
 		free(key_name);
 
 		/* populate reloc for 'key' */
-		elf_init_reloc_data_sym(file->elf, sec, idx * sizeof(*site) + 4,
+		elf_init_reloc_data_sym(file->elf, sec, offset + 4,
 					(idx * 2) + 1, key_sym,
 					is_sibling_call(insn) * STATIC_CALL_SITE_TAIL);
 
+		create_fake_symbol(file, "__static_call_site_", sec,
+				   offset, sizeof(*site));
+
 		idx++;
 	}
 }
-- 
2.45.2





[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux Kernel]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux