1 /* i386 CPU-specific part of loadcore.c for 32-bit mode */
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2009 Free Software Foundation, Inc.
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
22 #include <grub/misc.h>
23 #include <grub/efiemu/efiemu.h>
24 #include <grub/cpu/efiemu.h>
26 #include <grub/i18n.h>
28 /* Check if EHDR is a valid ELF header. */
30 grub_arch_efiemu_check_header32 (void *ehdr
)
34 /* Check the magic numbers. */
35 return (e
->e_ident
[EI_CLASS
] == ELFCLASS32
36 && e
->e_ident
[EI_DATA
] == ELFDATA2LSB
37 && e
->e_machine
== EM_386
);
40 /* Relocate symbols. */
42 grub_arch_efiemu_relocate_symbols32 (grub_efiemu_segment_t segs
,
43 struct grub_efiemu_elf_sym
*elfsyms
,
51 grub_dprintf ("efiemu", "relocating symbols %d %d\n",
52 e
->e_shoff
, e
->e_shnum
);
54 for (i
= 0, s
= (Elf32_Shdr
*) ((char *) e
+ e
->e_shoff
);
56 i
++, s
= (Elf32_Shdr
*) ((char *) s
+ e
->e_shentsize
))
57 if (s
->sh_type
== SHT_REL
)
59 grub_efiemu_segment_t seg
;
60 grub_dprintf ("efiemu", "shtrel\n");
62 /* Find the target segment. */
63 for (seg
= segs
; seg
; seg
= seg
->next
)
64 if (seg
->section
== s
->sh_info
)
71 for (rel
= (Elf32_Rel
*) ((char *) e
+ s
->sh_offset
),
72 max
= rel
+ s
->sh_size
/ s
->sh_entsize
;
77 struct grub_efiemu_elf_sym sym
;
78 if (seg
->size
< rel
->r_offset
)
79 return grub_error (GRUB_ERR_BAD_MODULE
,
80 "reloc offset is out of the segment");
83 ((char *) grub_efiemu_mm_obtain_request (seg
->handle
)
84 + seg
->off
+ rel
->r_offset
);
85 sym
= elfsyms
[ELF32_R_SYM (rel
->r_info
)];
87 switch (ELF32_R_TYPE (rel
->r_info
))
90 err
= grub_efiemu_write_value (addr
, sym
.off
+ *addr
,
93 sizeof (grub_uint32_t
));
100 err
= grub_efiemu_write_value (addr
, sym
.off
+ *addr
102 - seg
->off
, sym
.handle
,
105 sizeof (grub_uint32_t
));
110 return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET
,
111 N_("relocation 0x%x is not implemented yet"),
112 ELF_R_TYPE (rel
->r_info
));
118 return GRUB_ERR_NONE
;