17786032eSVasily Gorbik /* SPDX-License-Identifier: GPL-2.0-or-later */ 27786032eSVasily Gorbik #ifndef _OBJTOOL_ENDIANNESS_H 37786032eSVasily Gorbik #define _OBJTOOL_ENDIANNESS_H 47786032eSVasily Gorbik 57786032eSVasily Gorbik #include <linux/kernel.h> 67786032eSVasily Gorbik #include <endian.h> 7*0646c28bSChristophe Leroy #include <objtool/elf.h> 87786032eSVasily Gorbik 97786032eSVasily Gorbik /* 10*0646c28bSChristophe Leroy * Does a byte swap if target file endianness doesn't match the host, i.e. cross 117786032eSVasily Gorbik * compilation for little endian on big endian and vice versa. 127786032eSVasily Gorbik * To be used for multi-byte values conversion, which are read from / about 137786032eSVasily Gorbik * to be written to a target native endianness ELF file. 147786032eSVasily Gorbik */ need_bswap(struct elf * elf)15*0646c28bSChristophe Leroystatic inline bool need_bswap(struct elf *elf) 16*0646c28bSChristophe Leroy { 17*0646c28bSChristophe Leroy return (__BYTE_ORDER == __LITTLE_ENDIAN) ^ 18*0646c28bSChristophe Leroy (elf->ehdr.e_ident[EI_DATA] == ELFDATA2LSB); 19*0646c28bSChristophe Leroy } 20*0646c28bSChristophe Leroy 21*0646c28bSChristophe Leroy #define bswap_if_needed(elf, val) \ 227786032eSVasily Gorbik ({ \ 237786032eSVasily Gorbik __typeof__(val) __ret; \ 24*0646c28bSChristophe Leroy bool __need_bswap = need_bswap(elf); \ 257786032eSVasily Gorbik switch (sizeof(val)) { \ 26*0646c28bSChristophe Leroy case 8: \ 27*0646c28bSChristophe Leroy __ret = __need_bswap ? bswap_64(val) : (val); break; \ 28*0646c28bSChristophe Leroy case 4: \ 29*0646c28bSChristophe Leroy __ret = __need_bswap ? bswap_32(val) : (val); break; \ 30*0646c28bSChristophe Leroy case 2: \ 31*0646c28bSChristophe Leroy __ret = __need_bswap ? bswap_16(val) : (val); break; \ 327786032eSVasily Gorbik default: \ 337786032eSVasily Gorbik BUILD_BUG(); break; \ 347786032eSVasily Gorbik } \ 357786032eSVasily Gorbik __ret; \ 367786032eSVasily Gorbik }) 377786032eSVasily Gorbik 387786032eSVasily Gorbik #endif /* _OBJTOOL_ENDIANNESS_H */ 39