Skip to content

ld.lld: error: <inline asm>:25:2: macro 'extable_type_reg' is already defined #1513

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
nathanchance opened this issue Nov 24, 2021 · 4 comments
Assignees
Labels
[BUG] linux-next This is an issue only seen in linux-next [FEATURE] LTO Related to building the kernel with LLVM Link Time Optimization [FIXED][LINUX] development cycle This bug was only present and fixed in a -next or -rc cycle [Reported-by] kbuild test robot Reported-by: kbuild test robot <[email protected]> [TOOL] integrated-as The issue is relevant to LLVM integrated assembler

Comments

@nathanchance
Copy link
Member

The kernel test robot reported an issue with a proposed series:

$ git fetch https://git.kernel.org/pub/scm/linux/kernel/git/peterz/queue.git x86/wip.extable

$ git checkout 04a71fc5f69191cb18f97c0ae4e4c941fe335f4e

$ curl -LSs https://lore.kernel.org/all/[email protected]/2-a.bin | gzip -d > .config

$ make -skj"$(nproc)" LLVM=1 LLVM_IAS=1 olddefconfig vmlinux
ld.lld: error: <inline asm>:64:2: macro 'extable_type_reg' is already defined
        .macro extable_type_reg type:req reg:req
        ^

It looks like something similar to commit be604c616ca7 ("arm64: sysreg: Make mrs_s and msr_s macros work with Clang and LTO") will be needed here.

I tried something like

diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h
index 95bb23082b87..88a030c22bb2 100644
--- a/arch/x86/include/asm/asm.h
+++ b/arch/x86/include/asm/asm.h
@@ -152,30 +152,37 @@
 
 #else /* ! __ASSEMBLY__ */
 
-asm(
-"	.macro extable_type_reg type:req reg:req\n"
-"	.set found, 0\n"
-"	.set regnr, 0\n"
-"	.irp rs,rax,rcx,rdx,rbx,rsp,rbp,rsi,rdi,r8,r9,r10,r11,r12,r13,r14,r15\n"
-"	.ifc \\reg, %\\rs\n"
-"	.set found, found+1\n"
-"	.long \\type + (regnr << 8)\n"
-"	.endif\n"
-"	.set regnr, regnr+1\n"
-"	.endr\n"
-"	.set regnr, 0\n"
-"	.irp rs,eax,ecx,edx,ebx,esp,ebp,esi,edi,r8d,r9d,r10d,r11d,r12d,r13d,r14d,r15d\n"
-"	.ifc \\reg, %\\rs\n"
-"	.set found, found+1\n"
-"	.long \\type + (regnr << 8)\n"
-"	.endif\n"
-"	.set regnr, regnr+1\n"
-"	.endr\n"
-"	.if (found != 1)\n"
-"	.error \"extable_type_reg: bad register argument\"\n"
-"	.endif\n"
+# define DEFINE_EXTABLE_TYPE_REG \
+"	.macro extable_type_reg type:req reg:req\n"						\
+"	.set found, 0\n"									\
+"	.set regnr, 0\n"									\
+"	.irp rs,rax,rcx,rdx,rbx,rsp,rbp,rsi,rdi,r8,r9,r10,r11,r12,r13,r14,r15\n"		\
+"	.ifc \\reg, %\\rs\n"									\
+"	.set found, found+1\n"									\
+"	.long \\type + (regnr << 8)\n"								\
+"	.endif\n"										\
+"	.set regnr, regnr+1\n"									\
+"	.endr\n"										\
+"	.set regnr, 0\n"									\
+"	.irp rs,eax,ecx,edx,ebx,esp,ebp,esi,edi,r8d,r9d,r10d,r11d,r12d,r13d,r14d,r15d\n"	\
+"	.ifc \\reg, %\\rs\n"									\
+"	.set found, found+1\n"									\
+"	.long \\type + (regnr << 8)\n"								\
+"	.endif\n"										\
+"	.set regnr, regnr+1\n"									\
+"	.endr\n"										\
+"	.if (found != 1)\n"									\
+"	.error \"extable_type_reg: bad register argument\"\n"					\
+"	.endif\n"										\
 "	.endm\n"
-);
+
+# define UNDEFINE_EXTABLE_TYPE_REG \
+"	.purgem extable_type_reg\n"
+
+# define __extable_type_reg(type, reg) \
+	DEFINE_EXTABLE_TYPE_REG								\
+"	extable_type_reg type=" __stringify(type) ", reg=" __stringify(reg) " \n"	\
+	UNDEFINE_EXTABLE_TYPE_REG
 
 # define _ASM_EXTABLE_TYPE(from, to, type)			\
 	" .pushsection \"__ex_table\",\"a\"\n"			\
@@ -185,12 +192,12 @@ asm(
 	" .long " __stringify(type) " \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"						\
-	"extable_type_reg reg=" __stringify(reg) ", type=" __stringify(type) " \n"\
+# define _ASM_EXTABLE_TYPE_REG(from, to, type, reg)	\
+	" .pushsection \"__ex_table\",\"a\"\n"		\
+	" .balign 4\n"					\
+	" .long (" #from ") - .\n"			\
+	" .long (" #to ") - .\n"			\
+	__extable_type_reg(type, reg)			\
 	" .popsection\n"
 
 /* For C file, we already have NOKPROBE_SYMBOL macro */

which results in

In file included from arch/x86/kernel/asm-offsets.c:9:
In file included from ./include/linux/crypto.h:20:
In file included from ./include/linux/slab.h:15:
In file included from ./include/linux/gfp.h:6:
In file included from ./include/linux/mmzone.h:8:
In file included from ./include/linux/spinlock.h:55:
In file included from ./include/linux/preempt.h:78:
In file included from ./arch/x86/include/asm/preempt.h:7:
In file included from ./include/linux/thread_info.h:60:
In file included from ./arch/x86/include/asm/thread_info.h:53:
In file included from ./arch/x86/include/asm/cpufeature.h:5:
In file included from ./arch/x86/include/asm/processor.h:22:
./arch/x86/include/asm/msr.h:168:8: error: invalid % escape in inline assembly string
                     _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_WRMSR_SAFE, %[err])
                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./arch/x86/include/asm/asm.h:200:2: note: expanded from macro '_ASM_EXTABLE_TYPE_REG'
        __extable_type_reg(type, reg)                   \
        ^
./arch/x86/include/asm/asm.h:183:2: note: expanded from macro '__extable_type_reg'
        DEFINE_EXTABLE_TYPE_REG                                                         \
        ^
./arch/x86/include/asm/asm.h:160:16: note: expanded from macro 'DEFINE_EXTABLE_TYPE_REG'
"       .ifc \\reg, %\\rs\n"                                                                    \
                     ^
2 errors generated.

after which I tried replacing the % with %% in DEFINE_EXTABLE_TYPE_REG , which appears to break the macro entirely:

<instantiation>:19:2: error: extable_type_reg: bad register argument
        .error "extable_type_reg: bad register argument"
        ^
note: while in macro instantiation
        extable_type_reg type=(17 | ((0) << 16)), reg=%esi
        ^

My knowledge of assembly macros is non-existent so any input around this would be appreciate :)

@nathanchance nathanchance added [TOOL] integrated-as The issue is relevant to LLVM integrated assembler [FEATURE] LTO Related to building the kernel with LLVM Link Time Optimization [Reported-by] kbuild test robot Reported-by: kbuild test robot <[email protected]> labels Nov 24, 2021
@nickdesaulniers
Copy link
Member

after which I tried replacing the % with %% in DEFINE_EXTABLE_TYPE_REG , which appears to break the macro entirely:

Did you replace % with %% for BOTH .ifc directives in DEFINE_EXTABLE_TYPE_REG? ;)

@nathanchance
Copy link
Member Author

Did you replace % with %% for BOTH .ifc directives in DEFINE_EXTABLE_TYPE_REG? ;)

Nope... This works!

diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h
index 95bb23082b87..5b06676538ed 100644
--- a/arch/x86/include/asm/asm.h
+++ b/arch/x86/include/asm/asm.h
@@ -152,30 +152,37 @@
 
 #else /* ! __ASSEMBLY__ */
 
