as: How to determine the section of symbols

Peter Zijlstra peterz@infradead.org
Tue Jul 16 10:56:00 GMT 2019


On Tue, Jul 16, 2019 at 12:07:10PM +0200, Peter Zijlstra wrote:

> Also, 'funnily' when you add:
> 
> 	".long disp"
> 
> to emit the calculated displacement, you do get an assembly error, but
> the (indirect) usage in .skip doesn't trigger this.

So given that when we cross sections, is_long=1 for as yet unspecified
raisins, I figured I'd try and store that in our table and use it as a
size override, but that got me assmeble errors *again* :/


/tmp/ccjvEgTu.s: Assembler messages:
/tmp/ccjvEgTu.s: Error: invalid operands (.text.unlikely and .text sections) for `-' when setting `disp'
../arch/x86/include/asm/jump_label.h:34: Error: invalid operands (.text.unlikely and *ABS* sections) for `>>'
../arch/x86/include/asm/jump_label.h:34: Error: invalid operands (.text.unlikely and *ABS* sections) for `>>'
/tmp/ccjvEgTu.s: Error: invalid operands (.text.unlikely and .text sections) for `-' when setting `disp'
../arch/x86/include/asm/jump_label.h:34: Error: invalid operands (.text.unlikely and *ABS* sections) for `>>'
../arch/x86/include/asm/jump_label.h:34: Error: invalid operands (.text.unlikely and *ABS* sections) for `>>'
make[3]: *** [../scripts/Makefile.build:279: arch/x86/kvm/vmx/nested.o] Error 1
make[3]: *** Waiting for unfinished jobs....
../arch/x86/include/asm/jump_label.h: Assembler messages:
../arch/x86/include/asm/jump_label.h:37: Warning: .space repeat count is zero, ignored
../arch/x86/include/asm/jump_label.h:38: Warning: .space repeat count is zero, ignored
../arch/x86/include/asm/jump_label.h:37: Warning: .space repeat count is zero, ignored
../arch/x86/include/asm/jump_label.h:38: Warning: .space repeat count is zero, ignored
/tmp/ccmK11Jw.s: Error: invalid operands (.text.unlikely and .text sections) for `-' when setting `disp'
../arch/x86/include/asm/jump_label.h:34: Error: invalid operands (.text.unlikely and *ABS* sections) for `>>'
../arch/x86/include/asm/jump_label.h:34: Error: invalid operands (.text.unlikely and *ABS* sections) for `>>'
/tmp/ccmK11Jw.s: Error: invalid operands (.text.unlikely and .text sections) for `-' when setting `disp'
../arch/x86/include/asm/jump_label.h:34: Error: invalid operands (.text.unlikely and *ABS* sections) for `>>'
../arch/x86/include/asm/jump_label.h:34: Error: invalid operands (.text.unlikely and *ABS* sections) for `>>'
/tmp/ccmK11Jw.s: Error: invalid operands (.text.unlikely and .text sections) for `-' when setting `disp'
../arch/x86/include/asm/jump_label.h:34: Error: invalid operands (.text.unlikely and *ABS* sections) for `>>'
../arch/x86/include/asm/jump_label.h:34: Error: invalid operands (.text.unlikely and *ABS* sections) for `>>'
make[3]: *** [../scripts/Makefile.build:279: arch/x86/kvm/vmx/vmx.o] Error 1
make[2]: *** [../scripts/Makefile.build:489: arch/x86/kvm] Error 2
make[1]: *** [/usr/src/linux-2.6/Makefile:1071: arch/x86] Error 2
make: *** [Makefile:179: sub-make] Error 2


---
diff --git a/arch/x86/include/asm/jump_label.h b/arch/x86/include/asm/jump_label.h
index 663ec7a1f19f..ecff560958e2 100644
--- a/arch/x86/include/asm/jump_label.h
+++ b/arch/x86/include/asm/jump_label.h
@@ -25,7 +25,7 @@
 	_ASM_ALIGN "\n\t"				\
 	".long 1b - . \n\t"				\
 	".long %l[l_yes] - . \n\t"			\
-	_ASM_PTR "%c0 + %c1 - .\n\t"			\
+	_ASM_PTR "%c0 + %c1 + (4*is_long) - .\n\t"	\
 	".popsection \n\t"
 
 static __always_inline bool arch_static_branch(struct static_key *key, bool branch)
@@ -70,7 +70,14 @@ static __always_inline bool arch_static_branch(struct static_key *key, bool bran
 static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch)
 {
 	asm_volatile_goto("1:"
+
+		".set disp, %l[l_yes] - (1b + 2) \n\t"
+		".set res, (disp >> 31) == (disp >> 7) \n\t"
+		".set is_byte, -res \n\t"
+		".set is_long, -(~res) \n\t"
+
 		"jmp %l[l_yes] \n\t"
+
 		JUMP_TABLE_ENTRY
 		: :  "i" (key), "i" (branch) : : l_yes);
 
diff --git a/arch/x86/kernel/jump_label.c b/arch/x86/kernel/jump_label.c
index 22379f62f0f7..9aba802e593f 100644
--- a/arch/x86/kernel/jump_label.c
+++ b/arch/x86/kernel/jump_label.c
@@ -36,7 +36,7 @@ static inline bool __jump_disp_is_byte(s32 disp)
 int arch_jump_entry_size(struct jump_entry *entry)
 {
 	s32 disp = jump_entry_target(entry) - jump_entry_code(entry);
-	if (__jump_disp_is_byte(disp))
+	if (!jump_entry_is_arch(entry) && __jump_disp_is_byte(disp))
 		return JMP8_INSN_SIZE;
 	return JMP32_INSN_SIZE;
 }
diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h
index 5cafdb7c3e9c..e97e40a3bb81 100644
--- a/include/linux/jump_label.h
+++ b/include/linux/jump_label.h
@@ -98,13 +98,14 @@ struct static_key {
  *	    0 if initially false
  * bit 1 => 1 if points to struct static_key_mod
  *	    0 if points to struct jump_entry
+ * bit 2 -- arch defined
  */
 	union {
 		unsigned long type;
 		struct jump_entry *entries;
 		struct static_key_mod *next;
 	};
-};
+} __aligned(1<<3);
 
 #else
 struct static_key {
@@ -137,7 +138,7 @@ static inline unsigned long jump_entry_target(const struct jump_entry *entry)
 
 static inline struct static_key *jump_entry_key(const struct jump_entry *entry)
 {
-	long offset = entry->key & ~3L;
+	long offset = entry->key & ~7L;
 
 	return (struct static_key *)((unsigned long)&entry->key + offset);
 }
@@ -156,7 +157,7 @@ static inline unsigned long jump_entry_target(const struct jump_entry *entry)
 
 static inline struct static_key *jump_entry_key(const struct jump_entry *entry)
 {
-	return (struct static_key *)((unsigned long)entry->key & ~3UL);
+	return (struct static_key *)((unsigned long)entry->key & ~7UL);
 }
 
 #endif
@@ -171,6 +172,11 @@ static inline bool jump_entry_is_init(const struct jump_entry *entry)
 	return (unsigned long)entry->key & 2UL;
 }
 
+static inline bool jump_entry_is_arch(const struct jump_entry *entry)
+{
+	return (unsigned long)entry->key & 4UL;
+}
+
 static inline void jump_entry_set_init(struct jump_entry *entry)
 {
 	entry->key |= 2;



More information about the Binutils mailing list