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