0001
0002
0003
0004
0005
0006
0007
0008 #ifndef REMOTEPROC_ELF_LOADER_H
0009 #define REMOTEPROC_ELF_LOADER_H
0010
0011 #include <linux/elf.h>
0012 #include <linux/types.h>
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 static inline u8 fw_elf_get_class(const struct firmware *fw)
0024 {
0025 struct elf32_hdr *ehdr = (struct elf32_hdr *)fw->data;
0026
0027 return ehdr->e_ident[EI_CLASS];
0028 }
0029
0030 static inline void elf_hdr_init_ident(struct elf32_hdr *hdr, u8 class)
0031 {
0032 memcpy(hdr->e_ident, ELFMAG, SELFMAG);
0033 hdr->e_ident[EI_CLASS] = class;
0034 hdr->e_ident[EI_DATA] = ELFDATA2LSB;
0035 hdr->e_ident[EI_VERSION] = EV_CURRENT;
0036 hdr->e_ident[EI_OSABI] = ELFOSABI_NONE;
0037 }
0038
0039
0040 #define ELF_GEN_FIELD_GET_SET(__s, __field, __type) \
0041 static inline __type elf_##__s##_get_##__field(u8 class, const void *arg) \
0042 { \
0043 if (class == ELFCLASS32) \
0044 return (__type) ((const struct elf32_##__s *) arg)->__field; \
0045 else \
0046 return (__type) ((const struct elf64_##__s *) arg)->__field; \
0047 } \
0048 static inline void elf_##__s##_set_##__field(u8 class, void *arg, \
0049 __type value) \
0050 { \
0051 if (class == ELFCLASS32) \
0052 ((struct elf32_##__s *) arg)->__field = (__type) value; \
0053 else \
0054 ((struct elf64_##__s *) arg)->__field = (__type) value; \
0055 }
0056
0057 ELF_GEN_FIELD_GET_SET(hdr, e_entry, u64)
0058 ELF_GEN_FIELD_GET_SET(hdr, e_phnum, u16)
0059 ELF_GEN_FIELD_GET_SET(hdr, e_shnum, u16)
0060 ELF_GEN_FIELD_GET_SET(hdr, e_phoff, u64)
0061 ELF_GEN_FIELD_GET_SET(hdr, e_shoff, u64)
0062 ELF_GEN_FIELD_GET_SET(hdr, e_shstrndx, u16)
0063 ELF_GEN_FIELD_GET_SET(hdr, e_machine, u16)
0064 ELF_GEN_FIELD_GET_SET(hdr, e_type, u16)
0065 ELF_GEN_FIELD_GET_SET(hdr, e_version, u32)
0066 ELF_GEN_FIELD_GET_SET(hdr, e_ehsize, u32)
0067 ELF_GEN_FIELD_GET_SET(hdr, e_phentsize, u16)
0068 ELF_GEN_FIELD_GET_SET(hdr, e_shentsize, u16)
0069
0070 ELF_GEN_FIELD_GET_SET(phdr, p_paddr, u64)
0071 ELF_GEN_FIELD_GET_SET(phdr, p_vaddr, u64)
0072 ELF_GEN_FIELD_GET_SET(phdr, p_filesz, u64)
0073 ELF_GEN_FIELD_GET_SET(phdr, p_memsz, u64)
0074 ELF_GEN_FIELD_GET_SET(phdr, p_type, u32)
0075 ELF_GEN_FIELD_GET_SET(phdr, p_offset, u64)
0076 ELF_GEN_FIELD_GET_SET(phdr, p_flags, u32)
0077 ELF_GEN_FIELD_GET_SET(phdr, p_align, u64)
0078
0079 ELF_GEN_FIELD_GET_SET(shdr, sh_type, u32)
0080 ELF_GEN_FIELD_GET_SET(shdr, sh_flags, u32)
0081 ELF_GEN_FIELD_GET_SET(shdr, sh_entsize, u16)
0082 ELF_GEN_FIELD_GET_SET(shdr, sh_size, u64)
0083 ELF_GEN_FIELD_GET_SET(shdr, sh_offset, u64)
0084 ELF_GEN_FIELD_GET_SET(shdr, sh_name, u32)
0085 ELF_GEN_FIELD_GET_SET(shdr, sh_addr, u64)
0086
0087 #define ELF_STRUCT_SIZE(__s) \
0088 static inline unsigned long elf_size_of_##__s(u8 class) \
0089 { \
0090 if (class == ELFCLASS32)\
0091 return sizeof(struct elf32_##__s); \
0092 else \
0093 return sizeof(struct elf64_##__s); \
0094 }
0095
0096 ELF_STRUCT_SIZE(shdr)
0097 ELF_STRUCT_SIZE(phdr)
0098 ELF_STRUCT_SIZE(hdr)
0099
0100 static inline unsigned int elf_strtbl_add(const char *name, void *ehdr, u8 class, size_t *index)
0101 {
0102 u16 shstrndx = elf_hdr_get_e_shstrndx(class, ehdr);
0103 void *shdr;
0104 char *strtab;
0105 size_t idx, ret;
0106
0107 shdr = ehdr + elf_size_of_hdr(class) + shstrndx * elf_size_of_shdr(class);
0108 strtab = ehdr + elf_shdr_get_sh_offset(class, shdr);
0109 idx = index ? *index : 0;
0110 if (!strtab || !name)
0111 return 0;
0112
0113 ret = idx;
0114 strcpy((strtab + idx), name);
0115 idx += strlen(name) + 1;
0116 if (index)
0117 *index = idx;
0118
0119 return ret;
0120 }
0121
0122 #endif