1 /* SPDX-License-Identifier: GPL-2.0 */
3 * Remote processor elf helpers defines
5 * Copyright (C) 2020 Kalray, Inc.
8 #ifndef REMOTEPROC_ELF_LOADER_H
9 #define REMOTEPROC_ELF_LOADER_H
11 #include <linux/elf.h>
12 #include <linux/types.h>
15 * fw_elf_get_class - Get elf class
16 * @fw: the ELF firmware image
18 * Note that we use and elf32_hdr to access the class since the start of the
19 * struct is the same for both elf class
21 * Return: elf class of the firmware
23 static inline u8
fw_elf_get_class(const struct firmware
*fw
)
25 struct elf32_hdr
*ehdr
= (struct elf32_hdr
*)fw
->data
;
27 return ehdr
->e_ident
[EI_CLASS
];
30 static inline void elf_hdr_init_ident(struct elf32_hdr
*hdr
, u8
class)
32 memcpy(hdr
->e_ident
, ELFMAG
, SELFMAG
);
33 hdr
->e_ident
[EI_CLASS
] = class;
34 hdr
->e_ident
[EI_DATA
] = ELFDATA2LSB
;
35 hdr
->e_ident
[EI_VERSION
] = EV_CURRENT
;
36 hdr
->e_ident
[EI_OSABI
] = ELFOSABI_NONE
;
39 /* Generate getter and setter for a specific elf struct/field */
40 #define ELF_GEN_FIELD_GET_SET(__s, __field, __type) \
41 static inline __type elf_##__s##_get_##__field(u8 class, const void *arg) \
43 if (class == ELFCLASS32) \
44 return (__type) ((const struct elf32_##__s *) arg)->__field; \
46 return (__type) ((const struct elf64_##__s *) arg)->__field; \
48 static inline void elf_##__s##_set_##__field(u8 class, void *arg, \
51 if (class == ELFCLASS32) \
52 ((struct elf32_##__s *) arg)->__field = (__type) value; \
54 ((struct elf64_##__s *) arg)->__field = (__type) value; \
57 ELF_GEN_FIELD_GET_SET(hdr
, e_entry
, u64
)
58 ELF_GEN_FIELD_GET_SET(hdr
, e_phnum
, u16
)
59 ELF_GEN_FIELD_GET_SET(hdr
, e_shnum
, u16
)
60 ELF_GEN_FIELD_GET_SET(hdr
, e_phoff
, u64
)
61 ELF_GEN_FIELD_GET_SET(hdr
, e_shoff
, u64
)
62 ELF_GEN_FIELD_GET_SET(hdr
, e_shstrndx
, u16
)
63 ELF_GEN_FIELD_GET_SET(hdr
, e_machine
, u16
)
64 ELF_GEN_FIELD_GET_SET(hdr
, e_type
, u16
)
65 ELF_GEN_FIELD_GET_SET(hdr
, e_version
, u32
)
66 ELF_GEN_FIELD_GET_SET(hdr
, e_ehsize
, u32
)
67 ELF_GEN_FIELD_GET_SET(hdr
, e_phentsize
, u16
)
68 ELF_GEN_FIELD_GET_SET(hdr
, e_shentsize
, u16
)
70 ELF_GEN_FIELD_GET_SET(phdr
, p_paddr
, u64
)
71 ELF_GEN_FIELD_GET_SET(phdr
, p_vaddr
, u64
)
72 ELF_GEN_FIELD_GET_SET(phdr
, p_filesz
, u64
)
73 ELF_GEN_FIELD_GET_SET(phdr
, p_memsz
, u64
)
74 ELF_GEN_FIELD_GET_SET(phdr
, p_type
, u32
)
75 ELF_GEN_FIELD_GET_SET(phdr
, p_offset
, u64
)
76 ELF_GEN_FIELD_GET_SET(phdr
, p_flags
, u32
)
77 ELF_GEN_FIELD_GET_SET(phdr
, p_align
, u64
)
79 ELF_GEN_FIELD_GET_SET(shdr
, sh_type
, u32
)
80 ELF_GEN_FIELD_GET_SET(shdr
, sh_flags
, u32
)
81 ELF_GEN_FIELD_GET_SET(shdr
, sh_entsize
, u16
)
82 ELF_GEN_FIELD_GET_SET(shdr
, sh_size
, u64
)
83 ELF_GEN_FIELD_GET_SET(shdr
, sh_offset
, u64
)
84 ELF_GEN_FIELD_GET_SET(shdr
, sh_name
, u32
)
85 ELF_GEN_FIELD_GET_SET(shdr
, sh_addr
, u64
)
87 #define ELF_STRUCT_SIZE(__s) \
88 static inline unsigned long elf_size_of_##__s(u8 class) \
90 if (class == ELFCLASS32)\
91 return sizeof(struct elf32_##__s); \
93 return sizeof(struct elf64_##__s); \
100 static inline unsigned int elf_strtbl_add(const char *name
, void *ehdr
, u8
class, size_t *index
)
102 u16 shstrndx
= elf_hdr_get_e_shstrndx(class, ehdr
);
107 shdr
= ehdr
+ elf_size_of_hdr(class) + shstrndx
* elf_size_of_shdr(class);
108 strtab
= ehdr
+ elf_shdr_get_sh_offset(class, shdr
);
109 idx
= index
? *index
: 0;
110 if (!strtab
|| !name
)
114 strcpy((strtab
+ idx
), name
);
115 idx
+= strlen(name
) + 1;
122 #endif /* REMOTEPROC_ELF_LOADER_H */