-asm(
-"	.macro extable_type_reg type:req reg:req\n"
-"	.set found, 0\n"
-"	.set regnr, 0\n"
-"	.irp rs,rax,rcx,rdx,rbx,rsp,rbp,rsi,rdi,r8,r9,r10,r11,r12,r13,r14,r15\n"
-"	.ifc \\reg, %\\rs\n"
-"	.set found, found+1\n"
-"	.long \\type + (regnr << 8)\n"
-"	.endif\n"
-"	.set regnr, regnr+1\n"
-"	.endr\n"
-"	.set regnr, 0\n"
-"	.irp rs,eax,ecx,edx,ebx,esp,ebp,esi,edi,r8d,r9d,r10d,r11d,r12d,r13d,r14d,r15d\n"
-"	.ifc \\reg, %\\rs\n"
-"	.set found, found+1\n"
-"	.long \\type + (regnr << 8)\n"
-"	.endif\n"
-"	.set regnr, regnr+1\n"
-"	.endr\n"
-"	.if (found != 1)\n"
-"	.error \"extable_type_reg: bad register argument\"\n"
-"	.endif\n"
+# define DEFINE_EXTABLE_TYPE_REG \
+"	.macro extable_type_reg type:req reg:req\n"						\
+"	.set found, 0\n"									\
+"	.set regnr, 0\n"									\
+"	.irp rs,rax,rcx,rdx,rbx,rsp,rbp,rsi,rdi,r8,r9,r10,r11,r12,r13,r14,r15\n"		\
+"	.ifc \\reg, %%\\rs\n"									\
+"	.set found, found+1\n"									\
+"	.long \\type + (regnr << 8)\n"								\
+"	.endif\n"										\
+"	.set regnr, regnr+1\n"									\
+"	.endr\n"										\
+"	.set regnr, 0\n"									\
+"	.irp rs,eax,ecx,edx,ebx,esp,ebp,esi,edi,r8d,r9d,r10d,r11d,r12d,r13d,r14d,r15d\n"	\
+"	.ifc \\reg, %%\\rs\n"									\
+"	.set found, found+1\n"									\
+"	.long \\type + (regnr << 8)\n"								\
+"	.endif\n"										\
+"	.set regnr, regnr+1\n"									\
+"	.endr\n"										\
+"	.if (found != 1)\n"									\
+"	.error \"extable_type_reg: bad register argument\"\n"					\
+"	.endif\n"										\
 "	.endm\n"
-);
+
+# define UNDEFINE_EXTABLE_TYPE_REG \
+"	.purgem extable_type_reg\n"
+
+# define __extable_type_reg(type, reg) \
+	DEFINE_EXTABLE_TYPE_REG								\
+"	extable_type_reg type=" __stringify(type) ", reg=" __stringify(reg) " \n"	\
+	UNDEFINE_EXTABLE_TYPE_REG
 
 # define _ASM_EXTABLE_TYPE(from, to, type)			\
 	" .pushsection \"__ex_table\",\"a\"\n"			\
@@ -185,12 +192,12 @@ asm(
 	" .long " __stringify(type) " \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"						\
-	"extable_type_reg reg=" __stringify(reg) ", type=" __stringify(type) " \n"\
+# define _ASM_EXTABLE_TYPE_REG(from, to, type, reg)	\
+	" .pushsection \"__ex_table\",\"a\"\n"		\
+	" .balign 4\n"					\
+	" .long (" #from ") - .\n"			\
+	" .long (" #to ") - .\n"			\
+	__extable_type_reg(type, reg)			\
 	" .popsection\n"
 
 /* For C file, we already have NOKPROBE_SYMBOL macro */

@nathanchance
Copy link
Member Author

Patch submitted: https://lore.kernel.org/r/[email protected]/

@nathanchance nathanchance added [BUG] linux-next This is an issue only seen in linux-next [PATCH] Submitted A patch has been submitted for review labels Dec 10, 2021
@nathanchance nathanchance self-assigned this Dec 10, 2021
@nathanchance
Copy link
Member Author

@nathanchance nathanchance added [FIXED][LINUX] development cycle This bug was only present and fixed in a -next or -rc cycle and removed [PATCH] Submitted A patch has been submitted for review labels Dec 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[BUG] linux-next This is an issue only seen in linux-next [FEATURE] LTO Related to building the kernel with LLVM Link Time Optimization [FIXED][LINUX] development cycle This bug was only present and fixed in a -next or -rc cycle [Reported-by] kbuild test robot Reported-by: kbuild test robot <[email protected]> [TOOL] integrated-as The issue is relevant to LLVM integrated assembler
Projects
None yet
Development

No branches or pull requests

2 participants