Skip to content

Commit 0646c28

Browse files
chleroympe
authored andcommitted
objtool: Use target file endianness instead of a compiled constant
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. Tested-by: Naveen N. Rao <[email protected]> Reviewed-by: Naveen N. Rao <[email protected]> Acked-by: Josh Poimboeuf <[email protected]> Acked-by: Peter Zijlstra (Intel) <[email protected]> Signed-off-by: Christophe Leroy <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent efb11fd commit 0646c28

File tree

6 files changed

+30
-31
lines changed

6 files changed

+30
-31
lines changed

tools/objtool/arch/x86/include/arch/endianness.h

Lines changed: 0 additions & 9 deletions
This file was deleted.

tools/objtool/check.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2100,7 +2100,7 @@ static int read_unwind_hints(struct objtool_file *file)
21002100
return -1;
21012101
}
21022102

2103-
cfi.cfa.offset = bswap_if_needed(hint->sp_offset);
2103+
cfi.cfa.offset = bswap_if_needed(file->elf, hint->sp_offset);
21042104
cfi.type = hint->type;
21052105
cfi.end = hint->end;
21062106

tools/objtool/include/objtool/endianness.h

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,33 @@
22
#ifndef _OBJTOOL_ENDIANNESS_H
33
#define _OBJTOOL_ENDIANNESS_H
44

5-
#include <arch/endianness.h>
65
#include <linux/kernel.h>
76
#include <endian.h>
8-
9-
#ifndef __TARGET_BYTE_ORDER
10-
#error undefined arch __TARGET_BYTE_ORDER
11-
#endif
12-
13-
#if __BYTE_ORDER != __TARGET_BYTE_ORDER
14-
#define __NEED_BSWAP 1
15-
#else
16-
#define __NEED_BSWAP 0
17-
#endif
7+
#include <objtool/elf.h>
188

199
/*
20-
* Does a byte swap if target endianness doesn't match the host, i.e. cross
10+
* Does a byte swap if target file endianness doesn't match the host, i.e. cross
2111
* compilation for little endian on big endian and vice versa.
2212
* To be used for multi-byte values conversion, which are read from / about
2313
* to be written to a target native endianness ELF file.
2414
*/
25-
#define bswap_if_needed(val) \
15+
static inline bool need_bswap(struct elf *elf)
16+
{
17+
return (__BYTE_ORDER == __LITTLE_ENDIAN) ^
18+
(elf->ehdr.e_ident[EI_DATA] == ELFDATA2LSB);
19+
}
20+
21+
#define bswap_if_needed(elf, val) \
2622
({ \
2723
__typeof__(val) __ret; \
24+
bool __need_bswap = need_bswap(elf); \
2825
switch (sizeof(val)) { \
29-
case 8: __ret = __NEED_BSWAP ? bswap_64(val) : (val); break; \
30-
case 4: __ret = __NEED_BSWAP ? bswap_32(val) : (val); break; \
31-
case 2: __ret = __NEED_BSWAP ? bswap_16(val) : (val); break; \
26+
case 8: \
27+
__ret = __need_bswap ? bswap_64(val) : (val); break; \
28+
case 4: \
29+
__ret = __need_bswap ? bswap_32(val) : (val); break; \
30+
case 2: \
31+
__ret = __need_bswap ? bswap_16(val) : (val); break; \
3232
default: \
3333
BUILD_BUG(); break; \
3434
} \

tools/objtool/orc_dump.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ int orc_dump(const char *_objname)
7676
GElf_Rela rela;
7777
GElf_Sym sym;
7878
Elf_Data *data, *symtab = NULL, *rela_orc_ip = NULL;
79+
struct elf dummy_elf = {};
7980

8081

8182
objname = _objname;
@@ -94,6 +95,12 @@ int orc_dump(const char *_objname)
9495
return -1;
9596
}
9697

98+
if (!elf64_getehdr(elf)) {
99+
WARN_ELF("elf64_getehdr");
100+
return -1;
101+
}
102+
memcpy(&dummy_elf.ehdr, elf64_getehdr(elf), sizeof(dummy_elf.ehdr));
103+
97104
if (elf_getshdrnum(elf, &nr_sections)) {
98105
WARN_ELF("elf_getshdrnum");
99106
return -1;
@@ -198,11 +205,11 @@ int orc_dump(const char *_objname)
198205

199206
printf(" sp:");
200207

201-
print_reg(orc[i].sp_reg, bswap_if_needed(orc[i].sp_offset));
208+
print_reg(orc[i].sp_reg, bswap_if_needed(&dummy_elf, orc[i].sp_offset));
202209

203210
printf(" bp:");
204211

205-
print_reg(orc[i].bp_reg, bswap_if_needed(orc[i].bp_offset));
212+
print_reg(orc[i].bp_reg, bswap_if_needed(&dummy_elf, orc[i].bp_offset));
206213

207214
printf(" type:%s end:%d\n",
208215
orc_type_name(orc[i].type), orc[i].end);

tools/objtool/orc_gen.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,8 @@ static int write_orc_entry(struct elf *elf, struct section *orc_sec,
9797
/* populate ORC data */
9898
orc = (struct orc_entry *)orc_sec->data->d_buf + idx;
9999
memcpy(orc, o, sizeof(*orc));
100-
orc->sp_offset = bswap_if_needed(orc->sp_offset);
101-
orc->bp_offset = bswap_if_needed(orc->bp_offset);
100+
orc->sp_offset = bswap_if_needed(elf, orc->sp_offset);
101+
orc->bp_offset = bswap_if_needed(elf, orc->bp_offset);
102102

103103
/* populate reloc for ip */
104104
if (elf_add_reloc_to_insn(elf, ip_sec, idx * sizeof(int), R_X86_64_PC32,

tools/objtool/special.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ static int get_alt_entry(struct elf *elf, struct special_entry *entry,
8787
if (entry->feature) {
8888
unsigned short feature;
8989

90-
feature = bswap_if_needed(*(unsigned short *)(sec->data->d_buf +
90+
feature = bswap_if_needed(elf,
91+
*(unsigned short *)(sec->data->d_buf +
9192
offset +
9293
entry->feature));
9394
arch_handle_alternative(feature, alt);

0 commit comments

Comments
 (0)