| /* SPDX-License-Identifier: GPL-2.0-or-later */ |
| #ifndef _OBJTOOL_ENDIANNESS_H |
| #define _OBJTOOL_ENDIANNESS_H |
| |
| #include <linux/kernel.h> |
| #include <endian.h> |
| #include <objtool/elf.h> |
| |
| /* |
| * 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. |
| */ |
| static inline bool need_bswap(struct elf *elf) |
| { |
| return (__BYTE_ORDER == __LITTLE_ENDIAN) ^ |
| (elf->ehdr.e_ident[EI_DATA] == ELFDATA2LSB); |
| } |
| |
| #define bswap_if_needed(elf, val) \ |
| ({ \ |
| __typeof__(val) __ret; \ |
| bool __need_bswap = need_bswap(elf); \ |
| 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; \ |
| default: \ |
| BUILD_BUG(); break; \ |
| } \ |
| __ret; \ |
| }) |
| |
| #endif /* _OBJTOOL_ENDIANNESS_H */ |