x86_64 support for relocator
This commit is contained in:
parent
11aadbadfb
commit
73f6ce4ab2
7 changed files with 38 additions and 22 deletions
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue