Merge branch 'master' into leiflindholm/arm64

Conflicts:
	include/grub/util/install.h
This commit is contained in:
Vladimir Serbinenko 2013-11-25 13:02:27 +01:00
commit d6c92cdc34
82 changed files with 2897 additions and 353 deletions

View file

@ -396,7 +396,7 @@ efiemu32.o: efiemu/runtime/efiemu.c $(TARGET_OBJ2ELF)
-rm -f $@; \
if test "x$(TARGET_APPLE_LINKER)" = x1; then \
$(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m32 -Wall -Werror -nostdlib -O2 -c -o $@.bin $< || exit 1; \
$(OBJCONV) -felf32 -nu -nd $@.bin $@ || exit 1; \
$(TARGET_OBJCONV) -felf32 -nu -nd $@.bin $@ || exit 1; \
rm -f $@.bin; \
else \
$(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m32 -Wall -Werror -nostdlib -O2 -c -o $@ $< || exit 1; \
@ -423,7 +423,7 @@ efiemu64.o: efiemu64_c.o efiemu64_s.o $(TARGET_OBJ2ELEF)
if test "x$(TARGET_APPLE_LINKER)" = x1; then \
rm -f $@.bin; \
$(TARGET_CC) -m64 -Wl,-r -nostdlib -o $@.bin $^ || exit 1; \
$(OBJCONV) -felf64 -nu -nd $@.bin $@ || exit 1; \
$(TARGET_OBJCONV) -felf64 -nu -nd $@.bin $@ || exit 1; \
rm -f $@.bin; \
else \
$(TARGET_CC) -m64 -Wl,-melf_x86_64 -nostdlib -Wl,-r -o $@ $^ || exit 1; \

View file

@ -31,27 +31,32 @@
.macro floppy
part_start:
probe_values:
LOCAL(probe_values):
.byte 36, 18, 15, 9, 0
LOCAL(floppy_probe):
pushw %dx
/*
* Perform floppy probe.
*/
movw $probe_values - 1, %si
#ifdef __APPLE__
LOCAL(probe_values_minus_one) = LOCAL(probe_values) - 1
movw MACRO_DOLLAR(LOCAL(probe_values_minus_one)), %si
#else
movw MACRO_DOLLAR(LOCAL(probe_values)) - 1, %si
#endif
LOCAL(probe_loop):
/* reset floppy controller INT 13h AH=0 */
xorw %ax, %ax
int $0x13
int MACRO_DOLLAR(0x13)
incw %si
movb (%si), %cl
/* if number of sectors is 0, display error and die */
cmpb $0, %cl
jne 1f
testb %cl, %cl
jnz 1f
/*
* Floppy disk probe failure.
@ -64,20 +69,20 @@ fd_probe_error_string: .asciz "Floppy"
1:
/* perform read */
movw $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx
movw MACRO_DOLLAR(GRUB_BOOT_MACHINE_BUFFER_SEG), %bx
movw %bx, %es
xorw %bx, %bx
movw $0x201, %ax
movb $0, %ch
movb $0, %dh
int $0x13
movw MACRO_DOLLAR(0x201), %ax
movb MACRO_DOLLAR(0), %ch
movb MACRO_DOLLAR(0), %dh
int MACRO_DOLLAR(0x13)
/* if error, jump to "LOCAL(probe_loop)" */
jc LOCAL(probe_loop)
/* %cl is already the correct value! */
movb $1, %dh
movb $79, %ch
movb MACRO_DOLLAR(1), %dh
movb MACRO_DOLLAR(79), %ch
jmp LOCAL(final_init)
.endm
@ -180,7 +185,9 @@ kernel_address:
#ifndef HYBRID_BOOT
. = _start + GRUB_BOOT_MACHINE_KERNEL_SECTOR
kernel_sector:
.long 1, 0
.long 1
kernel_sector_high:
.long 0
#endif
. = _start + GRUB_BOOT_MACHINE_BOOT_DRIVE
@ -285,7 +292,7 @@ lba_mode:
/* the absolute address */
movl kernel_sector, %ebx
movl %ebx, 8(%si)
movl kernel_sector + 4, %ebx
movl kernel_sector_high, %ebx
movl %ebx, 12(%si)
/* the segment of buffer address */
@ -318,11 +325,12 @@ LOCAL(chs_mode):
int $0x13
jnc LOCAL(final_init)
popw %dx
/*
* The call failed, so maybe use the floppy probe instead.
*/
testb $GRUB_BOOT_MACHINE_BIOS_HD_FLAG, %dl
jz LOCAL(floppy_probe)
testb %dl, %dl
jnb LOCAL(floppy_probe)
/* Nope, we definitely have a hard disk, and we're screwed. */
ERR(hd_probe_error_string)
@ -353,7 +361,7 @@ LOCAL(final_init):
setup_sectors:
/* load logical sector start (top half) */
movl kernel_sector + 4, %eax
movl kernel_sector_high, %eax
orl %eax, %eax
jnz LOCAL(geometry_error)
@ -505,7 +513,9 @@ LOCAL(message):
#ifdef HYBRID_BOOT
. = _start + 0x1b0
kernel_sector:
.long 1, 0
.long 1
kernel_sector_high:
.long 0
#endif
. = _start + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC
nt_magic:

View file

@ -18,7 +18,6 @@
#include <config.h>
#include <grub/symbol.h>
#include <grub/i386/pc/memory.h>
#include <grub/machine/memory.h>
#include <grub/machine/boot.h>
#include <grub/machine/kernel.h>

View file

@ -27,6 +27,7 @@
.extern __bss_start
.extern _end
.extern _edata
.globl __start, _start, start
.set noreorder
@ -248,8 +249,9 @@ cmdlinedone:
#include "../../kern/mips/cache_flush.S"
/* Decompress the payload. */
lui $a0, %hi(__bss_start)
addiu $a0, $a0, %lo(__bss_start)
lui $a0, %hi(_edata)
addiu $a0, $a0, %lo(_edata)
lui $t0, %hi(base)
addiu $t0, $t0, %lo(base)
subu $a0, $a0, $t0
@ -265,16 +267,16 @@ cmdlinedone:
*/
move $s6, $a3
lui $t0, %hi(EXT_C(grub_decompress_core))
addiu $t0, $t0, %lo(EXT_C(grub_decompress_core))
lui $t9, %hi(EXT_C(grub_decompress_core))
addiu $t9, $t9, %lo(EXT_C(grub_decompress_core))
#ifdef GRUB_MACHINE_ARC
lui $sp, %hi(_start - 512)
jalr $t0
jalr $t9
addiu $sp, $sp, %lo(_start - 512)
#else
lui $sp, %hi(_start - 256)
jalr $t0
jalr $t9
addiu $sp, $sp, %lo(_start - 256)
#endif
move $a0, $s1
@ -287,3 +289,11 @@ cmdlinedone:
jr $t1
nop
/* Ensure that .data section is created. In code we suppose that _edata
is first location not in decompressor image. Strictly speaking it's
_edata only when .data is present and _etext otherwise. But checking
for .data presence would cost more in code than it is to ensure that
.data is created.
*/
.data
.long 0

View file

@ -426,6 +426,10 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
disk->total_sectors = total_sectors;
/* Limit the max to 0x7f because of Phoenix EDD. */
disk->max_agglomerate = 0x7f >> GRUB_DISK_CACHE_BITS;
COMPILE_TIME_ASSERT ((0x7f >> GRUB_DISK_CACHE_BITS
<< (GRUB_DISK_SECTOR_BITS + GRUB_DISK_CACHE_BITS))
+ sizeof (struct grub_biosdisk_dap)
< GRUB_MEMORY_MACHINE_SCRATCH_SIZE);
disk->data = data;

View file

@ -71,11 +71,7 @@ VARIABLE(grub_gdb_stack)
#define REG \reg
#define NDX \ndx
#endif
#ifdef __APPLE__
xorl %eax, %eax
#else
movl $0, %eax
#endif
movw REG, EXT_C(grub_gdb_regs)+(NDX * 4)
movw %ax, EXT_C(grub_gdb_regs)+(NDX * 4 + 2)
movl EXT_C(grub_gdb_regs)+(EAX * 4), %eax
@ -190,11 +186,7 @@ VARIABLE(grub_gdb_stack)
.text
1:
.if EC
#ifdef __APPLE__
add $$4, %esp
#else
add $4, %esp
#endif
add MACRO_DOLLAR(4), %esp
.endif
save_context

View file

@ -23,7 +23,7 @@ BEGIN {
} else if ($1 == "undefined") {
if ($3 in symtab)
modtab[$2] = modtab[$2] " " symtab[$3];
else if ($3 != "__gnu_local_gp") {
else if ($3 != "__gnu_local_gp" && $3 != "_gp_disp") {
printf "%s in %s is not defined\n", $3, $2 >"/dev/stderr";
error++;
}

View file

@ -229,9 +229,10 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
unsigned i;
Elf_Shdr *s;
grub_size_t tsize = 0, talign = 1;
#if defined (__ia64__) || defined (__powerpc__)
#if defined (__ia64__) || defined (__powerpc__) || defined (__mips__)
grub_size_t tramp;
grub_size_t got;
grub_err_t err;
#endif
char *ptr;
@ -244,10 +245,10 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
talign = s->sh_addralign;
}
#if defined (__ia64__) || defined (__powerpc__)
grub_arch_dl_get_tramp_got_size (e, &tramp, &got);
tramp *= GRUB_ARCH_DL_TRAMP_SIZE;
got *= sizeof (grub_uint64_t);
#if defined (__ia64__) || defined (__powerpc__) || defined (__mips__)
err = grub_arch_dl_get_tramp_got_size (e, &tramp, &got);
if (err)
return err;
tsize += ALIGN_UP (tramp, GRUB_ARCH_DL_TRAMP_ALIGN);
if (talign < GRUB_ARCH_DL_TRAMP_ALIGN)
talign = GRUB_ARCH_DL_TRAMP_ALIGN;
@ -313,7 +314,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
mod->segment = seg;
}
}
#if defined (__ia64__) || defined (__powerpc__)
#if defined (__ia64__) || defined (__powerpc__) || defined (__mips__)
ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_TRAMP_ALIGN);
mod->tramp = ptr;
ptr += tramp;

