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)
|
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)
|
if ((dev->open) (raw, disk) == GRUB_ERR_NONE)
|
||||||
break;
|
break;
|
||||||
else if (grub_errno == GRUB_ERR_UNKNOWN_DEVICE)
|
else if (grub_errno == GRUB_ERR_UNKNOWN_DEVICE)
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
else
|
else
|
||||||
goto fail;
|
goto fail;
|
||||||
|
grub_printf ("survived\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! dev)
|
if (! dev)
|
||||||
|
|
103
kern/mips/dl.c
103
kern/mips/dl.c
|
@ -22,6 +22,8 @@
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
#include <grub/err.h>
|
#include <grub/err.h>
|
||||||
#include <grub/cpu/types.h>
|
#include <grub/cpu/types.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
#include <grub/cpu/dl.h>
|
||||||
|
|
||||||
/* Check if EHDR is a valid ELF header. */
|
/* Check if EHDR is a valid ELF header. */
|
||||||
grub_err_t
|
grub_err_t
|
||||||
|
@ -52,6 +54,9 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
|
||||||
Elf_Shdr *s;
|
Elf_Shdr *s;
|
||||||
Elf_Word entsize;
|
Elf_Word entsize;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
grub_size_t gp_size = 0;
|
||||||
|
/* FIXME: suboptimal. */
|
||||||
|
grub_uint32_t *gp, *gpptr;
|
||||||
|
|
||||||
/* Find a symbol table. */
|
/* Find a symbol table. */
|
||||||
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
|
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;
|
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);
|
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
|
||||||
i < e->e_shnum;
|
i < e->e_shnum;
|
||||||
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
|
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);
|
addr = (Elf_Word *) ((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)
|
||||||
|
sym->st_value = (grub_addr_t) gp;
|
||||||
|
|
||||||
switch (ELF_R_TYPE (rel->r_info))
|
switch (ELF_R_TYPE (rel->r_info))
|
||||||
{
|
{
|
||||||
#if 0
|
case R_MIPS_HI16:
|
||||||
case R_386_32:
|
{
|
||||||
*addr += sym->st_value;
|
grub_uint32_t value;
|
||||||
break;
|
|
||||||
|
|
||||||
case R_386_PC32:
|
/* Handle partner lo16 relocation. Lower part is
|
||||||
*addr += (sym->st_value - (Elf_Word) seg->addr
|
treated as signed. Hence add 0x8000 to compensate.
|
||||||
- rel->r_offset);
|
*/
|
||||||
|
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;
|
break;
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
grub_printf ("Unknown relocation type %d\n",
|
grub_printf ("Unknown relocation type %d\n",
|
||||||
ELF_R_TYPE (rel->r_info));
|
ELF_R_TYPE (rel->r_info));
|
||||||
|
|
|
@ -24,8 +24,7 @@ grub_machine_init (void)
|
||||||
void *tst;
|
void *tst;
|
||||||
grub_mm_init_region ((void *) GRUB_MACHINE_MEMORY_STACK_HIGH,
|
grub_mm_init_region ((void *) GRUB_MACHINE_MEMORY_STACK_HIGH,
|
||||||
RAMSIZE - (GRUB_MACHINE_MEMORY_STACK_HIGH & 0x7fffffff));
|
RAMSIZE - (GRUB_MACHINE_MEMORY_STACK_HIGH & 0x7fffffff));
|
||||||
tst = grub_malloc (10);
|
grub_install_get_time_ms (grub_rtc_get_time_ms);
|
||||||
grub_free (tst);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in a new issue