Adjust mips/dl.c for bigendian
This commit is contained in:
parent
60ddfad3da
commit
11d86592b7
1 changed files with 19 additions and 5 deletions
|
@ -34,7 +34,7 @@ grub_arch_dl_check_header (void *ehdr)
|
||||||
Elf_Ehdr *e = ehdr;
|
Elf_Ehdr *e = ehdr;
|
||||||
|
|
||||||
/* Check the magic numbers. */
|
/* Check the magic numbers. */
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef GRUB_CPU_WORDS_BIGENDIAN
|
||||||
if (e->e_ident[EI_CLASS] != ELFCLASS32
|
if (e->e_ident[EI_CLASS] != ELFCLASS32
|
||||||
|| e->e_ident[EI_DATA] != ELFDATA2MSB
|
|| e->e_ident[EI_DATA] != ELFDATA2MSB
|
||||||
|| e->e_machine != EM_MIPS)
|
|| e->e_machine != EM_MIPS)
|
||||||
|
@ -144,14 +144,14 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
|
||||||
rel < max;
|
rel < max;
|
||||||
rel++)
|
rel++)
|
||||||
{
|
{
|
||||||
Elf_Word *addr;
|
grub_uint8_t *addr;
|
||||||
Elf_Sym *sym;
|
Elf_Sym *sym;
|
||||||
|
|
||||||
if (seg->size < rel->r_offset)
|
if (seg->size < rel->r_offset)
|
||||||
return grub_error (GRUB_ERR_BAD_MODULE,
|
return grub_error (GRUB_ERR_BAD_MODULE,
|
||||||
"reloc offset is out of the segment");
|
"reloc offset is out of the segment");
|
||||||
|
|
||||||
addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset);
|
addr = (grub_uint8_t *) ((char *) seg->addr + rel->r_offset);
|
||||||
sym = (Elf_Sym *) ((char *) mod->symtab
|
sym = (Elf_Sym *) ((char *) mod->symtab
|
||||||
+ entsize * ELF_R_SYM (rel->r_info));
|
+ entsize * ELF_R_SYM (rel->r_info));
|
||||||
if (sym->st_value == (grub_addr_t) &__gnu_local_gp_dummy)
|
if (sym->st_value == (grub_addr_t) &__gnu_local_gp_dummy)
|
||||||
|
@ -164,6 +164,10 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
|
||||||
grub_uint32_t value;
|
grub_uint32_t value;
|
||||||
Elf_Rel *rel2;
|
Elf_Rel *rel2;
|
||||||
|
|
||||||
|
#ifdef GRUB_CPU_WORDS_BIGENDIAN
|
||||||
|
addr += 2;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Handle partner lo16 relocation. Lower part is
|
/* Handle partner lo16 relocation. Lower part is
|
||||||
treated as signed. Hence add 0x8000 to compensate.
|
treated as signed. Hence add 0x8000 to compensate.
|
||||||
*/
|
*/
|
||||||
|
@ -175,13 +179,20 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
|
||||||
&& ELF_R_TYPE (rel2->r_info) == R_MIPS_LO16)
|
&& ELF_R_TYPE (rel2->r_info) == R_MIPS_LO16)
|
||||||
{
|
{
|
||||||
value += *(grub_int16_t *)
|
value += *(grub_int16_t *)
|
||||||
((char *) seg->addr + rel2->r_offset);
|
((char *) seg->addr + rel2->r_offset
|
||||||
|
#ifdef GRUB_CPU_WORDS_BIGENDIAN
|
||||||
|
+ 2
|
||||||
|
#endif
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*(grub_uint16_t *) addr = (value >> 16) & 0xffff;
|
*(grub_uint16_t *) addr = (value >> 16) & 0xffff;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case R_MIPS_LO16:
|
case R_MIPS_LO16:
|
||||||
|
#ifdef GRUB_CPU_WORDS_BIGENDIAN
|
||||||
|
addr += 2;
|
||||||
|
#endif
|
||||||
*(grub_uint16_t *) addr += (sym->st_value) & 0xffff;
|
*(grub_uint16_t *) addr += (sym->st_value) & 0xffff;
|
||||||
break;
|
break;
|
||||||
case R_MIPS_32:
|
case R_MIPS_32:
|
||||||
|
@ -208,6 +219,9 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
|
||||||
case R_MIPS_GOT16:
|
case R_MIPS_GOT16:
|
||||||
case R_MIPS_CALL16:
|
case R_MIPS_CALL16:
|
||||||
/* FIXME: reuse*/
|
/* FIXME: reuse*/
|
||||||
|
#ifdef GRUB_CPU_WORDS_BIGENDIAN
|
||||||
|
addr += 2;
|
||||||
|
#endif
|
||||||
*gpptr = sym->st_value + *(grub_uint16_t *) addr;
|
*gpptr = sym->st_value + *(grub_uint16_t *) addr;
|
||||||
*(grub_uint16_t *) addr
|
*(grub_uint16_t *) addr
|
||||||
= sizeof (grub_uint32_t) * (gpptr - gp);
|
= sizeof (grub_uint32_t) * (gpptr - gp);
|
||||||
|
|
Loading…
Reference in a new issue