1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 #ifndef _OBJTOOL_ENDIANNESS_H 3 #define _OBJTOOL_ENDIANNESS_H 4 5 #include <linux/kernel.h> 6 #include <endian.h> 7 8 /* 9 * Does a byte swap if target file endianness doesn't match the host, i.e. cross 10 * compilation for little endian on big endian and vice versa. 11 * To be used for multi-byte values conversion, which are read from / about 12 * to be written to a target native endianness ELF file. 13 */ 14 static inline bool need_bswap(GElf_Ehdr *ehdr) 15 { 16 return (__BYTE_ORDER == __LITTLE_ENDIAN) ^ 17 (ehdr->e_ident[EI_DATA] == ELFDATA2LSB); 18 } 19 20 #define __bswap_if_needed(ehdr, val) \ 21 ({ \ 22 __typeof__(val) __ret; \ 23 bool __need_bswap = need_bswap(ehdr); \ 24 switch (sizeof(val)) { \ 25 case 8: \ 26 __ret = __need_bswap ? bswap_64(val) : (val); break; \ 27 case 4: \ 28 __ret = __need_bswap ? bswap_32(val) : (val); break; \ 29 case 2: \ 30 __ret = __need_bswap ? bswap_16(val) : (val); break; \ 31 default: \ 32 BUILD_BUG(); break; \ 33 } \ 34 __ret; \ 35 }) 36 37 #endif /* _OBJTOOL_ENDIANNESS_H */ 38