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 pkglib_MODULES += relocator.mod
relocator_mod_SOURCES = lib/relocator.c lib/i386/relocator32.S \ relocator_mod_SOURCES = lib/relocator.c lib/i386/relocator32.S \
lib/i386/relocator64.S lib/i386/relocator16.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_CFLAGS = $(COMMON_CFLAGS)
relocator_mod_ASFLAGS = $(COMMON_ASFLAGS) relocator_mod_ASFLAGS = $(COMMON_ASFLAGS)
relocator_mod_LDFLAGS = $(COMMON_LDFLAGS) relocator_mod_LDFLAGS = $(COMMON_LDFLAGS)

View file

@ -167,7 +167,9 @@ xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)
xnu_mod_ASFLAGS = $(COMMON_ASFLAGS) xnu_mod_ASFLAGS = $(COMMON_ASFLAGS)
pkglib_MODULES += relocator.mod 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_CFLAGS = $(COMMON_CFLAGS)
relocator_mod_ASFLAGS = $(COMMON_ASFLAGS) relocator_mod_ASFLAGS = $(COMMON_ASFLAGS)
relocator_mod_LDFLAGS = $(COMMON_LDFLAGS) 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_align = 1;
grub_size_t grub_relocator_forward_size; grub_size_t grub_relocator_forward_size;
grub_size_t grub_relocator_backward_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 void
grub_cpu_relocator_init (void) grub_cpu_relocator_init (void)
@ -91,16 +95,26 @@ grub_cpu_relocator_jumper (void *rels, grub_addr_t addr)
{ {
grub_uint8_t *ptr; grub_uint8_t *ptr;
ptr = rels; 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; *(grub_uint8_t *) ptr = 0xb8;
ptr++; ptr++;
*(grub_uint32_t *) ptr = addr; *(grub_uint32_t *) ptr = addr;
ptr += 4; ptr += sizeof (grub_uint32_t);
/* jmp $addr */ #endif
*(grub_uint8_t *) ptr = 0xe9; /* jmp $eax/$rax */
*(grub_uint8_t *) ptr = 0xff;
ptr++;
*(grub_uint8_t *) ptr = 0xe0;
ptr++; ptr++;
*(grub_uint32_t *) ptr = addr - (grub_uint32_t) (ptr + 4);
ptr += 4;
} }
void void

View file

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

View file

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

View file

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

View file

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