time & reloc
This commit is contained in:
parent
6315da8831
commit
3f9f11b6d2
3 changed files with 99 additions and 10 deletions
|
@ -267,12 +267,15 @@ grub_disk_open (const char *name)
|
|||
|
||||
for (dev = grub_disk_dev_list; dev; dev = dev->next)
|
||||
{
|
||||
grub_printf ("open: %p\n", dev->open);
|
||||
grub_getkey ();
|
||||
if ((dev->open) (raw, disk) == GRUB_ERR_NONE)
|
||||
break;
|
||||
else if (grub_errno == GRUB_ERR_UNKNOWN_DEVICE)
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
else
|
||||
goto fail;
|
||||
grub_printf ("survived\n");
|
||||
}
|
||||
|
||||
if (! dev)
|
||||
|
|
103
kern/mips/dl.c
103
kern/mips/dl.c
|
@ -22,6 +22,8 @@
|
|||
#include <grub/misc.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/cpu/types.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/cpu/dl.h>
|
||||
|
||||
/* Check if EHDR is a valid ELF header. */
|
||||
grub_err_t
|
||||
|
@ -52,6 +54,9 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
|
|||
Elf_Shdr *s;
|
||||
Elf_Word entsize;
|
||||
unsigned i;
|
||||
grub_size_t gp_size = 0;
|
||||
/* FIXME: suboptimal. */
|
||||
grub_uint32_t *gp, *gpptr;
|
||||
|
||||
/* Find a symbol table. */
|
||||
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
|
||||
|
@ -65,6 +70,45 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
|
|||
|
||||
entsize = s->sh_entsize;
|
||||
|
||||
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
|
||||
i < e->e_shnum;
|
||||
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
|
||||
if (s->sh_type == SHT_REL)
|
||||
{
|
||||
grub_dl_segment_t seg;
|
||||
|
||||
/* Find the target segment. */
|
||||
for (seg = mod->segment; seg; seg = seg->next)
|
||||
if (seg->section == s->sh_info)
|
||||
break;
|
||||
|
||||
if (seg)
|
||||
{
|
||||
Elf_Rel *rel, *max;
|
||||
|
||||
for (rel = (Elf_Rel *) ((char *) e + s->sh_offset),
|
||||
max = rel + s->sh_size / s->sh_entsize;
|
||||
rel < max;
|
||||
rel++)
|
||||
switch (ELF_R_TYPE (rel->r_info))
|
||||
{
|
||||
case R_MIPS_GOT16:
|
||||
case R_MIPS_CALL16:
|
||||
case R_MIPS_GPREL32:
|
||||
gp_size += 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gp_size > 0x08000)
|
||||
return grub_error (GRUB_ERR_OUT_OF_RANGE, "__gnu_local_gp is too big\n");
|
||||
|
||||
gpptr = gp = grub_malloc (gp_size);
|
||||
if (!gp)
|
||||
return grub_errno;
|
||||
grub_printf ("gp=%p\n", gp);
|
||||
|
||||
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
|
||||
i < e->e_shnum;
|
||||
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
|
||||
|
@ -96,19 +140,62 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
|
|||
addr = (Elf_Word *) ((char *) seg->addr + rel->r_offset);
|
||||
sym = (Elf_Sym *) ((char *) mod->symtab
|
||||
+ entsize * ELF_R_SYM (rel->r_info));
|
||||
if (sym->st_value == (grub_addr_t) &__gnu_local_gp)
|
||||
sym->st_value = (grub_addr_t) gp;
|
||||
|
||||
switch (ELF_R_TYPE (rel->r_info))
|
||||
{
|
||||
#if 0
|
||||
case R_386_32:
|
||||
*addr += sym->st_value;
|
||||
break;
|
||||
case R_MIPS_HI16:
|
||||
{
|
||||
grub_uint32_t value;
|
||||
|
||||
case R_386_PC32:
|
||||
*addr += (sym->st_value - (Elf_Word) seg->addr
|
||||
- rel->r_offset);
|
||||
/* Handle partner lo16 relocation. Lower part is
|
||||
treated as signed. Hence add 0x8000 to compensate.
|
||||
*/
|
||||
value = (*(grub_uint16_t *) addr << 16)
|
||||
+ sym->st_value + 0x8000;
|
||||
if (rel + 1 < max && ELF_R_SYM (rel[1].r_info)
|
||||
== ELF_R_SYM (rel[0].r_info)
|
||||
&& ELF_R_TYPE (rel[1].r_info) == R_MIPS_LO16)
|
||||
value += *(grub_uint16_t *)
|
||||
((char *) seg->addr + rel[1].r_offset);
|
||||
*(grub_uint16_t *) addr += (value >> 16) & 0xffff;
|
||||
}
|
||||
break;
|
||||
case R_MIPS_LO16:
|
||||
*(grub_uint16_t *) addr += (sym->st_value) & 0xffff;
|
||||
break;
|
||||
case R_MIPS_32:
|
||||
*(grub_uint32_t *) addr = sym->st_value;
|
||||
break;
|
||||
case R_MIPS_26:
|
||||
{
|
||||
grub_uint32_t value;
|
||||
grub_uint32_t raw;
|
||||
raw = (*(grub_uint32_t *) addr) & 0x3ffffff;
|
||||
value = raw << 2;
|
||||
value += sym->st_value;
|
||||
raw = (value >> 2) & 0x3ffffff;
|
||||
|
||||
*(grub_uint32_t *) addr =
|
||||
raw | ((*(grub_uint32_t *) addr) & 0xfc000000);
|
||||
}
|
||||
break;
|
||||
case R_MIPS_GOT16:
|
||||
case R_MIPS_CALL16:
|
||||
/* FIXME: reuse*/
|
||||
*gpptr = sym->st_value + *(grub_uint16_t *) addr;
|
||||
*(grub_uint16_t *) addr
|
||||
= sizeof (grub_uint32_t) * (gpptr - gp);
|
||||
gpptr++;
|
||||
break;
|
||||
case R_MIPS_GPREL32:
|
||||
grub_printf ("gp32\n");
|
||||
*gpptr = sym->st_value + *(grub_uint16_t *) addr;
|
||||
*(grub_uint32_t *) addr
|
||||
= sizeof (grub_uint32_t) * (gpptr - gp);
|
||||
gpptr++;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
grub_printf ("Unknown relocation type %d\n",
|
||||
ELF_R_TYPE (rel->r_info));
|
||||
|
|
|
@ -24,8 +24,7 @@ grub_machine_init (void)
|
|||
void *tst;
|
||||
grub_mm_init_region ((void *) GRUB_MACHINE_MEMORY_STACK_HIGH,
|
||||
RAMSIZE - (GRUB_MACHINE_MEMORY_STACK_HIGH & 0x7fffffff));
|
||||
tst = grub_malloc (10);
|
||||
grub_free (tst);
|
||||
grub_install_get_time_ms (grub_rtc_get_time_ms);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in a new issue