5 #include <grub/module_verifier.h>
7 #include <grub/util/misc.h>
9 struct grub_module_verifier_arch archs
[] = {
10 { "i386", 4, 0, EM_386
, GRUB_MODULE_VERIFY_SUPPORTS_REL
, (int[]){
15 { "x86_64", 8, 0, EM_X86_64
, GRUB_MODULE_VERIFY_SUPPORTS_RELA
, (int[]){
18 /* R_X86_64_32, R_X86_64_32S are supported but shouldn't be used because of their limited range. */
26 { "powerpc", 4, 1, EM_PPC
, GRUB_MODULE_VERIFY_SUPPORTS_RELA
, (int[]){
27 GRUB_ELF_R_PPC_ADDR16_LO
,
28 GRUB_ELF_R_PPC_REL24
, /* It has limited range but GRUB adds trampolines when necessarry. */
29 GRUB_ELF_R_PPC_ADDR16_HA
,
30 GRUB_ELF_R_PPC_ADDR32
,
32 GRUB_ELF_R_PPC_PLTREL24
,
35 { "sparc64", 8, 1, EM_SPARCV9
, GRUB_MODULE_VERIFY_SUPPORTS_RELA
, (int[]){
36 R_SPARC_WDISP30
, /* It has limited range but GRUB adds trampolines when necessarry. */
43 /* Following 2 relocations have limited range but unfortunately
44 clang generates them, as it doesn't implement mcmodel=large properly.
45 At least our heap and core are under 4G, so it's not a problem
51 { "ia64", 8, 0, EM_IA_64
, GRUB_MODULE_VERIFY_SUPPORTS_RELA
, (int[]){
52 R_IA64_PCREL21B
, /* We should verify that it's pointing either
53 to a function or to a section in the same module.
54 Checking that external symbol is a function is
55 non-trivial and I have never seen this relocation used
56 for anything else, so assume that it always points to a
73 { "mipsel", 4, 0, EM_MIPS
, GRUB_MODULE_VERIFY_SUPPORTS_REL
| GRUB_MODULE_VERIFY_SUPPORTS_RELA
, (int[]){
84 { "mips", 4, 1, EM_MIPS
, GRUB_MODULE_VERIFY_SUPPORTS_REL
| GRUB_MODULE_VERIFY_SUPPORTS_RELA
, (int[]){
95 { "arm", 4, 0, EM_ARM
, GRUB_MODULE_VERIFY_SUPPORTS_REL
, (int[]){
96 /* Some relocations are range-limited but trampolines are added when necessarry. */
103 R_ARM_THM_MOVW_ABS_NC
,
108 { "arm64", 8, 0, EM_AARCH64
, GRUB_MODULE_VERIFY_SUPPORTS_REL
| GRUB_MODULE_VERIFY_SUPPORTS_RELA
, (int[]){
112 R_AARCH64_ADR_GOT_PAGE
,
113 R_AARCH64_LD64_GOT_LO12_NC
,
116 R_AARCH64_ADR_PREL_PG_HI21
,
117 R_AARCH64_ADD_ABS_LO12_NC
,
118 R_AARCH64_LDST64_ABS_LO12_NC
,
122 { "riscv32", 4, 0, EM_RISCV
, GRUB_MODULE_VERIFY_SUPPORTS_REL
| GRUB_MODULE_VERIFY_SUPPORTS_RELA
, (int[]){
143 R_RISCV_PCREL_LO12_I
,
144 R_RISCV_PCREL_LO12_S
,
150 { "riscv64", 8, 0, EM_RISCV
, GRUB_MODULE_VERIFY_SUPPORTS_REL
| GRUB_MODULE_VERIFY_SUPPORTS_RELA
, (int[]){
171 R_RISCV_PCREL_LO12_I
,
172 R_RISCV_PCREL_LO12_S
,
181 struct platform_whitelist
{
183 const char *platform
;
184 const char **whitelist_empty
;
187 static struct platform_whitelist whitelists
[] = {
188 {"i386", "xen", (const char *[]) {"all_video", 0}},
189 {"i386", "xen_pvh", (const char *[]) {"all_video", 0}},
190 {"x86_64", "xen", (const char *[]) {"all_video", 0}},
191 {"sparc64", "ieee1275", (const char *[]) {"all_video", 0}},
193 /* video is compiled-in on MIPS. */
194 {"mipsel", "loongson", (const char *[]) {"all_video", 0}},
195 {"mipsel", "qemu_mips", (const char *[]) {"all_video", 0}},
196 {"mipsel", "arc", (const char *[]) {"all_video", 0}},
197 {"mips", "qemu_mips", (const char *[]) {"all_video", 0}},
198 {"mips", "arc", (const char *[]) {"all_video", 0}},
203 main (int argc
, char **argv
)
206 unsigned arch
, whitelist
;
207 const char **whitelist_empty
= 0;
210 fprintf (stderr
, "usage: %s FILE ARCH PLATFORM\n", argv
[0]);
214 for (arch
= 0; arch
< ARRAY_SIZE(archs
); arch
++)
215 if (strcmp(archs
[arch
].name
, argv
[2]) == 0)
217 if (arch
== ARRAY_SIZE(archs
))
218 grub_util_error("%s: unknown arch: %s", argv
[1], argv
[2]);
220 for (whitelist
= 0; whitelist
< ARRAY_SIZE(whitelists
); whitelist
++)
221 if (strcmp(whitelists
[whitelist
].arch
, argv
[2]) == 0
222 && strcmp(whitelists
[whitelist
].platform
, argv
[3]) == 0)
224 if (whitelist
!= ARRAY_SIZE(whitelists
))
225 whitelist_empty
= whitelists
[whitelist
].whitelist_empty
;
227 module_size
= grub_util_get_image_size (argv
[1]);
228 module_img
= grub_util_read_image (argv
[1]);
229 if (archs
[arch
].voidp_sizeof
== 8)
230 grub_module_verify64(argv
[1], module_img
, module_size
, &archs
[arch
], whitelist_empty
);
232 grub_module_verify32(argv
[1], module_img
, module_size
, &archs
[arch
], whitelist_empty
);