View file

@ -32,6 +32,12 @@
#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12)
#define PAGES_TO_BYTES(pages) ((pages) << 12)
#if defined (__code_model_large__) || !defined (__x86_64__)
#define MAX_USABLE_ADDRESS 0xffffffff
#else
#define MAX_USABLE_ADDRESS 0x7fffffff
#endif
/* The size of a memory map obtained from the firmware. This must be
a multiplier of 4KB. */
#define MEMORY_MAP_SIZE 0x3000
@ -58,7 +64,7 @@ grub_efi_allocate_pages (grub_efi_physical_address_t address,
#if 1
/* Limit the memory access to less than 4GB for 32-bit platforms. */
if (address > 0xffffffff)
if (address > MAX_USABLE_ADDRESS)
return 0;
#endif
@ -66,7 +72,7 @@ grub_efi_allocate_pages (grub_efi_physical_address_t address,
if (address == 0)
{
type = GRUB_EFI_ALLOCATE_MAX_ADDRESS;
address = 0xffffffff;
address = MAX_USABLE_ADDRESS;
}
else
type = GRUB_EFI_ALLOCATE_ADDRESS;
@ -86,7 +92,7 @@ grub_efi_allocate_pages (grub_efi_physical_address_t address,
{
/* Uggh, the address 0 was allocated... This is too annoying,
so reallocate another one. */
address = 0xffffffff;
address = MAX_USABLE_ADDRESS;
status = efi_call_4 (b->allocate_pages, type, GRUB_EFI_LOADER_DATA, pages, &address);
grub_efi_free_pages (0, pages);
if (status != GRUB_EFI_SUCCESS)
@ -319,7 +325,7 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map,
{
if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
#if 1
&& desc->physical_start <= 0xffffffff
&& desc->physical_start <= MAX_USABLE_ADDRESS
#endif
&& desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000
&& desc->num_pages != 0)
@ -337,9 +343,9 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map,
#if 1
if (BYTES_TO_PAGES (filtered_desc->physical_start)
+ filtered_desc->num_pages
> BYTES_TO_PAGES (0x100000000LL))
> BYTES_TO_PAGES (MAX_USABLE_ADDRESS+1LL))
filtered_desc->num_pages
= (BYTES_TO_PAGES (0x100000000LL)
= (BYTES_TO_PAGES (MAX_USABLE_ADDRESS+1LL)
- BYTES_TO_PAGES (filtered_desc->physical_start));
#endif

View file

@ -46,7 +46,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
return GRUB_ERR_BAD_MODULE;
}
#if defined (__ia64__) || defined (__powerpc__)
#if defined (__ia64__) || defined (__powerpc__) || defined (__mips__)
void grub_arch_dl_get_tramp_got_size (const void *ehdr __attribute__ ((unused)),
grub_size_t *tramp, grub_size_t *got)
{

View file

@ -17,8 +17,6 @@
*/
#include <grub/symbol.h>
/* For stack parameters. */
#include <grub/i386/pc/memory.h>
#include <grub/machine/memory.h>
#include <grub/cpu/linux.h>
#include <grub/offsets.h>

View file

@ -161,13 +161,13 @@ mmap_iterate_hook (grub_uint64_t addr, grub_uint64_t size,
void *data __attribute__ ((unused)))
{
/* Avoid the lower memory. */
if (addr < 0x100000)
if (addr < GRUB_MEMORY_MACHINE_UPPER_START)
{
if (size <= 0x100000 - addr)
if (size <= GRUB_MEMORY_MACHINE_UPPER_START - addr)
return 0;
size -= 0x100000 - addr;
addr = 0x100000;
size -= GRUB_MEMORY_MACHINE_UPPER_START - addr;
addr = GRUB_MEMORY_MACHINE_UPPER_START;
}
/* Ignore >4GB. */

View file

@ -19,7 +19,6 @@
#include <config.h>
#include <grub/symbol.h>
#include <grub/i386/pc/memory.h>
#include <grub/machine/memory.h>
#include <grub/machine/kernel.h>

View file

@ -16,7 +16,7 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/i386/pc/memory.h>
#include <grub/machine/memory.h>
/*
* Note: These functions defined in this file may be called from C.
@ -196,8 +196,6 @@ protcseg:
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/i386/pc/memory.h>
prot_to_real:
/* just in case, set GDT */
lgdt gdtdesc

View file

@ -170,7 +170,7 @@ grub_ia64_make_trampoline (struct grub_ia64_trampoline *tr, grub_uint64_t addr)
grub_memcpy (tr->jump, jump, sizeof (tr->jump));
}
void
grub_err_t
grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
grub_size_t *got)
{
@ -187,7 +187,7 @@ grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
break;
if (i == grub_le_to_cpu16 (e->e_shnum))
return;
return GRUB_ERR_NONE;
for (i = 0, s = (Elf64_Shdr *) ((char *) e + grub_le_to_cpu64 (e->e_shoff));
i < grub_le_to_cpu16 (e->e_shnum);
@ -211,7 +211,9 @@ grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
break;
}
}
*tramp = cntt;
*got = cntg;
*tramp = cntt * sizeof (struct grub_ia64_trampoline);
*got = cntg * sizeof (grub_uint64_t);
return GRUB_ERR_NONE;
}

View file

@ -396,8 +396,8 @@ grub_machine_get_bootlocation (char **device, char **path)
const char *syspart = 0;
if (GRUB_ARC_SYSTEM_PARAMETER_BLOCK->firmware_vector_length
>= ((char *) (&GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable + 1)
- (char *) GRUB_ARC_FIRMWARE_VECTOR)
>= (unsigned) ((char *) (&GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable + 1)
- (char *) GRUB_ARC_FIRMWARE_VECTOR)
&& GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable)
syspart = GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable ("SystemPartition");
if (!syspart)

View file

@ -20,11 +20,11 @@ FUNCTION (grub_arch_sync_dma_caches)
move $t0, $t2
subu $t1, $t3, $t2
1:
cache 1, 0($t0)
cache_op 1, 0($t0)
#ifdef GRUB_MACHINE_MIPS_LOONGSON
cache 1, 1($t0)
cache 1, 2($t0)
cache 1, 3($t0)
cache_op 1, 1($t0)
cache_op 1, 2($t0)
cache_op 1, 3($t0)
addiu $t1, $t1, -0x20
bne $t1, $zero, 1b
@ -34,36 +34,36 @@ FUNCTION (grub_arch_sync_dma_caches)
bne $t1, $zero, 1b
addiu $t0, $t0, 0x4
#endif
sync
sync_op
move $t0, $t2
subu $t1, $t3, $t2
2:
#ifdef GRUB_MACHINE_MIPS_LOONGSON
cache 0, 0($t0)
cache_op 0, 0($t0)
addiu $t1, $t1, -0x20
bne $t1, $zero, 2b
addiu $t0, $t0, 0x20
#else
cache 0, 0($t0)
cache_op 0, 0($t0)
addiu $t1, $t1, -4
bne $t1, $zero, 2b
addiu $t0, $t0, 0x4
#endif
sync
sync_op
move $t0, $t2
subu $t1, $t3, $t2
2:
#ifdef GRUB_MACHINE_MIPS_LOONGSON
cache 23, 0($t0)
cache_op 23, 0($t0)
addiu $t1, $t1, -0x20
bne $t1, $zero, 2b
addiu $t0, $t0, 0x20
#else
cache 23, 0($t0)
cache_op 23, 0($t0)
addiu $t1, $t1, -0x4
bne $t1, $zero, 2b
addiu $t0, $t0, 0x4
#endif
sync
sync_op
jr $ra

View file

@ -1,3 +1,17 @@
#ifndef CACHE_OP_DEFINED
#define CACHE_OP_DEFINED 1
.macro cache_op op addr
.set mips3
cache \op, \addr
.set mips1
.endm
.macro sync_op
.set mips3
sync
.set mips1
.endm
#endif
move $t2, $a0
addu $t3, $a0, $a1
srl $t2, $t2, 5
@ -8,12 +22,12 @@
move $t0, $t2
subu $t1, $t3, $t2
1:
cache 1, 0($t0)
cache_op 1, 0($t0)
/* All four ways. */
#ifdef GRUB_MACHINE_MIPS_LOONGSON
cache 1, 1($t0)
cache 1, 2($t0)
cache 1, 3($t0)
cache_op 1, 1($t0)
cache_op 1, 2($t0)
cache_op 1, 3($t0)
addiu $t1, $t1, -0x20
bne $t1, $zero, 1b
addiu $t0, $t0, 0x20
@ -23,11 +37,11 @@
bne $t1, $zero, 1b
addiu $t0, $t0, 0x4
#endif
sync
sync_op
move $t0, $t2
subu $t1, $t3, $t2
2:
cache 0, 0($t0)
cache_op 0, 0($t0)
#ifdef GRUB_MACHINE_MIPS_LOONGSON
addiu $t1, $t1, -0x20
bne $t1, $zero, 2b
@ -37,4 +51,4 @@
bne $t1, $zero, 2b
addiu $t0, $t0, 0x4
#endif
sync
sync_op

View file

@ -27,6 +27,7 @@
/* Dummy __gnu_local_gp. Resolved by linker. */
static char __gnu_local_gp_dummy;
static char _gp_disp_dummy;
/* Check if EHDR is a valid ELF header. */
grub_err_t
@ -51,6 +52,58 @@ grub_arch_dl_check_header (void *ehdr)
#pragma GCC diagnostic ignored "-Wcast-align"
grub_err_t
grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
grub_size_t *got)
{
const Elf_Ehdr *e = ehdr;
const Elf_Shdr *s;
unsigned i;
/* FIXME: suboptimal. */
grub_size_t gp_size = 0;
*tramp = 0;
*got = 0;
/* Find a symbol table. */
for (i = 0, s = (const Elf_Shdr *) ((const char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (const Elf_Shdr *) ((const char *) s + e->e_shentsize))
if (s->sh_type == SHT_SYMTAB)
break;
if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, N_("no symbol table"));
for (i = 0, s = (const Elf_Shdr *) ((const char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (const Elf_Shdr *) ((const char *) s + e->e_shentsize))
if (s->sh_type == SHT_REL)
{
const Elf_Rel *rel, *max;
for (rel = (const Elf_Rel *) ((const 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");
*got = gp_size;
return GRUB_ERR_NONE;
}
/* Relocate symbols. */
grub_err_t
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
@ -59,7 +112,6 @@ 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;
grub_uint32_t gp0;
@ -88,43 +140,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
gp0 = ((grub_uint32_t *)((char *) e + s->sh_offset))[5];
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;
gpptr = gp = mod->got;
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
@ -149,6 +165,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
{
grub_uint8_t *addr;
Elf_Sym *sym;
grub_uint32_t sym_value;
if (seg->size < rel->r_offset)
return grub_error (GRUB_ERR_BAD_MODULE,
@ -157,9 +174,17 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
addr = (grub_uint8_t *) ((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_dummy)
sym->st_value = (grub_addr_t) gp;
sym_value = sym->st_value;
if (sym_value == (grub_addr_t) &__gnu_local_gp_dummy)
sym_value = (grub_addr_t) gp;
else if (sym_value == (grub_addr_t) &_gp_disp_dummy)
{
sym_value = (grub_addr_t) gp - (grub_addr_t) addr;
if (ELF_R_TYPE (rel->r_info) == R_MIPS_LO16)
/* ABI mandates +4 even if partner lui doesn't
immediately precede addiu. */
sym_value += 4;
}
switch (ELF_R_TYPE (rel->r_info))
{
case R_MIPS_HI16:
@ -175,7 +200,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
treated as signed. Hence add 0x8000 to compensate.
*/
value = (*(grub_uint16_t *) addr << 16)
+ sym->st_value + 0x8000;
+ sym_value + 0x8000;
for (rel2 = rel + 1; rel2 < max; rel2++)
if (ELF_R_SYM (rel2->r_info)
== ELF_R_SYM (rel->r_info)
@ -196,13 +221,13 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
#ifdef GRUB_CPU_WORDS_BIGENDIAN
addr += 2;
#endif
*(grub_uint16_t *) addr += (sym->st_value) & 0xffff;
*(grub_uint16_t *) addr += sym_value & 0xffff;
break;
case R_MIPS_32:
*(grub_uint32_t *) addr += sym->st_value;
*(grub_uint32_t *) addr += sym_value;
break;
case R_MIPS_GPREL32:
*(grub_uint32_t *) addr = sym->st_value
*(grub_uint32_t *) addr = sym_value
+ *(grub_uint32_t *) addr + gp0 - (grub_uint32_t)gp;
break;
@ -212,7 +237,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
grub_uint32_t raw;
raw = (*(grub_uint32_t *) addr) & 0x3ffffff;
value = raw << 2;
value += sym->st_value;
value += sym_value;
raw = (value >> 2) & 0x3ffffff;
*(grub_uint32_t *) addr =
@ -220,12 +245,36 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
}
break;
case R_MIPS_GOT16:
if (ELF_ST_BIND (sym->st_info) == STB_LOCAL)
{
Elf_Rel *rel2;
/* Handle partner lo16 relocation. Lower part is
treated as signed. Hence add 0x8000 to compensate.
*/
sym_value += (*(grub_uint16_t *) addr << 16)
+ 0x8000;
for (rel2 = rel + 1; rel2 < max; rel2++)
if (ELF_R_SYM (rel2->r_info)
== ELF_R_SYM (rel->r_info)
&& ELF_R_TYPE (rel2->r_info) == R_MIPS_LO16)
{
sym_value += *(grub_int16_t *)
((char *) seg->addr + rel2->r_offset
#ifdef GRUB_CPU_WORDS_BIGENDIAN
+ 2
#endif
);
break;
}
sym_value &= 0xffff0000;
*(grub_uint16_t *) addr = 0;
}
case R_MIPS_CALL16:
/* FIXME: reuse*/
#ifdef GRUB_CPU_WORDS_BIGENDIAN
addr += 2;
#endif
*gpptr = sym->st_value + *(grub_uint16_t *) addr;
*gpptr = sym_value + *(grub_uint16_t *) addr;
*(grub_uint16_t *) addr
= sizeof (grub_uint32_t) * (gpptr - gp);
gpptr++;
@ -234,7 +283,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
break;
default:
{
grub_free (gp);
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
N_("relocation 0x%x is not implemented yet"),
ELF_R_TYPE (rel->r_info));
@ -252,5 +300,6 @@ void
grub_arch_dl_init_linker (void)
{
grub_dl_register_symbol ("__gnu_local_gp", &__gnu_local_gp_dummy, 0, 0);
grub_dl_register_symbol ("_gp_disp", &_gp_disp_dummy, 0, 0);
}

View file

@ -116,10 +116,10 @@ bsscont:
bne $t3, $0, bsscont
nop
lui $t1, %hi(grub_main)
addiu $t1, %lo(grub_main)
lui $t9, %hi(grub_main)
addiu $t9, %lo(grub_main)
lui $sp, %hi(GRUB_MACHINE_MEMORY_STACK_HIGH)
jr $t1
jr $t9
addiu $sp, $sp, %lo(GRUB_MACHINE_MEMORY_STACK_HIGH)

View file

@ -1220,6 +1220,15 @@ grub_abort (void)
grub_exit ();
}
#if defined (__clang__) && !defined (GRUB_UTIL)
/* clang emits references to abort(). */
void __attribute__ ((noreturn))
abort (void)
{
grub_abort ();
}
#endif
void
grub_fatal (const char *fmt, ...)
{

View file

@ -38,9 +38,26 @@ grub_arch_dl_check_header (void *ehdr)
return GRUB_ERR_NONE;
}
/* For low-endian reverse lis and addr_high as well as ori and addr_low. */
struct trampoline
{
grub_uint32_t lis;
grub_uint32_t ori;
grub_uint32_t mtctr;
grub_uint32_t bctr;
};
static const struct trampoline trampoline_template =
{
0x3d800000,
0x618c0000,
0x7d8903a6,
0x4e800420,
};
#pragma GCC diagnostic ignored "-Wcast-align"
void
grub_err_t
grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
grub_size_t *got)
{
@ -59,7 +76,7 @@ grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
break;
if (i == e->e_shnum)
return;
return GRUB_ERR_NONE;
for (i = 0, s = (const Elf_Shdr *) ((const char *) e + e->e_shoff);
i < e->e_shnum;
@ -77,26 +94,11 @@ grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
}
return;
*tramp *= sizeof (struct trampoline);
return GRUB_ERR_NONE;
}
/* For low-endian reverse lis and addr_high as well as ori and addr_low. */
struct trampoline
{
grub_uint32_t lis;
grub_uint32_t ori;
grub_uint32_t mtctr;
grub_uint32_t bctr;
};
static const struct trampoline trampoline_template =
{
0x3d800000,
0x618c0000,
0x7d8903a6,
0x4e800420,
};
/* Relocate symbols. */
grub_err_t
grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
@ -167,8 +169,6 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
if (delta << 6 >> 6 != delta)
{
COMPILE_TIME_ASSERT (sizeof (struct trampoline)
== GRUB_ARCH_DL_TRAMP_SIZE);
grub_memcpy (tptr, &trampoline_template,
sizeof (*tptr));
delta = (grub_uint8_t *) tptr - (grub_uint8_t *) addr;

View file

@ -100,14 +100,32 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr)
break;
case R_X86_64_PC32:
*addr32 += rel->r_addend + sym->st_value -
(Elf64_Xword) seg->addr - rel->r_offset;
{
grub_int64_t value;
value = ((grub_int32_t) *addr32) + rel->r_addend + sym->st_value -
(Elf64_Xword) seg->addr - rel->r_offset;
if (value != (grub_int32_t) value)
return grub_error (GRUB_ERR_BAD_MODULE, "relocation out of range");
*addr32 = value;
}
break;
case R_X86_64_32:
{
grub_uint64_t value = *addr32 + rel->r_addend + sym->st_value;
if (value != (grub_uint32_t) value)
return grub_error (GRUB_ERR_BAD_MODULE, "relocation out of range");
*addr32 = value;
}
break;
case R_X86_64_32S:
*addr32 += rel->r_addend + sym->st_value;
break;
{
grub_int64_t value = ((grub_int32_t) *addr32) + rel->r_addend + sym->st_value;
if (value != (grub_int32_t) value)
return grub_error (GRUB_ERR_BAD_MODULE, "relocation out of range");
*addr32 = value;
}
break;
default:
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,

View file

@ -36,94 +36,94 @@
.text
FUNCTION(efi_wrap_0)
subq $48, %rsp
subq $40, %rsp
call *%rdi
addq $48, %rsp
addq $40, %rsp
ret
FUNCTION(efi_wrap_1)
subq $48, %rsp
subq $40, %rsp
mov %rsi, %rcx
call *%rdi
addq $48, %rsp
addq $40, %rsp
ret
FUNCTION(efi_wrap_2)
subq $48, %rsp
subq $40, %rsp
mov %rsi, %rcx
call *%rdi
addq $48, %rsp
addq $40, %rsp
ret
FUNCTION(efi_wrap_3)
subq $48, %rsp
subq $40, %rsp
mov %rcx, %r8
mov %rsi, %rcx
call *%rdi
addq $48, %rsp
addq $40, %rsp
ret
FUNCTION(efi_wrap_4)
subq $48, %rsp
subq $40, %rsp
mov %r8, %r9
mov %rcx, %r8
mov %rsi, %rcx
call *%rdi
addq $48, %rsp
addq $40, %rsp
ret
FUNCTION(efi_wrap_5)
subq $48, %rsp
subq $40, %rsp
mov %r9, 32(%rsp)
mov %r8, %r9
mov %rcx, %r8
mov %rsi, %rcx
call *%rdi
addq $48, %rsp
addq $40, %rsp
ret
FUNCTION(efi_wrap_6)
subq $64, %rsp
mov 64+8(%rsp), %rax
subq $56, %rsp
mov 56+8(%rsp), %rax
mov %rax, 40(%rsp)
mov %r9, 32(%rsp)
mov %r8, %r9
mov %rcx, %r8
mov %rsi, %rcx
call *%rdi
addq $64, %rsp
addq $56, %rsp
ret
FUNCTION(efi_wrap_7)
subq $96, %rsp
mov 96+16(%rsp), %rax
subq $88, %rsp
mov 88+16(%rsp), %rax
mov %rax, 48(%rsp)
mov 96+8(%rsp), %rax
mov 88+8(%rsp), %rax
mov %rax, 40(%rsp)
mov %r9, 32(%rsp)
mov %r8, %r9
mov %rcx, %r8
mov %rsi, %rcx
call *%rdi
addq $96, %rsp
addq $88, %rsp
ret
FUNCTION(efi_wrap_10)
subq $96, %rsp
mov 96+40(%rsp), %rax
subq $88, %rsp
mov 88+40(%rsp), %rax
mov %rax, 72(%rsp)
mov 96+32(%rsp), %rax
mov 88+32(%rsp), %rax
mov %rax, 64(%rsp)
mov 96+24(%rsp), %rax
mov 88+24(%rsp), %rax
mov %rax, 56(%rsp)
mov 96+16(%rsp), %rax
mov 88+16(%rsp), %rax
mov %rax, 48(%rsp)
mov 96+8(%rsp), %rax
mov 88+8(%rsp), %rax
mov %rax, 40(%rsp)
mov %r9, 32(%rsp)
mov %r8, %r9
mov %rcx, %r8
mov %rsi, %rcx
call *%rdi
addq $96, %rsp
addq $88, %rsp
ret

View file

@ -30,6 +30,6 @@ _start:
movq %rcx, EXT_C(grub_efi_image_handle)(%rip)
movq %rdx, EXT_C(grub_efi_system_table)(%rip)
andq $~0xf, %rsp
call EXT_C(grub_main)
ret
/* Doesn't return. */

View file

@ -341,6 +341,14 @@ page2offset (grub_uint64_t page)
return page << 12;
}
#if defined (__x86_64__) && defined (__code_model_large__)
#define MAX_TOTAL_PAGES (1LL << (64 - 12))
#elif defined (__x86_64__)
#define MAX_TOTAL_PAGES (1LL << (31 - 12))
#else
#define MAX_TOTAL_PAGES (1LL << (32 - 12))
#endif
static void
map_all_pages (void)
{
@ -355,6 +363,9 @@ map_all_pages (void)
grub_size_t n_unusable_pages = 0;
struct mmu_update m2p_updates[2 * MAX_N_UNUSABLE_PAGES];
if (total_pages > MAX_TOTAL_PAGES - 4)
total_pages = MAX_TOTAL_PAGES - 4;
grub_memset (&gnttab_setver, 0, sizeof (gnttab_setver));
gnttab_setver.version = 2;

View file

@ -125,7 +125,10 @@ void
grub_crypto_hash (const gcry_md_spec_t *hash, void *out, const void *in,
grub_size_t inlen)
{
grub_uint8_t ctx[hash->contextsize];
GRUB_PROPERLY_ALIGNED_ARRAY (ctx, GRUB_CRYPTO_MAX_MD_CONTEXT_SIZE);
if (hash->contextsize > sizeof (ctx))
grub_fatal ("Too large md context");
hash->init (&ctx);
hash->write (&ctx, in, inlen);
hash->final (&ctx);

View file

@ -749,7 +749,7 @@ extern USItype __udiv_qrnnd ();
************** MIPS *****************
***************************************/
#if defined (__mips__) && W_TYPE_SIZE == 32
#if (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
#if defined (__clang__) || (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
#define umul_ppmm(w1, w0, u, v) \
do { \
UDItype _r; \

View file

@ -69,16 +69,23 @@ typedef grub_uint8_t gf_single_t;
#define GF_POLYNOMIAL 0x1d
#define GF_INVERT2 0x8e
#if defined (STANDALONE) && !defined (TEST)
static gf_single_t * const gf_powx __attribute__ ((section(".text"))) = (void *) 0x100000;
static gf_single_t * const gf_powx_inv __attribute__ ((section(".text"))) = (void *) 0x100200;
static int *const chosenstat __attribute__ ((section(".text"))) = (void *) 0x100300;
static gf_single_t *const sigma __attribute__ ((section(".text"))) = (void *) 0x100700;
static gf_single_t *const errpot __attribute__ ((section(".text"))) = (void *) 0x100800;
static int *const errpos __attribute__ ((section(".text"))) = (void *) 0x100900;
static gf_single_t *const sy __attribute__ ((section(".text"))) = (void *) 0x100d00;
static gf_single_t *const mstat __attribute__ ((section(".text"))) = (void *) 0x100e00;
static gf_single_t *const errvals __attribute__ ((section(".text"))) = (void *) 0x100f00;
static gf_single_t *const eqstat __attribute__ ((section(".text"))) = (void *) 0x101000;
#ifdef __APPLE__
#define ATTRIBUTE_TEXT __attribute__ ((section("_text,_text")))
#else
#define ATTRIBUTE_TEXT __attribute__ ((section(".text")))
#endif
static gf_single_t * const gf_powx ATTRIBUTE_TEXT = (void *) 0x100000;
static gf_single_t * const gf_powx_inv ATTRIBUTE_TEXT = (void *) 0x100200;
static int *const chosenstat ATTRIBUTE_TEXT = (void *) 0x100300;
static gf_single_t *const sigma ATTRIBUTE_TEXT = (void *) 0x100700;
static gf_single_t *const errpot ATTRIBUTE_TEXT = (void *) 0x100800;
static int *const errpos ATTRIBUTE_TEXT = (void *) 0x100900;
static gf_single_t *const sy ATTRIBUTE_TEXT = (void *) 0x100d00;
static gf_single_t *const mstat ATTRIBUTE_TEXT = (void *) 0x100e00;
static gf_single_t *const errvals ATTRIBUTE_TEXT = (void *) 0x100f00;
static gf_single_t *const eqstat ATTRIBUTE_TEXT = (void *) 0x101000;
/* Next available address: (void *) 0x112000. */
#else

View file

@ -184,8 +184,8 @@ grub_mmap_register (grub_uint64_t start, grub_uint64_t size, int type)
return 0;
b = grub_efi_system_table->boot_services;
address = start & (~0x3ffULL);
pages = (end - address + 0x3ff) >> 12;
address = start & (~0xfffULL);
pages = (end - address + 0xfff) >> 12;
status = efi_call_2 (b->free_pages, address, pages);
if (status != GRUB_EFI_SUCCESS && status != GRUB_EFI_NOT_FOUND)
{
@ -263,7 +263,7 @@ grub_mmap_malign_and_register (grub_uint64_t align __attribute__ ((unused)),
atype = GRUB_EFI_ALLOCATE_ANY_PAGES;
#endif
pages = (size + 0x3ff) >> 12;
pages = (size + 0xfff) >> 12;
status = efi_call_4 (b->allocate_pages, atype,
make_efi_memtype (type), pages, &address);
if (status != GRUB_EFI_SUCCESS)

View file

@ -1,21 +0,0 @@
static void
grub_file_progress_hook_real (grub_disk_addr_t sector,
unsigned offset, unsigned length,
void *data)
{
grub_file_t file = data;
file->progress_offset += length;
show_progress (file->progress_offset, file->size);
}
GRUB_MOD_INIT (progress)
{
grub_file_progress_hook = grub_file_progress_hook_real;
}
GRUB_MOD_FINI (progress)
{
grub_file_progress_hook = 0;
}

View file

@ -31,11 +31,11 @@
static char *
get_ofpathname (const char *dev)
{
char *ret = xmalloc (2 * PATH_MAX);
char *end = ret + 2 * PATH_MAX - 1;
size_t alloced = 4096;
char *ret = xmalloc (alloced);
size_t offset = 0;
int fd;
pid_t pid;
char *ptr = ret;
pid = grub_util_exec_pipe ((const char * []){ "ofpathname", dev, NULL }, &fd);
if (!pid)
@ -45,13 +45,29 @@ get_ofpathname (const char *dev)
if (!fp)
goto fail;
while (!feof (fp) && ptr < end)
while (!feof (fp))
{
size_t r;
r = fread (ptr, 1, end - ptr, fp);
ptr += r;
if (alloced == offset)
{
alloced *= 2;
ret = xrealloc (ret, alloced);
}
r = fread (ret + offset, 1, alloced - offset, fp);
offset += r;
}
if (offset > 0 && ret[offset - 1] == '\n')
offset--;
if (offset > 0 && ret[offset - 1] == '\r')
offset--;
if (alloced == offset)
{
alloced++;
ret = xrealloc (ret, alloced);
}
ret[offset] = '\0';
fclose (fp);
return ret;

View file

@ -114,8 +114,8 @@ check_is_serial (void)
isn't critical.
*/
if (GRUB_ARC_SYSTEM_PARAMETER_BLOCK->firmware_vector_length
>= ((char *) (&GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable + 1)
- (char *) GRUB_ARC_FIRMWARE_VECTOR)
>= (unsigned) ((char *) (&GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable + 1)
- (char *) GRUB_ARC_FIRMWARE_VECTOR)
&& GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable)
consout = GRUB_ARC_FIRMWARE_VECTOR->getenvironmentvariable ("ConsoleOut");
if (!consout)
@ -136,8 +136,8 @@ set_console_dimensions (void)
}
if (GRUB_ARC_SYSTEM_PARAMETER_BLOCK->firmware_vector_length
>= ((char *) (&GRUB_ARC_FIRMWARE_VECTOR->getdisplaystatus + 1)
- (char *) GRUB_ARC_FIRMWARE_VECTOR)
>= (unsigned) ((char *) (&GRUB_ARC_FIRMWARE_VECTOR->getdisplaystatus + 1)
- (char *) GRUB_ARC_FIRMWARE_VECTOR)
&& GRUB_ARC_FIRMWARE_VECTOR->getdisplaystatus)
info = GRUB_ARC_FIRMWARE_VECTOR->getdisplaystatus (GRUB_ARC_STDOUT);
if (info)