* [RFC PATCH v1] objtool: Use target file endianness instead of a compiled constant
@ 2022-03-31 7:52 Christophe Leroy
2022-03-31 8:08 ` Peter Zijlstra
0 siblings, 1 reply; 3+ messages in thread
From: Christophe Leroy @ 2022-03-31 7:52 UTC (permalink / raw)
To: Sathvika Vasireddy, Josh Poimboeuf, Peter Zijlstra
Cc: Christophe Leroy, linux-kernel, linuxppc-dev
Some architectures like powerpc support both endianness, it's
therefore not possible to fix the endianness via arch/endianness.h
because there is no easy way to get the target endianness at
build time.
Use the endianness recorded in the file objtool is working on.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
.../arch/x86/include/arch/endianness.h | 9 ------
tools/objtool/check.c | 2 +-
tools/objtool/include/objtool/endianness.h | 29 +++++++++----------
tools/objtool/orc_dump.c | 4 +--
tools/objtool/orc_gen.c | 4 +--
tools/objtool/special.c | 3 +-
6 files changed, 20 insertions(+), 31 deletions(-)
delete mode 100644 tools/objtool/arch/x86/include/arch/endianness.h
diff --git a/tools/objtool/arch/x86/include/arch/endianness.h b/tools/objtool/arch/x86/include/arch/endianness.h
deleted file mode 100644
index 7c362527da20..000000000000
--- a/tools/objtool/arch/x86/include/arch/endianness.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef _ARCH_ENDIANNESS_H
-#define _ARCH_ENDIANNESS_H
-
-#include <endian.h>
-
-#define __TARGET_BYTE_ORDER __LITTLE_ENDIAN
-
-#endif /* _ARCH_ENDIANNESS_H */
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 6de5085e3e5a..378d4e2de285 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -1941,7 +1941,7 @@ static int read_unwind_hints(struct objtool_file *file)
return -1;
}
- cfi.cfa.offset = bswap_if_needed(hint->sp_offset);
+ cfi.cfa.offset = bswap_if_needed(&file->elf->ehdr, hint->sp_offset);
cfi.type = hint->type;
cfi.end = hint->end;
diff --git a/tools/objtool/include/objtool/endianness.h b/tools/objtool/include/objtool/endianness.h
index 10241341eff3..2c7469a7645b 100644
--- a/tools/objtool/include/objtool/endianness.h
+++ b/tools/objtool/include/objtool/endianness.h
@@ -2,33 +2,30 @@
#ifndef _OBJTOOL_ENDIANNESS_H
#define _OBJTOOL_ENDIANNESS_H
-#include <arch/endianness.h>
#include <linux/kernel.h>
#include <endian.h>
-
-#ifndef __TARGET_BYTE_ORDER
-#error undefined arch __TARGET_BYTE_ORDER
-#endif
-
-#if __BYTE_ORDER != __TARGET_BYTE_ORDER
-#define __NEED_BSWAP 1
-#else
-#define __NEED_BSWAP 0
-#endif
+#include <objtool/elf.h>
/*
- * Does a byte swap if target endianness doesn't match the host, i.e. cross
+ * Does a byte swap if target file endianness doesn't match the host, i.e. cross
* compilation for little endian on big endian and vice versa.
* To be used for multi-byte values conversion, which are read from / about
* to be written to a target native endianness ELF file.
*/
-#define bswap_if_needed(val) \
+static inline bool need_bswap(GElf_Ehdr *ehdr)
+{
+ return (__BYTE_ORDER == __LITTLE_ENDIAN) ^
+ (ehdr->e_ident[EI_DATA] == ELFDATA2LSB);
+}
+
+#define bswap_if_needed(ehdr, val) \
({ \
__typeof__(val) __ret; \
+ bool __need_bswap = need_bswap(ehdr); \
switch (sizeof(val)) { \
- case 8: __ret = __NEED_BSWAP ? bswap_64(val) : (val); break; \
- case 4: __ret = __NEED_BSWAP ? bswap_32(val) : (val); break; \
- case 2: __ret = __NEED_BSWAP ? bswap_16(val) : (val); break; \
+ case 8: __ret = __need_bswap ? bswap_64(val) : (val); break; \
+ case 4: __ret = __need_bswap ? bswap_32(val) : (val); break; \
+ case 2: __ret = __need_bswap ? bswap_16(val) : (val); break; \
default: \
BUILD_BUG(); break; \
} \
diff --git a/tools/objtool/orc_dump.c b/tools/objtool/orc_dump.c
index f5a8508c42d6..5a51586c6ad2 100644
--- a/tools/objtool/orc_dump.c
+++ b/tools/objtool/orc_dump.c
@@ -198,11 +198,11 @@ int orc_dump(const char *_objname)
printf(" sp:");
- print_reg(orc[i].sp_reg, bswap_if_needed(orc[i].sp_offset));
+ print_reg(orc[i].sp_reg, bswap_if_needed(elf64_getehdr(elf), orc[i].sp_offset));
printf(" bp:");
- print_reg(orc[i].bp_reg, bswap_if_needed(orc[i].bp_offset));
+ print_reg(orc[i].bp_reg, bswap_if_needed(elf64_getehdr(elf), orc[i].bp_offset));
printf(" type:%s end:%d\n",
orc_type_name(orc[i].type), orc[i].end);
diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c
index dd3c64af9db2..63c36ed284a5 100644
--- a/tools/objtool/orc_gen.c
+++ b/tools/objtool/orc_gen.c
@@ -97,8 +97,8 @@ static int write_orc_entry(struct elf *elf, struct section *orc_sec,
/* populate ORC data */
orc = (struct orc_entry *)orc_sec->data->d_buf + idx;
memcpy(orc, o, sizeof(*orc));
- orc->sp_offset = bswap_if_needed(orc->sp_offset);
- orc->bp_offset = bswap_if_needed(orc->bp_offset);
+ orc->sp_offset = bswap_if_needed(&elf->ehdr, orc->sp_offset);
+ orc->bp_offset = bswap_if_needed(&elf->ehdr, orc->bp_offset);
/* populate reloc for ip */
if (elf_add_reloc_to_insn(elf, ip_sec, idx * sizeof(int), R_X86_64_PC32,
diff --git a/tools/objtool/special.c b/tools/objtool/special.c
index e2223dd91c37..ae563c524416 100644
--- a/tools/objtool/special.c
+++ b/tools/objtool/special.c
@@ -87,7 +87,8 @@ static int get_alt_entry(struct elf *elf, struct special_entry *entry,
if (entry->feature) {
unsigned short feature;
- feature = bswap_if_needed(*(unsigned short *)(sec->data->d_buf +
+ feature = bswap_if_needed(&elf->ehdr,
+ *(unsigned short *)(sec->data->d_buf +
offset +
entry->feature));
arch_handle_alternative(feature, alt);
--
2.35.1
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [RFC PATCH v1] objtool: Use target file endianness instead of a compiled constant
2022-03-31 7:52 [RFC PATCH v1] objtool: Use target file endianness instead of a compiled constant Christophe Leroy
@ 2022-03-31 8:08 ` Peter Zijlstra
2022-03-31 8:10 ` Christophe Leroy
0 siblings, 1 reply; 3+ messages in thread
From: Peter Zijlstra @ 2022-03-31 8:08 UTC (permalink / raw)
To: Christophe Leroy
Cc: Sathvika Vasireddy, Josh Poimboeuf, linux-kernel, linuxppc-dev
On Thu, Mar 31, 2022 at 09:52:07AM +0200, Christophe Leroy wrote:
> Some architectures like powerpc support both endianness, it's
> therefore not possible to fix the endianness via arch/endianness.h
> because there is no easy way to get the target endianness at
> build time.
>
> Use the endianness recorded in the file objtool is working on.
>
> +#include <objtool/elf.h>
>
> /*
> - * Does a byte swap if target endianness doesn't match the host, i.e. cross
> + * Does a byte swap if target file endianness doesn't match the host, i.e. cross
> * compilation for little endian on big endian and vice versa.
> * To be used for multi-byte values conversion, which are read from / about
> * to be written to a target native endianness ELF file.
> */
> -#define bswap_if_needed(val) \
> +static inline bool need_bswap(GElf_Ehdr *ehdr)
> +{
> + return (__BYTE_ORDER == __LITTLE_ENDIAN) ^
> + (ehdr->e_ident[EI_DATA] == ELFDATA2LSB);
> +}
> +
> +#define bswap_if_needed(ehdr, val) \
> ({ \
> __typeof__(val) __ret; \
> + bool __need_bswap = need_bswap(ehdr); \
> switch (sizeof(val)) { \
> - case 8: __ret = __NEED_BSWAP ? bswap_64(val) : (val); break; \
> - case 4: __ret = __NEED_BSWAP ? bswap_32(val) : (val); break; \
> - case 2: __ret = __NEED_BSWAP ? bswap_16(val) : (val); break; \
> + case 8: __ret = __need_bswap ? bswap_64(val) : (val); break; \
> + case 4: __ret = __need_bswap ? bswap_32(val) : (val); break; \
> + case 2: __ret = __need_bswap ? bswap_16(val) : (val); break; \
> default: \
> BUILD_BUG(); break; \
> } \
Far less painfull that I imagined it would be,.. but I think I prefer
passing in elf, as opposed to elf->ehdr, would that work?
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [RFC PATCH v1] objtool: Use target file endianness instead of a compiled constant
2022-03-31 8:08 ` Peter Zijlstra
@ 2022-03-31 8:10 ` Christophe Leroy
0 siblings, 0 replies; 3+ messages in thread
From: Christophe Leroy @ 2022-03-31 8:10 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Sathvika Vasireddy, Josh Poimboeuf, linux-kernel@vger.kernel.org,
linuxppc-dev@lists.ozlabs.org
Le 31/03/2022 à 10:08, Peter Zijlstra a écrit :
> On Thu, Mar 31, 2022 at 09:52:07AM +0200, Christophe Leroy wrote:
>> Some architectures like powerpc support both endianness, it's
>> therefore not possible to fix the endianness via arch/endianness.h
>> because there is no easy way to get the target endianness at
>> build time.
>>
>> Use the endianness recorded in the file objtool is working on.
>>
>
>> +#include <objtool/elf.h>
>>
>> /*
>> - * Does a byte swap if target endianness doesn't match the host, i.e. cross
>> + * Does a byte swap if target file endianness doesn't match the host, i.e. cross
>> * compilation for little endian on big endian and vice versa.
>> * To be used for multi-byte values conversion, which are read from / about
>> * to be written to a target native endianness ELF file.
>> */
>> -#define bswap_if_needed(val) \
>> +static inline bool need_bswap(GElf_Ehdr *ehdr)
>> +{
>> + return (__BYTE_ORDER == __LITTLE_ENDIAN) ^
>> + (ehdr->e_ident[EI_DATA] == ELFDATA2LSB);
>> +}
>> +
>> +#define bswap_if_needed(ehdr, val) \
>> ({ \
>> __typeof__(val) __ret; \
>> + bool __need_bswap = need_bswap(ehdr); \
>> switch (sizeof(val)) { \
>> - case 8: __ret = __NEED_BSWAP ? bswap_64(val) : (val); break; \
>> - case 4: __ret = __NEED_BSWAP ? bswap_32(val) : (val); break; \
>> - case 2: __ret = __NEED_BSWAP ? bswap_16(val) : (val); break; \
>> + case 8: __ret = __need_bswap ? bswap_64(val) : (val); break; \
>> + case 4: __ret = __need_bswap ? bswap_32(val) : (val); break; \
>> + case 2: __ret = __need_bswap ? bswap_16(val) : (val); break; \
>> default: \
>> BUILD_BUG(); break; \
>> } \
>
> Far less painfull that I imagined it would be,.. but I think I prefer
> passing in elf, as opposed to elf->ehdr, would that work?
That's what I wanted to do in the beginning, but we don't have it in
orc_dump()
Christophe
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2022-03-31 8:10 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-03-31 7:52 [RFC PATCH v1] objtool: Use target file endianness instead of a compiled constant Christophe Leroy
2022-03-31 8:08 ` Peter Zijlstra
2022-03-31 8:10 ` Christophe Leroy
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox