x86_64 support for relocator

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-01-12 23:30:52 +01:00
parent 11aadbadfb
commit 73f6ce4ab2
7 changed files with 38 additions and 22 deletions

View file

@ -18,7 +18,7 @@ vga_text_mod_LDFLAGS = $(COMMON_LDFLAGS)
pkglib_MODULES += relocator.mod
relocator_mod_SOURCES = lib/relocator.c lib/i386/relocator32.S \
lib/i386/relocator64.S lib/i386/relocator16.S \
lib/i386/relocator_asm.S lib/i386/relocator.c
lib/$(target_cpu)/relocator_asm.S lib/i386/relocator.c
relocator_mod_CFLAGS = $(COMMON_CFLAGS)
relocator_mod_ASFLAGS = $(COMMON_ASFLAGS)
relocator_mod_LDFLAGS = $(COMMON_LDFLAGS)

View file

@ -167,7 +167,9 @@ xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)
xnu_mod_ASFLAGS = $(COMMON_ASFLAGS)
pkglib_MODULES += relocator.mod
relocator_mod_SOURCES = lib/i386/relocator.c lib/i386/relocator_asm.S lib/i386/relocator_backward.S
relocator_mod_SOURCES = lib/relocator.c lib/i386/relocator32.S \
lib/i386/relocator64.S lib/i386/relocator16.S \
lib/$(target_cpu)/relocator_asm.S lib/i386/relocator.c
relocator_mod_CFLAGS = $(COMMON_CFLAGS)
relocator_mod_ASFLAGS = $(COMMON_ASFLAGS)
relocator_mod_LDFLAGS = $(COMMON_LDFLAGS)

View file

@ -77,7 +77,11 @@ extern grub_addr_t grub_relocator64_cr3;
grub_size_t grub_relocator_align = 1;
grub_size_t grub_relocator_forward_size;
grub_size_t grub_relocator_backward_size;
grub_size_t grub_relocator_jumper_size = 10;
#ifdef __x86_64__
grub_size_t grub_relocator_jumper_size = 12;
#else
grub_size_t grub_relocator_jumper_size = 7;
#endif
void
grub_cpu_relocator_init (void)
@ -91,16 +95,26 @@ grub_cpu_relocator_jumper (void *rels, grub_addr_t addr)
{
grub_uint8_t *ptr;
ptr = rels;
/* movl $addr, %eax (for relocator) */
#ifdef __x86_64__
/* movq imm64, %rax (for relocator) */
*(grub_uint8_t *) ptr = 0x48;
ptr++;
*(grub_uint8_t *) ptr = 0xb8;
ptr++;
*(grub_uint64_t *) ptr = addr;
ptr += sizeof (grub_uint64_t);
#else
/* movl imm32, %eax (for relocator) */
*(grub_uint8_t *) ptr = 0xb8;
ptr++;
*(grub_uint32_t *) ptr = addr;
ptr += 4;
/* jmp $addr */
*(grub_uint8_t *) ptr = 0xe9;
ptr += sizeof (grub_uint32_t);
#endif
/* jmp $eax/$rax */
*(grub_uint8_t *) ptr = 0xff;
ptr++;
*(grub_uint8_t *) ptr = 0xe0;
ptr++;
*(grub_uint32_t *) ptr = addr - (grub_uint32_t) (ptr + 4);
ptr += 4;
}
void

View file

@ -21,7 +21,7 @@
#ifdef __x86_64__
#define RAX %rax
#define RSI %rdi
#define RSI %rsi
#else
#define RAX %eax
#define RSI %esi
@ -93,7 +93,7 @@ LOCAL(cont1):
movl %esi, %eax
shrl $4, %eax
movw %ax, (LOCAL (segment) - LOCAL (base)) (RSI, 1)
movw %ax, (LOCAL (segment) - LOCAL (base)) (%esi, 1)
/* jump to a 16 bit segment */
ljmp $PSEUDO_REAL_CSEG, $(LOCAL (cont2) - LOCAL(base))

View file

@ -21,7 +21,7 @@
#ifdef __x86_64__
#define RAX %rax
#define RSI %rdi
#define RSI %rsi
#else
#define RAX %eax
#define RSI %esi

View file

@ -21,7 +21,7 @@
#ifdef __x86_64__
#define RAX %rax
#define RSI %rdi
#define RSI %rsi
#else
#define RAX %eax
#define RSI %esi
@ -82,7 +82,7 @@ VARIABLE(grub_relocator64_cr3)
.byte 0xb8
VARIABLE(grub_relocator64_cr3)
.quad 0
movl %rax, %cr3
movq %rax, %cr3
#endif
/* Load GDT. */
lgdt (LOCAL(gdtdesc) - LOCAL(base)) (RSI, 1)

View file

@ -40,7 +40,7 @@ grub_relocator_new (void)
ret->postchunks = ~(grub_addr_t) 0;
ret->relocators_size = grub_relocator_jumper_size;
grub_dprintf ("relocator", "relocators_size=%d\n", ret->relocators_size);
grub_dprintf ("relocator", "relocators_size=%ld\n", ret->relocators_size);
return ret;
}
@ -103,7 +103,7 @@ get_best_header (struct grub_relocator *rel,
hb = h;
hbp = hp;
*best_addr = addr;
grub_dprintf ("relocator", "picked %p/%x\n", hb, addr);
grub_dprintf ("relocator", "picked %p/%lx\n", hb, addr);
}
}
else
@ -146,7 +146,7 @@ get_best_header (struct grub_relocator *rel,
hb = h;
hbp = hp;
*best_addr = addr;
grub_dprintf ("relocator", "picked %p/%x\n", hb, addr);
grub_dprintf ("relocator", "picked %p/%lx\n", hb, addr);
}
}
}
@ -221,7 +221,7 @@ malloc_in_range (struct grub_relocator *rel,
hb = get_best_header (rel, start, end, align, size, rb, &hbp, &best_addr,
from_low_priv, collisioncheck);
grub_dprintf ("relocator", "best header %p/%x\n", hb, best_addr);
grub_dprintf ("relocator", "best header %p/%lx\n", hb, best_addr);
if (!hb)
{
@ -421,14 +421,14 @@ grub_relocator_alloc_chunk_addr (struct grub_relocator *rel, void **src,
rel->highestnonpostaddr = start + size;
}
grub_dprintf ("relocator", "relocators_size=%d\n", rel->relocators_size);
grub_dprintf ("relocator", "relocators_size=%ld\n", rel->relocators_size);
if (start < target)
rel->relocators_size += grub_relocator_backward_size;
if (start > target)
rel->relocators_size += grub_relocator_forward_size;
grub_dprintf ("relocator", "relocators_size=%d\n", rel->relocators_size);
grub_dprintf ("relocator", "relocators_size=%ld\n", rel->relocators_size);
chunk->src = start;
chunk->target = target;
@ -485,7 +485,7 @@ grub_relocator_alloc_chunk_align (struct grub_relocator *rel, void **src,
}
adjust_limits (rel, &min_addr2, &max_addr2, min_addr, max_addr);
grub_dprintf ("relocator", "Adjusted limits from %x-%x to %x-%x\n",
grub_dprintf ("relocator", "Adjusted limits from %lx-%lx to %lx-%lx\n",
min_addr, max_addr, min_addr2, max_addr2);
do
@ -572,7 +572,7 @@ grub_relocator_prepare_relocs (struct grub_relocator *rel, grub_addr_t addr,
grub_addr_t rels;
grub_addr_t rels0;
grub_dprintf ("relocator", "Preparing relocs (size=%d)\n",
grub_dprintf ("relocator", "Preparing relocs (size=%ld)\n",
rel->relocators_size);
if (!malloc_in_range (rel, 0, ~(grub_addr_t)0 - rel->relocators_size + 1,